• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define STATSD_DEBUG false  // STOPSHIP if true
18 #include "Log.h"
19 
20 #include "StatsPuller.h"
21 #include "StatsPullerManager.h"
22 #include "guardrail/StatsdStats.h"
23 #include "puller_util.h"
24 #include "stats_log_util.h"
25 
26 namespace android {
27 namespace os {
28 namespace statsd {
29 
30 using std::lock_guard;
31 
32 sp<UidMap> StatsPuller::mUidMap = nullptr;
SetUidMap(const sp<UidMap> & uidMap)33 void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
34 
StatsPuller(const int tagId,const int64_t coolDownNs,const int64_t pullTimeoutNs,const std::vector<int> additiveFields)35 StatsPuller::StatsPuller(const int tagId, const int64_t coolDownNs, const int64_t pullTimeoutNs,
36                          const std::vector<int> additiveFields)
37     : mTagId(tagId),
38       mPullTimeoutNs(pullTimeoutNs),
39       mCoolDownNs(coolDownNs),
40       mAdditiveFields(additiveFields),
41       mLastPullTimeNs(0),
42       mLastEventTimeNs(0) {
43 }
44 
Pull(const int64_t eventTimeNs,std::vector<std::shared_ptr<LogEvent>> * data)45 PullErrorCode StatsPuller::Pull(const int64_t eventTimeNs,
46                                 std::vector<std::shared_ptr<LogEvent>>* data) {
47     lock_guard<std::mutex> lock(mLock);
48     const int64_t elapsedTimeNs = getElapsedRealtimeNs();
49     const int64_t systemUptimeMillis = getSystemUptimeMillis();
50     StatsdStats::getInstance().notePull(mTagId);
51     const bool shouldUseCache =
52             (mLastEventTimeNs == eventTimeNs) || (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs);
53     if (shouldUseCache) {
54         if (mHasGoodData) {
55             (*data) = mCachedData;
56             StatsdStats::getInstance().notePullFromCache(mTagId);
57 
58         }
59         return mHasGoodData ? PULL_SUCCESS : PULL_FAIL;
60     }
61     if (mLastPullTimeNs > 0) {
62         StatsdStats::getInstance().updateMinPullIntervalSec(
63                 mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC);
64     }
65     mCachedData.clear();
66     mLastPullTimeNs = elapsedTimeNs;
67     mLastEventTimeNs = eventTimeNs;
68     PullErrorCode status = PullInternal(&mCachedData);
69     mHasGoodData = (status == PULL_SUCCESS);
70     if (!mHasGoodData) {
71         return status;
72     }
73     const int64_t pullElapsedDurationNs = getElapsedRealtimeNs() - elapsedTimeNs;
74     const int64_t pullSystemUptimeDurationMillis = getSystemUptimeMillis() - systemUptimeMillis;
75     StatsdStats::getInstance().notePullTime(mTagId, pullElapsedDurationNs);
76     const bool pullTimeOut = pullElapsedDurationNs > mPullTimeoutNs;
77     if (pullTimeOut) {
78         // Something went wrong. Discard the data.
79         mCachedData.clear();
80         mHasGoodData = false;
81         StatsdStats::getInstance().notePullTimeout(
82                 mTagId, pullSystemUptimeDurationMillis, NanoToMillis(pullElapsedDurationNs));
83         ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId,
84               (long long)pullElapsedDurationNs);
85         return PULL_FAIL;
86     }
87 
88     if (mCachedData.size() > 0) {
89         mapAndMergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId, mAdditiveFields);
90     }
91 
92     if (mCachedData.empty()) {
93         VLOG("Data pulled is empty");
94         StatsdStats::getInstance().noteEmptyData(mTagId);
95     }
96 
97     (*data) = mCachedData;
98     return PULL_SUCCESS;
99 }
100 
ForceClearCache()101 int StatsPuller::ForceClearCache() {
102     return clearCache();
103 }
104 
clearCache()105 int StatsPuller::clearCache() {
106     lock_guard<std::mutex> lock(mLock);
107     return clearCacheLocked();
108 }
109 
clearCacheLocked()110 int StatsPuller::clearCacheLocked() {
111     int ret = mCachedData.size();
112     mCachedData.clear();
113     mLastPullTimeNs = 0;
114     mLastEventTimeNs = 0;
115     return ret;
116 }
117 
ClearCacheIfNecessary(int64_t timestampNs)118 int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) {
119     if (timestampNs - mLastPullTimeNs > mCoolDownNs) {
120         return clearCache();
121     } else {
122         return 0;
123     }
124 }
125 
126 }  // namespace statsd
127 }  // namespace os
128 }  // namespace android
129