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 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; 33 void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; } 34 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 45 bool StatsPuller::Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) { 46 lock_guard<std::mutex> lock(mLock); 47 const int64_t elapsedTimeNs = getElapsedRealtimeNs(); 48 const int64_t systemUptimeMillis = getSystemUptimeMillis(); 49 StatsdStats::getInstance().notePull(mTagId); 50 const bool shouldUseCache = 51 (mLastEventTimeNs == eventTimeNs) || (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs); 52 if (shouldUseCache) { 53 if (mHasGoodData) { 54 (*data) = mCachedData; 55 StatsdStats::getInstance().notePullFromCache(mTagId); 56 57 } 58 return mHasGoodData; 59 } 60 if (mLastPullTimeNs > 0) { 61 StatsdStats::getInstance().updateMinPullIntervalSec( 62 mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC); 63 } 64 mCachedData.clear(); 65 mLastPullTimeNs = elapsedTimeNs; 66 mLastEventTimeNs = eventTimeNs; 67 mHasGoodData = PullInternal(&mCachedData); 68 if (!mHasGoodData) { 69 return mHasGoodData; 70 } 71 const int64_t pullElapsedDurationNs = getElapsedRealtimeNs() - elapsedTimeNs; 72 const int64_t pullSystemUptimeDurationMillis = getSystemUptimeMillis() - systemUptimeMillis; 73 StatsdStats::getInstance().notePullTime(mTagId, pullElapsedDurationNs); 74 const bool pullTimeOut = pullElapsedDurationNs > mPullTimeoutNs; 75 if (pullTimeOut) { 76 // Something went wrong. Discard the data. 77 mCachedData.clear(); 78 mHasGoodData = false; 79 StatsdStats::getInstance().notePullTimeout( 80 mTagId, pullSystemUptimeDurationMillis, NanoToMillis(pullElapsedDurationNs)); 81 ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId, 82 (long long)pullElapsedDurationNs); 83 return mHasGoodData; 84 } 85 86 if (mCachedData.size() > 0) { 87 mapAndMergeIsolatedUidsToHostUid(mCachedData, mUidMap, mTagId, mAdditiveFields); 88 } 89 90 if (mCachedData.empty()) { 91 VLOG("Data pulled is empty"); 92 StatsdStats::getInstance().noteEmptyData(mTagId); 93 } 94 95 (*data) = mCachedData; 96 return mHasGoodData; 97 } 98 99 int StatsPuller::ForceClearCache() { 100 return clearCache(); 101 } 102 103 int StatsPuller::clearCache() { 104 lock_guard<std::mutex> lock(mLock); 105 return clearCacheLocked(); 106 } 107 108 int StatsPuller::clearCacheLocked() { 109 int ret = mCachedData.size(); 110 mCachedData.clear(); 111 mLastPullTimeNs = 0; 112 mLastEventTimeNs = 0; 113 return ret; 114 } 115 116 int StatsPuller::ClearCacheIfNecessary(int64_t timestampNs) { 117 if (timestampNs - mLastPullTimeNs > mCoolDownNs) { 118 return clearCache(); 119 } else { 120 return 0; 121 } 122 } 123 124 } // namespace statsd 125 } // namespace os 126 } // namespace android 127