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