blob: 34818145a9220ebc02f1e1b7fe5c0b48850b7a53 [file] [log] [blame]
Yao Chenab273e22017-09-06 12:53:50 -07001/*
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
Chenjie Yuc7939cb2019-02-04 17:25:45 -080017#define DEBUG false // STOPSHIP if true
Joe Onorato9fc9edf2017-10-15 20:08:52 -070018#include "Log.h"
tsaichristined21aacf2019-10-07 14:47:38 -070019
20#include "StatsLogProcessor.h"
Yao Chenab273e22017-09-06 12:53:50 -070021
yro947fbce2017-11-15 22:50:23 -080022#include <android-base/file.h>
23#include <dirent.h>
Chenjie Yuc7939cb2019-02-04 17:25:45 -080024#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
tsaichristined21aacf2019-10-07 14:47:38 -070025#include <log/log_event_list.h>
26#include <utils/Errors.h>
27#include <utils/SystemClock.h>
28
yro947fbce2017-11-15 22:50:23 -080029#include "android-base/stringprintf.h"
Muhammad Qureshic8e22662019-11-20 17:18:03 -080030#include "atoms_info.h"
Chenjie Yuc7939cb2019-02-04 17:25:45 -080031#include "external/StatsPullerManager.h"
Yao Chenb3561512017-11-21 18:07:17 -080032#include "guardrail/StatsdStats.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070033#include "metrics/CountMetricProducer.h"
tsaichristined21aacf2019-10-07 14:47:38 -070034#include "state/StateManager.h"
Chenjie Yuc7939cb2019-02-04 17:25:45 -080035#include "stats_log_util.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070036#include "stats_util.h"
tsaichristined21aacf2019-10-07 14:47:38 -070037#include "statslog.h"
yro947fbce2017-11-15 22:50:23 -080038#include "storage/StorageManager.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070039
Yao Chenab273e22017-09-06 12:53:50 -070040using namespace android;
yro947fbce2017-11-15 22:50:23 -080041using android::base::StringPrintf;
yrob0378b02017-11-09 20:36:25 -080042using android::util::FIELD_COUNT_REPEATED;
yro17adac92017-11-08 23:16:29 -080043using android::util::FIELD_TYPE_BOOL;
44using android::util::FIELD_TYPE_FLOAT;
45using android::util::FIELD_TYPE_INT32;
46using android::util::FIELD_TYPE_INT64;
47using android::util::FIELD_TYPE_MESSAGE;
48using android::util::FIELD_TYPE_STRING;
49using android::util::ProtoOutputStream;
Yao Chen44cf27c2017-09-14 22:32:50 -070050using std::make_unique;
51using std::unique_ptr;
52using std::vector;
Bookatz906a35c2017-09-20 15:26:44 -070053
54namespace android {
55namespace os {
56namespace statsd {
Yao Chenab273e22017-09-06 12:53:50 -070057
yro947fbce2017-11-15 22:50:23 -080058// for ConfigMetricsReportList
yro17adac92017-11-08 23:16:29 -080059const int FIELD_ID_CONFIG_KEY = 1;
yro947fbce2017-11-15 22:50:23 -080060const int FIELD_ID_REPORTS = 2;
yro17adac92017-11-08 23:16:29 -080061// for ConfigKey
62const int FIELD_ID_UID = 1;
Yangster-mac94e197c2018-01-02 16:03:03 -080063const int FIELD_ID_ID = 2;
yro947fbce2017-11-15 22:50:23 -080064// for ConfigMetricsReport
Yao Chen4c959cb2018-02-13 13:27:48 -080065// const int FIELD_ID_METRICS = 1; // written in MetricsManager.cpp
yro947fbce2017-11-15 22:50:23 -080066const int FIELD_ID_UID_MAP = 2;
Yangster-mac330af582018-02-08 15:24:38 -080067const int FIELD_ID_LAST_REPORT_ELAPSED_NANOS = 3;
68const int FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS = 4;
Yangster-mac3fa5d7f2018-03-10 21:50:27 -080069const int FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS = 5;
70const int FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS = 6;
Chenjie Yue36018b2018-04-16 15:18:30 -070071const int FIELD_ID_DUMP_REPORT_REASON = 8;
Yangster-mac9def8e32018-04-17 13:55:51 -070072const int FIELD_ID_STRINGS = 9;
Yangster-mac3fa5d7f2018-03-10 21:50:27 -080073
Muhammad Qureshi844694b2019-04-05 10:10:40 -070074// for ActiveConfigList
75const int FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG = 1;
Chenjie Yuc7939cb2019-02-04 17:25:45 -080076
Yangster-macb142cc82018-03-30 15:22:08 -070077#define NS_PER_HOUR 3600 * NS_PER_SEC
yro947fbce2017-11-15 22:50:23 -080078
Chenjie Yuc7939cb2019-02-04 17:25:45 -080079#define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric"
yro17adac92017-11-08 23:16:29 -080080
Tej Singh42f9e062018-11-09 10:01:00 -080081// Cool down period for writing data to disk to avoid overwriting files.
82#define WRITE_DATA_COOL_DOWN_SEC 5
83
yro31eb67b2017-10-24 13:33:21 -070084StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
Chenjie Yue2219202018-06-08 10:07:51 -070085 const sp<StatsPullerManager>& pullerManager,
Yangster-mac932ecec2018-02-01 10:23:52 -080086 const sp<AlarmMonitor>& anomalyAlarmMonitor,
87 const sp<AlarmMonitor>& periodicAlarmMonitor,
Yangster-mac15f6bbc2018-04-08 11:52:26 -070088 const int64_t timeBaseNs,
Tej Singh6ede28b2019-01-29 17:06:54 -080089 const std::function<bool(const ConfigKey&)>& sendBroadcast,
90 const std::function<bool(
91 const int&, const vector<int64_t>&)>& activateBroadcast)
Chenjie Yu85ed8382017-12-14 16:48:54 -080092 : mUidMap(uidMap),
Chenjie Yue2219202018-06-08 10:07:51 -070093 mPullerManager(pullerManager),
Yangster-mac932ecec2018-02-01 10:23:52 -080094 mAnomalyAlarmMonitor(anomalyAlarmMonitor),
95 mPeriodicAlarmMonitor(periodicAlarmMonitor),
Chenjie Yu85ed8382017-12-14 16:48:54 -080096 mSendBroadcast(sendBroadcast),
Tej Singh6ede28b2019-01-29 17:06:54 -080097 mSendActivationBroadcast(activateBroadcast),
Yangster-mac15f6bbc2018-04-08 11:52:26 -070098 mTimeBaseNs(timeBaseNs),
Yao Chen163d2602018-04-10 10:39:53 -070099 mLargestTimestampSeen(0),
100 mLastTimestampSeen(0) {
Chenjie Yue2219202018-06-08 10:07:51 -0700101 mPullerManager->ForceClearPullerCache();
Yao Chenab273e22017-09-06 12:53:50 -0700102}
103
Yao Chenef99c4f2017-09-22 16:26:54 -0700104StatsLogProcessor::~StatsLogProcessor() {
Yao Chenab273e22017-09-06 12:53:50 -0700105}
106
Yao Chen9a43b4f2019-04-10 10:43:20 -0700107static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outData) {
108 outData->clear();
109 outData->resize(proto.size());
110 size_t pos = 0;
111 sp<android::util::ProtoReader> reader = proto.data();
112 while (reader->readBuffer() != NULL) {
113 size_t toRead = reader->currentToRead();
114 std::memcpy(&((*outData)[pos]), reader->readBuffer(), toRead);
115 pos += toRead;
116 reader->move(toRead);
117 }
118}
119
Yangster-mace2cd6d52017-11-09 20:38:30 -0800120void StatsLogProcessor::onAnomalyAlarmFired(
Yangster-macb142cc82018-03-30 15:22:08 -0700121 const int64_t& timestampNs,
Yangster-mac932ecec2018-02-01 10:23:52 -0800122 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
Yangster-macb0d06282018-01-05 15:44:07 -0800123 std::lock_guard<std::mutex> lock(mMetricsMutex);
Bookatzcc5adef22017-11-21 14:36:23 -0800124 for (const auto& itr : mMetricsManagers) {
Yangster-mac932ecec2018-02-01 10:23:52 -0800125 itr.second->onAnomalyAlarmFired(timestampNs, alarmSet);
126 }
127}
128void StatsLogProcessor::onPeriodicAlarmFired(
Yangster-macb142cc82018-03-30 15:22:08 -0700129 const int64_t& timestampNs,
Yangster-mac932ecec2018-02-01 10:23:52 -0800130 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
131
132 std::lock_guard<std::mutex> lock(mMetricsMutex);
133 for (const auto& itr : mMetricsManagers) {
134 itr.second->onPeriodicAlarmFired(timestampNs, alarmSet);
Yangster-mace2cd6d52017-11-09 20:38:30 -0800135 }
136}
137
Yao Chen8a8d16c2018-02-08 14:50:40 -0800138void updateUid(Value* value, int hostUid) {
139 int uid = value->int_value;
140 if (uid != hostUid) {
141 value->setInt(hostUid);
142 }
143}
144
Yangster-macd40053e2018-01-09 16:29:22 -0800145void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
Yao Chenc40a19d2018-03-15 16:48:25 -0700146 if (android::util::AtomsInfo::kAtomsWithAttributionChain.find(event->GetTagId()) !=
147 android::util::AtomsInfo::kAtomsWithAttributionChain.end()) {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800148 for (auto& value : *(event->getMutableValues())) {
149 if (value.mField.getPosAtDepth(0) > kAttributionField) {
150 break;
151 }
152 if (isAttributionUidField(value)) {
153 const int hostUid = mUidMap->getHostUidOrSelf(value.mValue.int_value);
154 updateUid(&value.mValue, hostUid);
155 }
Yangster-macd40053e2018-01-09 16:29:22 -0800156 }
Yao Chenc40a19d2018-03-15 16:48:25 -0700157 } else {
158 auto it = android::util::AtomsInfo::kAtomsWithUidField.find(event->GetTagId());
159 if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) {
160 int uidField = it->second; // uidField is the field number in proto,
161 // starting from 1
162 if (uidField > 0 && (int)event->getValues().size() >= uidField &&
163 (event->getValues())[uidField - 1].mValue.getType() == INT) {
164 Value& value = (*event->getMutableValues())[uidField - 1].mValue;
165 const int hostUid = mUidMap->getHostUidOrSelf(value.int_value);
166 updateUid(&value, hostUid);
167 } else {
168 ALOGE("Malformed log, uid not found. %s", event->ToString().c_str());
169 }
170 }
Yao Chen312e8982017-12-05 15:29:03 -0800171 }
Yangster-macd40053e2018-01-09 16:29:22 -0800172}
173
174void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) {
175 status_t err = NO_ERROR, err2 = NO_ERROR, err3 = NO_ERROR;
176 bool is_create = event.GetBool(3, &err);
177 auto parent_uid = int(event.GetLong(1, &err2));
178 auto isolated_uid = int(event.GetLong(2, &err3));
179 if (err == NO_ERROR && err2 == NO_ERROR && err3 == NO_ERROR) {
180 if (is_create) {
181 mUidMap->assignIsolatedUid(isolated_uid, parent_uid);
182 } else {
Bookatz3c648862018-05-25 13:32:43 -0700183 mUidMap->removeIsolatedUid(isolated_uid);
Yangster-macd40053e2018-01-09 16:29:22 -0800184 }
185 } else {
186 ALOGE("Failed to parse uid in the isolated uid change event.");
187 }
188}
189
Yangster-mac892f3d32018-05-02 14:16:48 -0700190void StatsLogProcessor::resetConfigs() {
191 std::lock_guard<std::mutex> lock(mMetricsMutex);
192 resetConfigsLocked(getElapsedRealtimeNs());
193}
194
195void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs) {
196 std::vector<ConfigKey> configKeys;
197 for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
198 configKeys.push_back(it->first);
199 }
200 resetConfigsLocked(timestampNs, configKeys);
201}
202
Yao Chen3ff3a492018-08-06 16:17:37 -0700203void StatsLogProcessor::OnLogEvent(LogEvent* event) {
Tej Singh480392f2019-10-23 15:53:46 -0700204 OnLogEvent(event, getElapsedRealtimeNs());
205}
206
207void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) {
Yangster-macd40053e2018-01-09 16:29:22 -0800208 std::lock_guard<std::mutex> lock(mMetricsMutex);
Yao Chen876889c2018-05-02 11:16:16 -0700209
210#ifdef VERY_VERBOSE_PRINTING
211 if (mPrintAllLogs) {
212 ALOGI("%s", event->ToString().c_str());
213 }
214#endif
Tej Singh480392f2019-10-23 15:53:46 -0700215 const int64_t eventElapsedTimeNs = event->GetElapsedTimestampNs();
Yangster-macb8382a12018-04-04 10:39:12 -0700216
Tej Singh480392f2019-10-23 15:53:46 -0700217 resetIfConfigTtlExpiredLocked(eventElapsedTimeNs);
Yangster-macb142cc82018-03-30 15:22:08 -0700218
Yangster-macd40053e2018-01-09 16:29:22 -0800219 StatsdStats::getInstance().noteAtomLogged(
Yangster-mac330af582018-02-08 15:24:38 -0800220 event->GetTagId(), event->GetElapsedTimestampNs() / NS_PER_SEC);
Yangster-macd40053e2018-01-09 16:29:22 -0800221
David Chen21582962017-11-01 17:32:46 -0700222 // Hard-coded logic to update the isolated uid's in the uid-map.
Stefan Lafonae2df012017-11-14 09:17:21 -0800223 // The field numbers need to be currently updated by hand with atoms.proto
Yangster-macd40053e2018-01-09 16:29:22 -0800224 if (event->GetTagId() == android::util::ISOLATED_UID_CHANGED) {
225 onIsolatedUidChangedEventLocked(*event);
David Chencfc311d2018-01-23 17:55:54 -0800226 }
227
tsaichristined21aacf2019-10-07 14:47:38 -0700228 StateManager::getInstance().onLogEvent(*event);
229
David Chencfc311d2018-01-23 17:55:54 -0800230 if (mMetricsManagers.empty()) {
231 return;
232 }
233
Yangster-macb142cc82018-03-30 15:22:08 -0700234 int64_t curTimeSec = getElapsedRealtimeSec();
Yangster-mac330af582018-02-08 15:24:38 -0800235 if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
Chenjie Yue2219202018-06-08 10:07:51 -0700236 mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
Yangster-mac330af582018-02-08 15:24:38 -0800237 mLastPullerCacheClearTimeSec = curTimeSec;
Chenjie Yufa22d652018-02-05 14:37:48 -0800238 }
239
Yangster-macb142cc82018-03-30 15:22:08 -0700240
David Chencfc311d2018-01-23 17:55:54 -0800241 if (event->GetTagId() != android::util::ISOLATED_UID_CHANGED) {
Yangster-macd40053e2018-01-09 16:29:22 -0800242 // Map the isolated uid to host uid if necessary.
243 mapIsolatedUidToHostUidIfNecessaryLocked(event);
244 }
245
Tej Singh6ede28b2019-01-29 17:06:54 -0800246 std::unordered_set<int> uidsWithActiveConfigsChanged;
247 std::unordered_map<int, std::vector<int64_t>> activeConfigsPerUid;
Yangster-macd40053e2018-01-09 16:29:22 -0800248 // pass the event to metrics managers.
249 for (auto& pair : mMetricsManagers) {
Tej Singh6ede28b2019-01-29 17:06:54 -0800250 int uid = pair.first.GetUid();
251 int64_t configId = pair.first.GetId();
252 bool isPrevActive = pair.second->isActive();
Yangster-macd40053e2018-01-09 16:29:22 -0800253 pair.second->onLogEvent(*event);
Tej Singh6ede28b2019-01-29 17:06:54 -0800254 bool isCurActive = pair.second->isActive();
255 // Map all active configs by uid.
256 if (isCurActive) {
257 auto activeConfigs = activeConfigsPerUid.find(uid);
258 if (activeConfigs != activeConfigsPerUid.end()) {
259 activeConfigs->second.push_back(configId);
260 } else {
261 vector<int64_t> newActiveConfigs;
262 newActiveConfigs.push_back(configId);
263 activeConfigsPerUid[uid] = newActiveConfigs;
264 }
265 }
266 // The activation state of this config changed.
267 if (isPrevActive != isCurActive) {
268 VLOG("Active status changed for uid %d", uid);
269 uidsWithActiveConfigsChanged.insert(uid);
270 StatsdStats::getInstance().noteActiveStatusChanged(pair.first, isCurActive);
271 }
Tej Singh480392f2019-10-23 15:53:46 -0700272 flushIfNecessaryLocked(pair.first, *(pair.second));
David Chen21582962017-11-01 17:32:46 -0700273 }
Tej Singh6ede28b2019-01-29 17:06:54 -0800274
Tej Singh480392f2019-10-23 15:53:46 -0700275 // Don't use the event timestamp for the guardrail.
Tej Singh6ede28b2019-01-29 17:06:54 -0800276 for (int uid : uidsWithActiveConfigsChanged) {
277 // Send broadcast so that receivers can pull data.
278 auto lastBroadcastTime = mLastActivationBroadcastTimes.find(uid);
279 if (lastBroadcastTime != mLastActivationBroadcastTimes.end()) {
Tej Singh480392f2019-10-23 15:53:46 -0700280 if (elapsedRealtimeNs - lastBroadcastTime->second <
281 StatsdStats::kMinActivationBroadcastPeriodNs) {
Tej Singh16ca28f2019-06-24 11:58:23 -0700282 StatsdStats::getInstance().noteActivationBroadcastGuardrailHit(uid);
Tej Singh6ede28b2019-01-29 17:06:54 -0800283 VLOG("StatsD would've sent an activation broadcast but the rate limit stopped us.");
284 return;
285 }
286 }
287 auto activeConfigs = activeConfigsPerUid.find(uid);
288 if (activeConfigs != activeConfigsPerUid.end()) {
289 if (mSendActivationBroadcast(uid, activeConfigs->second)) {
290 VLOG("StatsD sent activation notice for uid %d", uid);
Tej Singh480392f2019-10-23 15:53:46 -0700291 mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
Tej Singh6ede28b2019-01-29 17:06:54 -0800292 }
293 } else {
294 std::vector<int64_t> emptyActiveConfigs;
295 if (mSendActivationBroadcast(uid, emptyActiveConfigs)) {
296 VLOG("StatsD sent EMPTY activation notice for uid %d", uid);
Tej Singh480392f2019-10-23 15:53:46 -0700297 mLastActivationBroadcastTimes[uid] = elapsedRealtimeNs;
Tej Singh6ede28b2019-01-29 17:06:54 -0800298 }
299 }
300 }
301}
302
303void StatsLogProcessor::GetActiveConfigs(const int uid, vector<int64_t>& outActiveConfigs) {
304 std::lock_guard<std::mutex> lock(mMetricsMutex);
305 GetActiveConfigsLocked(uid, outActiveConfigs);
306}
307
308void StatsLogProcessor::GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs) {
309 outActiveConfigs.clear();
310 for (auto& pair : mMetricsManagers) {
311 if (pair.first.GetUid() == uid && pair.second->isActive()) {
312 outActiveConfigs.push_back(pair.first.GetId());
313 }
314 }
Yao Chenab273e22017-09-06 12:53:50 -0700315}
316
Yangster-macc04feba2018-04-02 14:37:33 -0700317void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
318 const StatsdConfig& config) {
Yangster-macb0d06282018-01-05 15:44:07 -0800319 std::lock_guard<std::mutex> lock(mMetricsMutex);
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000320 WriteDataToDiskLocked(key, timestampNs, CONFIG_UPDATED, NO_TIME_CONSTRAINTS);
Yangster-macb142cc82018-03-30 15:22:08 -0700321 OnConfigUpdatedLocked(timestampNs, key, config);
322}
323
324void StatsLogProcessor::OnConfigUpdatedLocked(
325 const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) {
Tej Singh484524a2018-02-01 15:10:05 -0800326 VLOG("Updated configuration for key %s", key.ToString().c_str());
Yangster-mac932ecec2018-02-01 10:23:52 -0800327 sp<MetricsManager> newMetricsManager =
Chenjie Yue2219202018-06-08 10:07:51 -0700328 new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager,
329 mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
Yao Chencaf339d2017-10-06 16:01:10 -0700330 if (newMetricsManager->isConfigValid()) {
David Chend6896892017-10-25 11:49:03 -0700331 mUidMap->OnConfigUpdated(key);
Yangster-macb142cc82018-03-30 15:22:08 -0700332 newMetricsManager->refreshTtl(timestampNs);
Yao Chend10f7b12017-12-18 12:53:50 -0800333 mMetricsManagers[key] = newMetricsManager;
Yao Chenb3561512017-11-21 18:07:17 -0800334 VLOG("StatsdConfig valid");
Yao Chencaf339d2017-10-06 16:01:10 -0700335 } else {
336 // If there is any error in the config, don't use it.
Yao Chenb3561512017-11-21 18:07:17 -0800337 ALOGE("StatsdConfig NOT valid");
Yao Chencaf339d2017-10-06 16:01:10 -0700338 }
yro00698da2017-09-15 10:06:40 -0700339}
Bookatz906a35c2017-09-20 15:26:44 -0700340
Yangster7c334a12017-11-22 14:24:24 -0800341size_t StatsLogProcessor::GetMetricsSize(const ConfigKey& key) const {
Yangster-macb0d06282018-01-05 15:44:07 -0800342 std::lock_guard<std::mutex> lock(mMetricsMutex);
Yao Chen729093d2017-10-16 10:33:26 -0700343 auto it = mMetricsManagers.find(key);
344 if (it == mMetricsManagers.end()) {
345 ALOGW("Config source %s does not exist", key.ToString().c_str());
David Chen1d7b0cd2017-11-15 14:20:04 -0800346 return 0;
Yao Chen729093d2017-10-16 10:33:26 -0700347 }
David Chen1d7b0cd2017-11-15 14:20:04 -0800348 return it->second->byteSize();
349}
350
Yao Chena80e5c02018-09-04 13:55:29 -0700351void StatsLogProcessor::dumpStates(int out, bool verbose) {
Yao Chen884c8c12018-01-26 10:36:25 -0800352 std::lock_guard<std::mutex> lock(mMetricsMutex);
Yao Chena80e5c02018-09-04 13:55:29 -0700353 FILE* fout = fdopen(out, "w");
354 if (fout == NULL) {
355 return;
Yao Chen884c8c12018-01-26 10:36:25 -0800356 }
Yao Chena80e5c02018-09-04 13:55:29 -0700357 fprintf(fout, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
358 for (auto metricsManager : mMetricsManagers) {
359 metricsManager.second->dumpStates(fout, verbose);
360 }
361
362 fclose(fout);
Yao Chen884c8c12018-01-26 10:36:25 -0800363}
364
yro4beccbe2018-03-15 19:42:05 -0700365/*
Bookatz9cc7b662018-11-06 10:39:21 -0800366 * onDumpReport dumps serialized ConfigMetricsReportList into proto.
yro4beccbe2018-03-15 19:42:05 -0700367 */
Yangster-macb142cc82018-03-30 15:22:08 -0700368void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
Yangster-mace68f3a52018-04-04 00:01:43 -0700369 const bool include_current_partial_bucket,
Bookatzff71cad2018-09-20 17:17:49 -0700370 const bool erase_data,
Chenjie Yue36018b2018-04-16 15:18:30 -0700371 const DumpReportReason dumpReportReason,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000372 const DumpLatency dumpLatency,
Bookatzff71cad2018-09-20 17:17:49 -0700373 ProtoOutputStream* proto) {
Yangster-macb0d06282018-01-05 15:44:07 -0800374 std::lock_guard<std::mutex> lock(mMetricsMutex);
Yangster-mac20877162017-12-22 17:19:39 -0800375
yro947fbce2017-11-15 22:50:23 -0800376 // Start of ConfigKey.
Bookatzff71cad2018-09-20 17:17:49 -0700377 uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
378 proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
379 proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
380 proto->end(configKeyToken);
yro947fbce2017-11-15 22:50:23 -0800381 // End of ConfigKey.
yro17adac92017-11-08 23:16:29 -0800382
Yao Chen9a43b4f2019-04-10 10:43:20 -0700383 bool keepFile = false;
384 auto it = mMetricsManagers.find(key);
385 if (it != mMetricsManagers.end() && it->second->shouldPersistLocalHistory()) {
386 keepFile = true;
387 }
388
yro947fbce2017-11-15 22:50:23 -0800389 // Then, check stats-data directory to see there's any file containing
390 // ConfigMetricsReport from previous shutdowns to concatenate to reports.
Yao Chen9a43b4f2019-04-10 10:43:20 -0700391 StorageManager::appendConfigMetricsReport(
392 key, proto, erase_data && !keepFile /* should remove file after appending it */,
393 dumpReportReason == ADB_DUMP /*if caller is adb*/);
yro947fbce2017-11-15 22:50:23 -0800394
Yangster-mace68f3a52018-04-04 00:01:43 -0700395 if (it != mMetricsManagers.end()) {
396 // This allows another broadcast to be sent within the rate-limit period if we get close to
397 // filling the buffer again soon.
398 mLastBroadcastTimes.erase(key);
399
Yao Chen9a43b4f2019-04-10 10:43:20 -0700400 vector<uint8_t> buffer;
401 onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket,
402 erase_data, dumpReportReason, dumpLatency,
403 false /* is this data going to be saved on disk */, &buffer);
404 proto->write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS,
405 reinterpret_cast<char*>(buffer.data()), buffer.size());
Yangster-mace68f3a52018-04-04 00:01:43 -0700406 } else {
407 ALOGW("Config source %s does not exist", key.ToString().c_str());
408 }
Bookatzff71cad2018-09-20 17:17:49 -0700409}
410
411/*
412 * onDumpReport dumps serialized ConfigMetricsReportList into outData.
413 */
414void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
415 const bool include_current_partial_bucket,
416 const bool erase_data,
417 const DumpReportReason dumpReportReason,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000418 const DumpLatency dumpLatency,
Bookatzff71cad2018-09-20 17:17:49 -0700419 vector<uint8_t>* outData) {
420 ProtoOutputStream proto;
421 onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000422 dumpReportReason, dumpLatency, &proto);
Yangster-mace68f3a52018-04-04 00:01:43 -0700423
David Chen1d7b0cd2017-11-15 14:20:04 -0800424 if (outData != nullptr) {
Yao Chen9a43b4f2019-04-10 10:43:20 -0700425 flushProtoToBuffer(proto, outData);
426 VLOG("output data size %zu", outData->size());
yro17adac92017-11-08 23:16:29 -0800427 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800428
Yangster-mace68f3a52018-04-04 00:01:43 -0700429 StatsdStats::getInstance().noteMetricsReportSent(key, proto.size());
Yao Chen729093d2017-10-16 10:33:26 -0700430}
431
yro4beccbe2018-03-15 19:42:05 -0700432/*
433 * onConfigMetricsReportLocked dumps serialized ConfigMetricsReport into outData.
434 */
Yao Chen9a43b4f2019-04-10 10:43:20 -0700435void StatsLogProcessor::onConfigMetricsReportLocked(
436 const ConfigKey& key, const int64_t dumpTimeStampNs,
437 const bool include_current_partial_bucket, const bool erase_data,
438 const DumpReportReason dumpReportReason, const DumpLatency dumpLatency,
439 const bool dataSavedOnDisk, vector<uint8_t>* buffer) {
yro4beccbe2018-03-15 19:42:05 -0700440 // We already checked whether key exists in mMetricsManagers in
441 // WriteDataToDisk.
442 auto it = mMetricsManagers.find(key);
Yangster-mace68f3a52018-04-04 00:01:43 -0700443 if (it == mMetricsManagers.end()) {
444 return;
445 }
yro4beccbe2018-03-15 19:42:05 -0700446 int64_t lastReportTimeNs = it->second->getLastReportTimeNs();
447 int64_t lastReportWallClockNs = it->second->getLastReportWallClockNs();
448
Yangster-mac9def8e32018-04-17 13:55:51 -0700449 std::set<string> str_set;
450
Yao Chen9a43b4f2019-04-10 10:43:20 -0700451 ProtoOutputStream tempProto;
yro4beccbe2018-03-15 19:42:05 -0700452 // First, fill in ConfigMetricsReport using current data on memory, which
453 // starts from filling in StatsLogReport's.
Yao Chen9a43b4f2019-04-10 10:43:20 -0700454 it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
455 dumpLatency, &str_set, &tempProto);
yro4beccbe2018-03-15 19:42:05 -0700456
David Chen9e6dbbd2018-05-07 17:52:29 -0700457 // Fill in UidMap if there is at least one metric to report.
458 // This skips the uid map if it's an empty config.
459 if (it->second->getNumMetrics() > 0) {
Yao Chen9a43b4f2019-04-10 10:43:20 -0700460 uint64_t uidMapToken = tempProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UID_MAP);
dwchen730403e2018-10-29 11:41:56 -0700461 mUidMap->appendUidMap(
462 dumpTimeStampNs, key, it->second->hashStringInReport() ? &str_set : nullptr,
Yao Chen9a43b4f2019-04-10 10:43:20 -0700463 it->second->versionStringsInReport(), it->second->installerInReport(), &tempProto);
464 tempProto.end(uidMapToken);
David Chen9e6dbbd2018-05-07 17:52:29 -0700465 }
yro4beccbe2018-03-15 19:42:05 -0700466
467 // Fill in the timestamps.
Yao Chen9a43b4f2019-04-10 10:43:20 -0700468 tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_ELAPSED_NANOS,
469 (long long)lastReportTimeNs);
470 tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS,
471 (long long)dumpTimeStampNs);
472 tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS,
473 (long long)lastReportWallClockNs);
474 tempProto.write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS,
475 (long long)getWallClockNs());
Chenjie Yue36018b2018-04-16 15:18:30 -0700476 // Dump report reason
Yao Chen9a43b4f2019-04-10 10:43:20 -0700477 tempProto.write(FIELD_TYPE_INT32 | FIELD_ID_DUMP_REPORT_REASON, dumpReportReason);
Yangster-mac9def8e32018-04-17 13:55:51 -0700478
David Chen56ae0d92018-05-11 16:00:22 -0700479 for (const auto& str : str_set) {
Yao Chen9a43b4f2019-04-10 10:43:20 -0700480 tempProto.write(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | FIELD_ID_STRINGS, str);
481 }
482
483 flushProtoToBuffer(tempProto, buffer);
484
485 // save buffer to disk if needed
486 if (erase_data && !dataSavedOnDisk && it->second->shouldPersistLocalHistory()) {
487 VLOG("save history to disk");
488 string file_name = StorageManager::getDataHistoryFileName((long)getWallClockSec(),
489 key.GetUid(), key.GetId());
490 StorageManager::writeFile(file_name.c_str(), buffer->data(), buffer->size());
Yangster-mac9def8e32018-04-17 13:55:51 -0700491 }
Yangster-macb142cc82018-03-30 15:22:08 -0700492}
yro4beccbe2018-03-15 19:42:05 -0700493
Yao Chen163d2602018-04-10 10:39:53 -0700494void StatsLogProcessor::resetConfigsLocked(const int64_t timestampNs,
495 const std::vector<ConfigKey>& configs) {
496 for (const auto& key : configs) {
Yangster-macb142cc82018-03-30 15:22:08 -0700497 StatsdConfig config;
498 if (StorageManager::readConfigFromDisk(key, &config)) {
499 OnConfigUpdatedLocked(timestampNs, key, config);
500 StatsdStats::getInstance().noteConfigReset(key);
501 } else {
502 ALOGE("Failed to read backup config from disk for : %s", key.ToString().c_str());
503 auto it = mMetricsManagers.find(key);
504 if (it != mMetricsManagers.end()) {
505 it->second->refreshTtl(timestampNs);
506 }
507 }
508 }
yro4beccbe2018-03-15 19:42:05 -0700509}
510
Yao Chen163d2602018-04-10 10:39:53 -0700511void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) {
512 std::vector<ConfigKey> configKeysTtlExpired;
513 for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
514 if (it->second != nullptr && !it->second->isInTtl(timestampNs)) {
515 configKeysTtlExpired.push_back(it->first);
516 }
517 }
518 if (configKeysTtlExpired.size() > 0) {
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000519 WriteDataToDiskLocked(CONFIG_RESET, NO_TIME_CONSTRAINTS);
Yao Chen163d2602018-04-10 10:39:53 -0700520 resetConfigsLocked(timestampNs, configKeysTtlExpired);
521 }
522}
523
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700524void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
Yangster-macb0d06282018-01-05 15:44:07 -0800525 std::lock_guard<std::mutex> lock(mMetricsMutex);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700526 auto it = mMetricsManagers.find(key);
527 if (it != mMetricsManagers.end()) {
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700528 WriteDataToDiskLocked(key, getElapsedRealtimeNs(), CONFIG_REMOVED,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000529 NO_TIME_CONSTRAINTS);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700530 mMetricsManagers.erase(it);
David Chend6896892017-10-25 11:49:03 -0700531 mUidMap->OnConfigRemoved(key);
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700532 }
Yao Chenb3561512017-11-21 18:07:17 -0800533 StatsdStats::getInstance().noteConfigRemoved(key);
David Chen1d7b0cd2017-11-15 14:20:04 -0800534
David Chen1d7b0cd2017-11-15 14:20:04 -0800535 mLastBroadcastTimes.erase(key);
Chenjie Yufa22d652018-02-05 14:37:48 -0800536
Tej Singh6ede28b2019-01-29 17:06:54 -0800537 int uid = key.GetUid();
538 bool lastConfigForUid = true;
539 for (auto it : mMetricsManagers) {
540 if (it.first.GetUid() == uid) {
541 lastConfigForUid = false;
542 break;
543 }
544 }
545 if (lastConfigForUid) {
546 mLastActivationBroadcastTimes.erase(uid);
547 }
548
Chenjie Yufa22d652018-02-05 14:37:48 -0800549 if (mMetricsManagers.empty()) {
Chenjie Yue2219202018-06-08 10:07:51 -0700550 mPullerManager->ForceClearPullerCache();
Chenjie Yufa22d652018-02-05 14:37:48 -0800551 }
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700552}
553
Tej Singh480392f2019-10-23 15:53:46 -0700554void StatsLogProcessor::flushIfNecessaryLocked(const ConfigKey& key,
555 MetricsManager& metricsManager) {
556 int64_t elapsedRealtimeNs = getElapsedRealtimeNs();
David Chend9269e22017-12-05 13:43:51 -0800557 auto lastCheckTime = mLastByteSizeTimes.find(key);
558 if (lastCheckTime != mLastByteSizeTimes.end()) {
Tej Singh480392f2019-10-23 15:53:46 -0700559 if (elapsedRealtimeNs - lastCheckTime->second < StatsdStats::kMinByteSizeCheckPeriodNs) {
David Chend9269e22017-12-05 13:43:51 -0800560 return;
561 }
562 }
563
564 // We suspect that the byteSize() computation is expensive, so we set a rate limit.
565 size_t totalBytes = metricsManager.byteSize();
Tej Singh480392f2019-10-23 15:53:46 -0700566 mLastByteSizeTimes[key] = elapsedRealtimeNs;
David Chen48944902018-05-03 10:29:11 -0700567 bool requestDump = false;
Tej Singh480392f2019-10-23 15:53:46 -0700568 if (totalBytes > StatsdStats::kMaxMetricsBytesPerConfig) {
569 // Too late. We need to start clearing data.
570 metricsManager.dropData(elapsedRealtimeNs);
Chenjie Yuc3c30c02018-10-26 09:48:07 -0700571 StatsdStats::getInstance().noteDataDropped(key, totalBytes);
David Chen12942952017-12-04 14:28:43 -0800572 VLOG("StatsD had to toss out metrics for %s", key.ToString().c_str());
David Chen48944902018-05-03 10:29:11 -0700573 } else if ((totalBytes > StatsdStats::kBytesPerConfigTriggerGetData) ||
574 (mOnDiskDataConfigs.find(key) != mOnDiskDataConfigs.end())) {
575 // Request to send a broadcast if:
576 // 1. in memory data > threshold OR
577 // 2. config has old data report on disk.
578 requestDump = true;
579 }
580
581 if (requestDump) {
David Chend9269e22017-12-05 13:43:51 -0800582 // Send broadcast so that receivers can pull data.
583 auto lastBroadcastTime = mLastBroadcastTimes.find(key);
584 if (lastBroadcastTime != mLastBroadcastTimes.end()) {
Tej Singh480392f2019-10-23 15:53:46 -0700585 if (elapsedRealtimeNs - lastBroadcastTime->second <
586 StatsdStats::kMinBroadcastPeriodNs) {
David Chend9269e22017-12-05 13:43:51 -0800587 VLOG("StatsD would've sent a broadcast but the rate limit stopped us.");
David Chen1d7b0cd2017-11-15 14:20:04 -0800588 return;
589 }
590 }
David Chen48944902018-05-03 10:29:11 -0700591 if (mSendBroadcast(key)) {
592 mOnDiskDataConfigs.erase(key);
593 VLOG("StatsD triggered data fetch for %s", key.ToString().c_str());
Tej Singh480392f2019-10-23 15:53:46 -0700594 mLastBroadcastTimes[key] = elapsedRealtimeNs;
David Chen48944902018-05-03 10:29:11 -0700595 StatsdStats::getInstance().noteBroadcastSent(key);
596 }
yro31eb67b2017-10-24 13:33:21 -0700597 }
598}
599
Chenjie Yue36018b2018-04-16 15:18:30 -0700600void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key,
Yangster-mac892f3d32018-05-02 14:16:48 -0700601 const int64_t timestampNs,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000602 const DumpReportReason dumpReportReason,
603 const DumpLatency dumpLatency) {
yro028091c2018-05-09 16:03:27 -0700604 if (mMetricsManagers.find(key) == mMetricsManagers.end() ||
605 !mMetricsManagers.find(key)->second->shouldWriteToDisk()) {
Yangster-mac892f3d32018-05-02 14:16:48 -0700606 return;
607 }
Yao Chen9a43b4f2019-04-10 10:43:20 -0700608 vector<uint8_t> buffer;
David Chen56ae0d92018-05-11 16:00:22 -0700609 onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/,
Yao Chen9a43b4f2019-04-10 10:43:20 -0700610 true /* erase_data */, dumpReportReason, dumpLatency, true,
611 &buffer);
612 string file_name =
613 StorageManager::getDataFileName((long)getWallClockSec(), key.GetUid(), key.GetId());
614 StorageManager::writeFile(file_name.c_str(), buffer.data(), buffer.size());
615
David Chen48944902018-05-03 10:29:11 -0700616 // We were able to write the ConfigMetricsReport to disk, so we should trigger collection ASAP.
617 mOnDiskDataConfigs.insert(key);
Yangster-mace68f3a52018-04-04 00:01:43 -0700618}
619
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700620void StatsLogProcessor::SaveActiveConfigsToDisk(int64_t currentTimeNs) {
Chenjie Yuc7939cb2019-02-04 17:25:45 -0800621 std::lock_guard<std::mutex> lock(mMetricsMutex);
jianjin996f40d2019-03-29 13:53:48 -0700622 const int64_t timeNs = getElapsedRealtimeNs();
623 // Do not write to disk if we already have in the last few seconds.
jianjin996f40d2019-03-29 13:53:48 -0700624 if (static_cast<unsigned long long> (timeNs) <
625 mLastActiveMetricsWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
626 ALOGI("Statsd skipping writing active metrics to disk. Already wrote data in last %d seconds",
627 WRITE_DATA_COOL_DOWN_SEC);
628 return;
629 }
630 mLastActiveMetricsWriteNs = timeNs;
631
Chenjie Yuc7939cb2019-02-04 17:25:45 -0800632 ProtoOutputStream proto;
Tej Singhf53d4452019-05-09 18:17:59 -0700633 WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, DEVICE_SHUTDOWN, &proto);
Chenjie Yuc7939cb2019-02-04 17:25:45 -0800634
635 string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
636 StorageManager::deleteFile(file_name.c_str());
637 android::base::unique_fd fd(
638 open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR));
639 if (fd == -1) {
640 ALOGE("Attempt to write %s but failed", file_name.c_str());
641 return;
642 }
643 proto.flush(fd.get());
644}
645
Tej Singhf53d4452019-05-09 18:17:59 -0700646void StatsLogProcessor::WriteActiveConfigsToProtoOutputStream(
647 int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
648 std::lock_guard<std::mutex> lock(mMetricsMutex);
649 WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, reason, proto);
650}
651
652void StatsLogProcessor::WriteActiveConfigsToProtoOutputStreamLocked(
653 int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
654 for (const auto& pair : mMetricsManagers) {
655 const sp<MetricsManager>& metricsManager = pair.second;
656 uint64_t configToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
657 FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG);
658 metricsManager->writeActiveConfigToProtoOutputStream(currentTimeNs, reason, proto);
659 proto->end(configToken);
660 }
661}
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700662void StatsLogProcessor::LoadActiveConfigsFromDisk() {
663 std::lock_guard<std::mutex> lock(mMetricsMutex);
Chenjie Yuc7939cb2019-02-04 17:25:45 -0800664 string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
665 int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700666 if (-1 == fd) {
667 VLOG("Attempt to read %s but failed", file_name.c_str());
668 StorageManager::deleteFile(file_name.c_str());
669 return;
Chenjie Yuc7939cb2019-02-04 17:25:45 -0800670 }
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700671 string content;
672 if (!android::base::ReadFdToString(fd, &content)) {
673 ALOGE("Attempt to read %s but failed", file_name.c_str());
674 close(fd);
675 StorageManager::deleteFile(file_name.c_str());
676 return;
677 }
678
679 close(fd);
680
681 ActiveConfigList activeConfigList;
682 if (!activeConfigList.ParseFromString(content)) {
683 ALOGE("Attempt to read %s but failed; failed to load active configs", file_name.c_str());
684 StorageManager::deleteFile(file_name.c_str());
685 return;
686 }
Tej Singhf53d4452019-05-09 18:17:59 -0700687 // Passing in mTimeBaseNs only works as long as we only load from disk is when statsd starts.
688 SetConfigsActiveStateLocked(activeConfigList, mTimeBaseNs);
689 StorageManager::deleteFile(file_name.c_str());
690}
691
692void StatsLogProcessor::SetConfigsActiveState(const ActiveConfigList& activeConfigList,
693 int64_t currentTimeNs) {
694 std::lock_guard<std::mutex> lock(mMetricsMutex);
695 SetConfigsActiveStateLocked(activeConfigList, currentTimeNs);
696}
697
698void StatsLogProcessor::SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
699 int64_t currentTimeNs) {
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700700 for (int i = 0; i < activeConfigList.config_size(); i++) {
701 const auto& config = activeConfigList.config(i);
702 ConfigKey key(config.uid(), config.id());
703 auto it = mMetricsManagers.find(key);
704 if (it == mMetricsManagers.end()) {
705 ALOGE("No config found for config %s", key.ToString().c_str());
706 continue;
707 }
708 VLOG("Setting active config %s", key.ToString().c_str());
Tej Singhf53d4452019-05-09 18:17:59 -0700709 it->second->loadActiveConfig(config, currentTimeNs);
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700710 }
711 VLOG("Successfully loaded %d active configs.", activeConfigList.config_size());
Chenjie Yuc7939cb2019-02-04 17:25:45 -0800712}
713
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000714void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
715 const DumpLatency dumpLatency) {
Yangster-mac892f3d32018-05-02 14:16:48 -0700716 const int64_t timeNs = getElapsedRealtimeNs();
Tej Singh42f9e062018-11-09 10:01:00 -0800717 // Do not write to disk if we already have in the last few seconds.
718 // This is to avoid overwriting files that would have the same name if we
719 // write twice in the same second.
720 if (static_cast<unsigned long long> (timeNs) <
721 mLastWriteTimeNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
722 ALOGI("Statsd skipping writing data to disk. Already wrote data in last %d seconds",
723 WRITE_DATA_COOL_DOWN_SEC);
724 return;
725 }
726 mLastWriteTimeNs = timeNs;
Yangster-mace68f3a52018-04-04 00:01:43 -0700727 for (auto& pair : mMetricsManagers) {
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000728 WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason, dumpLatency);
Yangster-mace68f3a52018-04-04 00:01:43 -0700729 }
730}
731
Muhammad Qureshi844694b2019-04-05 10:10:40 -0700732void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason,
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000733 const DumpLatency dumpLatency) {
Yangster-macb0d06282018-01-05 15:44:07 -0800734 std::lock_guard<std::mutex> lock(mMetricsMutex);
Olivier Gaillard6c75ecd2019-02-20 09:57:33 +0000735 WriteDataToDiskLocked(dumpReportReason, dumpLatency);
yro947fbce2017-11-15 22:50:23 -0800736}
737
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700738void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) {
Yangster6df5fcc2018-04-12 11:04:29 -0700739 std::lock_guard<std::mutex> lock(mMetricsMutex);
Chenjie Yue2219202018-06-08 10:07:51 -0700740 mPullerManager->OnAlarmFired(timestampNs);
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700741}
742
David Chend37bc232018-04-12 18:05:11 -0700743int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) {
744 auto it = mMetricsManagers.find(key);
745 if (it == mMetricsManagers.end()) {
746 return 0;
747 } else {
748 return it->second->getLastReportTimeNs();
749 }
750}
751
Tej Singh9ec159a2019-11-14 11:59:48 -0800752void StatsLogProcessor::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk,
753 const int uid, const int64_t version) {
754 std::lock_guard<std::mutex> lock(mMetricsMutex);
755 ALOGW("Received app upgrade");
756 for (auto it : mMetricsManagers) {
757 it.second->notifyAppUpgrade(eventTimeNs, apk, uid, version);
758 }
759}
760
761void StatsLogProcessor::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
762 const int uid) {
763 std::lock_guard<std::mutex> lock(mMetricsMutex);
764 ALOGW("Received app removed");
765 for (auto it : mMetricsManagers) {
766 it.second->notifyAppRemoved(eventTimeNs, apk, uid);
767 }
768}
769
770void StatsLogProcessor::onUidMapReceived(const int64_t& eventTimeNs) {
771 std::lock_guard<std::mutex> lock(mMetricsMutex);
772 ALOGW("Received uid map");
773 for (auto it : mMetricsManagers) {
774 it.second->onUidMapReceived(eventTimeNs);
775 }
776}
777
David Chen48944902018-05-03 10:29:11 -0700778void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) {
779 std::lock_guard<std::mutex> lock(mMetricsMutex);
780 mOnDiskDataConfigs.insert(key);
781}
782
Yao Chenef99c4f2017-09-22 16:26:54 -0700783} // namespace statsd
784} // namespace os
785} // namespace android