• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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 #define STATSD_DEBUG false  // STOPSHIP if true
17 #include "Log.h"
18 
19 #include "StatsdStats.h"
20 
21 #include <android/util/ProtoOutputStream.h>
22 
23 #include "../stats_log_util.h"
24 #include "statslog_statsd.h"
25 #include "storage/StorageManager.h"
26 #include "utils/ShardOffsetProvider.h"
27 
28 namespace android {
29 namespace os {
30 namespace statsd {
31 
32 using android::util::FIELD_COUNT_REPEATED;
33 using android::util::FIELD_TYPE_BOOL;
34 using android::util::FIELD_TYPE_ENUM;
35 using android::util::FIELD_TYPE_FLOAT;
36 using android::util::FIELD_TYPE_INT32;
37 using android::util::FIELD_TYPE_INT64;
38 using android::util::FIELD_TYPE_MESSAGE;
39 using android::util::FIELD_TYPE_STRING;
40 using android::util::FIELD_TYPE_UINT32;
41 using android::util::ProtoOutputStream;
42 using std::lock_guard;
43 using std::shared_ptr;
44 using std::string;
45 using std::to_string;
46 using std::vector;
47 
48 const int FIELD_ID_BEGIN_TIME = 1;
49 const int FIELD_ID_END_TIME = 2;
50 const int FIELD_ID_CONFIG_STATS = 3;
51 const int FIELD_ID_ATOM_STATS = 7;
52 const int FIELD_ID_UIDMAP_STATS = 8;
53 const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
54 const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
55 const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
56 const int FIELD_ID_LOGGER_ERROR_STATS = 16;
57 const int FIELD_ID_OVERFLOW = 18;
58 const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL = 19;
59 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS = 20;
60 const int FIELD_ID_SHARD_OFFSET = 21;
61 
62 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CALLING_UID = 1;
63 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_ID = 2;
64 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_UID = 3;
65 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_PACKAGE = 4;
66 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_INVALID_QUERY_REASON = 5;
67 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_QUERY_WALL_TIME_NS = 6;
68 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_HAS_ERROR = 7;
69 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_ERROR = 8;
70 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_LATENCY_NS = 9;
71 
72 const int FIELD_ID_ATOM_STATS_TAG = 1;
73 const int FIELD_ID_ATOM_STATS_COUNT = 2;
74 const int FIELD_ID_ATOM_STATS_ERROR_COUNT = 3;
75 const int FIELD_ID_ATOM_STATS_DROPS_COUNT = 4;
76 const int FIELD_ID_ATOM_STATS_SKIP_COUNT = 5;
77 
78 const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
79 const int FIELD_ID_PERIODIC_ALARMS_REGISTERED = 1;
80 
81 const int FIELD_ID_LOG_LOSS_STATS_TIME = 1;
82 const int FIELD_ID_LOG_LOSS_STATS_COUNT = 2;
83 const int FIELD_ID_LOG_LOSS_STATS_ERROR = 3;
84 const int FIELD_ID_LOG_LOSS_STATS_TAG = 4;
85 const int FIELD_ID_LOG_LOSS_STATS_UID = 5;
86 const int FIELD_ID_LOG_LOSS_STATS_PID = 6;
87 
88 const int FIELD_ID_OVERFLOW_COUNT = 1;
89 const int FIELD_ID_OVERFLOW_MAX_HISTORY = 2;
90 const int FIELD_ID_OVERFLOW_MIN_HISTORY = 3;
91 
92 const int FIELD_ID_CONFIG_STATS_UID = 1;
93 const int FIELD_ID_CONFIG_STATS_ID = 2;
94 const int FIELD_ID_CONFIG_STATS_CREATION = 3;
95 const int FIELD_ID_CONFIG_STATS_RESET = 19;
96 const int FIELD_ID_CONFIG_STATS_DELETION = 4;
97 const int FIELD_ID_CONFIG_STATS_METRIC_COUNT = 5;
98 const int FIELD_ID_CONFIG_STATS_CONDITION_COUNT = 6;
99 const int FIELD_ID_CONFIG_STATS_MATCHER_COUNT = 7;
100 const int FIELD_ID_CONFIG_STATS_ALERT_COUNT = 8;
101 const int FIELD_ID_CONFIG_STATS_VALID = 9;
102 const int FIELD_ID_CONFIG_STATS_INVALID_CONFIG_REASON = 24;
103 const int FIELD_ID_CONFIG_STATS_BROADCAST = 10;
104 const int FIELD_ID_CONFIG_STATS_DATA_DROP_TIME = 11;
105 const int FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES = 21;
106 const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME = 12;
107 const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES = 20;
108 const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13;
109 const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14;
110 const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15;
111 const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16;
112 const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17;
113 const int FIELD_ID_CONFIG_STATS_ANNOTATION = 18;
114 const int FIELD_ID_CONFIG_STATS_ACTIVATION = 22;
115 const int FIELD_ID_CONFIG_STATS_DEACTIVATION = 23;
116 const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT64 = 1;
117 const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT32 = 2;
118 const int FIELD_ID_CONFIG_STATS_RESTRICTED_METRIC_STATS = 25;
119 const int FIELD_ID_CONFIG_STATS_DEVICE_INFO_TABLE_CREATION_FAILED = 26;
120 const int FIELD_ID_CONFIG_STATS_RESTRICTED_DB_CORRUPTED_COUNT = 27;
121 const int FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_FLUSH_LATENCY = 28;
122 const int FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_TIME_SEC = 29;
123 const int FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_BYTES = 30;
124 
125 const int FIELD_ID_INVALID_CONFIG_REASON_ENUM = 1;
126 const int FIELD_ID_INVALID_CONFIG_REASON_METRIC_ID = 2;
127 const int FIELD_ID_INVALID_CONFIG_REASON_STATE_ID = 3;
128 const int FIELD_ID_INVALID_CONFIG_REASON_ALERT_ID = 4;
129 const int FIELD_ID_INVALID_CONFIG_REASON_ALARM_ID = 5;
130 const int FIELD_ID_INVALID_CONFIG_REASON_SUBSCRIPTION_ID = 6;
131 const int FIELD_ID_INVALID_CONFIG_REASON_MATCHER_ID = 7;
132 const int FIELD_ID_INVALID_CONFIG_REASON_CONDITION_ID = 8;
133 
134 const int FIELD_ID_MATCHER_STATS_ID = 1;
135 const int FIELD_ID_MATCHER_STATS_COUNT = 2;
136 const int FIELD_ID_CONDITION_STATS_ID = 1;
137 const int FIELD_ID_CONDITION_STATS_COUNT = 2;
138 const int FIELD_ID_METRIC_STATS_ID = 1;
139 const int FIELD_ID_METRIC_STATS_COUNT = 2;
140 const int FIELD_ID_ALERT_STATS_ID = 1;
141 const int FIELD_ID_ALERT_STATS_COUNT = 2;
142 
143 const int FIELD_ID_UID_MAP_CHANGES = 1;
144 const int FIELD_ID_UID_MAP_BYTES_USED = 2;
145 const int FIELD_ID_UID_MAP_DROPPED_CHANGES = 3;
146 const int FIELD_ID_UID_MAP_DELETED_APPS = 4;
147 
148 const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID = 1;
149 const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME = 2;
150 
151 // for RestrictedMetricStats proto
152 const int FIELD_ID_RESTRICTED_STATS_METRIC_ID = 1;
153 const int FIELD_ID_RESTRICTED_STATS_INSERT_ERROR = 2;
154 const int FIELD_ID_RESTRICTED_STATS_TABLE_CREATION_ERROR = 3;
155 const int FIELD_ID_RESTRICTED_STATS_TABLE_DELETION_ERROR = 4;
156 const int FIELD_ID_RESTRICTED_STATS_FLUSH_LATENCY = 5;
157 const int FIELD_ID_RESTRICTED_STATS_CATEGORY_CHANGED_COUNT = 6;
158 
159 const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySizeLimitMap = {
160         {util::BINDER_CALLS, {6000, 10000}},
161         {util::LOOPER_STATS, {1500, 2500}},
162         {util::CPU_TIME_PER_UID_FREQ, {6000, 10000}},
163 };
164 
StatsdStats()165 StatsdStats::StatsdStats() {
166     mPushedAtomStats.resize(kMaxPushedAtomId + 1);
167     mStartTimeSec = getWallClockSec();
168 }
169 
getInstance()170 StatsdStats& StatsdStats::getInstance() {
171     static StatsdStats statsInstance;
172     return statsInstance;
173 }
174 
addToIceBoxLocked(shared_ptr<ConfigStats> & stats)175 void StatsdStats::addToIceBoxLocked(shared_ptr<ConfigStats>& stats) {
176     // The size of mIceBox grows strictly by one at a time. It won't be > kMaxIceBoxSize.
177     if (mIceBox.size() == kMaxIceBoxSize) {
178         mIceBox.pop_front();
179     }
180     mIceBox.push_back(stats);
181 }
182 
noteConfigReceived(const ConfigKey & key,int metricsCount,int conditionsCount,int matchersCount,int alertsCount,const std::list<std::pair<const int64_t,const int32_t>> & annotations,const optional<InvalidConfigReason> & reason)183 void StatsdStats::noteConfigReceived(
184         const ConfigKey& key, int metricsCount, int conditionsCount, int matchersCount,
185         int alertsCount, const std::list<std::pair<const int64_t, const int32_t>>& annotations,
186         const optional<InvalidConfigReason>& reason) {
187     lock_guard<std::mutex> lock(mLock);
188     int32_t nowTimeSec = getWallClockSec();
189 
190     // If there is an existing config for the same key, icebox the old config.
191     noteConfigRemovedInternalLocked(key);
192 
193     shared_ptr<ConfigStats> configStats = std::make_shared<ConfigStats>();
194     configStats->uid = key.GetUid();
195     configStats->id = key.GetId();
196     configStats->creation_time_sec = nowTimeSec;
197     configStats->metric_count = metricsCount;
198     configStats->condition_count = conditionsCount;
199     configStats->matcher_count = matchersCount;
200     configStats->alert_count = alertsCount;
201     configStats->is_valid = !reason.has_value();
202     configStats->reason = reason;
203     for (auto& v : annotations) {
204         configStats->annotations.emplace_back(v);
205     }
206 
207     if (!reason.has_value()) {
208         mConfigStats[key] = configStats;
209     } else {
210         configStats->deletion_time_sec = nowTimeSec;
211         addToIceBoxLocked(configStats);
212     }
213 }
214 
noteConfigRemovedInternalLocked(const ConfigKey & key)215 void StatsdStats::noteConfigRemovedInternalLocked(const ConfigKey& key) {
216     auto it = mConfigStats.find(key);
217     if (it != mConfigStats.end()) {
218         int32_t nowTimeSec = getWallClockSec();
219         it->second->deletion_time_sec = nowTimeSec;
220         addToIceBoxLocked(it->second);
221         mConfigStats.erase(it);
222     }
223 }
224 
noteConfigRemoved(const ConfigKey & key)225 void StatsdStats::noteConfigRemoved(const ConfigKey& key) {
226     lock_guard<std::mutex> lock(mLock);
227     noteConfigRemovedInternalLocked(key);
228 }
229 
noteConfigResetInternalLocked(const ConfigKey & key)230 void StatsdStats::noteConfigResetInternalLocked(const ConfigKey& key) {
231     auto it = mConfigStats.find(key);
232     if (it != mConfigStats.end()) {
233         it->second->reset_time_sec = getWallClockSec();
234     }
235 }
236 
noteConfigReset(const ConfigKey & key)237 void StatsdStats::noteConfigReset(const ConfigKey& key) {
238     lock_guard<std::mutex> lock(mLock);
239     noteConfigResetInternalLocked(key);
240 }
241 
noteLogLost(int32_t wallClockTimeSec,int32_t count,int32_t lastError,int32_t lastTag,int32_t uid,int32_t pid)242 void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
243                               int32_t lastTag, int32_t uid, int32_t pid) {
244     lock_guard<std::mutex> lock(mLock);
245     if (mLogLossStats.size() == kMaxLoggerErrors) {
246         mLogLossStats.pop_front();
247     }
248     mLogLossStats.emplace_back(wallClockTimeSec, count, lastError, lastTag, uid, pid);
249 }
250 
noteBroadcastSent(const ConfigKey & key)251 void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
252     noteBroadcastSent(key, getWallClockSec());
253 }
254 
noteBroadcastSent(const ConfigKey & key,int32_t timeSec)255 void StatsdStats::noteBroadcastSent(const ConfigKey& key, int32_t timeSec) {
256     lock_guard<std::mutex> lock(mLock);
257     auto it = mConfigStats.find(key);
258     if (it == mConfigStats.end()) {
259         ALOGE("Config key %s not found!", key.ToString().c_str());
260         return;
261     }
262     if (it->second->broadcast_sent_time_sec.size() == kMaxTimestampCount) {
263         it->second->broadcast_sent_time_sec.pop_front();
264     }
265     it->second->broadcast_sent_time_sec.push_back(timeSec);
266 }
267 
noteActiveStatusChanged(const ConfigKey & key,bool activated)268 void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated) {
269     noteActiveStatusChanged(key, activated, getWallClockSec());
270 }
271 
noteActiveStatusChanged(const ConfigKey & key,bool activated,int32_t timeSec)272 void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated, int32_t timeSec) {
273     lock_guard<std::mutex> lock(mLock);
274     auto it = mConfigStats.find(key);
275     if (it == mConfigStats.end()) {
276         ALOGE("Config key %s not found!", key.ToString().c_str());
277         return;
278     }
279     auto& vec = activated ? it->second->activation_time_sec
280                           : it->second->deactivation_time_sec;
281     if (vec.size() == kMaxTimestampCount) {
282         vec.pop_front();
283     }
284     vec.push_back(timeSec);
285 }
286 
noteActivationBroadcastGuardrailHit(const int uid)287 void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid) {
288     noteActivationBroadcastGuardrailHit(uid, getWallClockSec());
289 }
290 
noteActivationBroadcastGuardrailHit(const int uid,const int32_t timeSec)291 void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid, const int32_t timeSec) {
292     lock_guard<std::mutex> lock(mLock);
293     auto& guardrailTimes = mActivationBroadcastGuardrailStats[uid];
294     if (guardrailTimes.size() == kMaxTimestampCount) {
295         guardrailTimes.pop_front();
296     }
297     guardrailTimes.push_back(timeSec);
298 }
299 
noteDataDropped(const ConfigKey & key,const size_t totalBytes)300 void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes) {
301     noteDataDropped(key, totalBytes, getWallClockSec());
302 }
303 
noteEventQueueOverflow(int64_t oldestEventTimestampNs,int32_t atomId,bool isSkipped)304 void StatsdStats::noteEventQueueOverflow(int64_t oldestEventTimestampNs, int32_t atomId,
305                                          bool isSkipped) {
306     lock_guard<std::mutex> lock(mLock);
307 
308     mOverflowCount++;
309 
310     int64_t history = getElapsedRealtimeNs() - oldestEventTimestampNs;
311 
312     if (history > mMaxQueueHistoryNs) {
313         mMaxQueueHistoryNs = history;
314     }
315 
316     if (history < mMinQueueHistoryNs) {
317         mMinQueueHistoryNs = history;
318     }
319 
320     noteAtomLoggedLocked(atomId, isSkipped);
321     noteAtomDroppedLocked(atomId);
322 }
323 
noteAtomDroppedLocked(int32_t atomId)324 void StatsdStats::noteAtomDroppedLocked(int32_t atomId) {
325     constexpr int kMaxPushedAtomDroppedStatsSize = kMaxPushedAtomId + kMaxNonPlatformPushedAtoms;
326     if (mPushedAtomDropsStats.size() < kMaxPushedAtomDroppedStatsSize ||
327         mPushedAtomDropsStats.find(atomId) != mPushedAtomDropsStats.end()) {
328         mPushedAtomDropsStats[atomId]++;
329     }
330 }
331 
noteDataDropped(const ConfigKey & key,const size_t totalBytes,int32_t timeSec)332 void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec) {
333     lock_guard<std::mutex> lock(mLock);
334     auto it = mConfigStats.find(key);
335     if (it == mConfigStats.end()) {
336         ALOGE("Config key %s not found!", key.ToString().c_str());
337         return;
338     }
339     if (it->second->data_drop_time_sec.size() == kMaxTimestampCount) {
340         it->second->data_drop_time_sec.pop_front();
341         it->second->data_drop_bytes.pop_front();
342     }
343     it->second->data_drop_time_sec.push_back(timeSec);
344     it->second->data_drop_bytes.push_back(totalBytes);
345 }
346 
noteMetricsReportSent(const ConfigKey & key,const size_t num_bytes)347 void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes) {
348     noteMetricsReportSent(key, num_bytes, getWallClockSec());
349 }
350 
noteMetricsReportSent(const ConfigKey & key,const size_t num_bytes,int32_t timeSec)351 void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes,
352                                         int32_t timeSec) {
353     lock_guard<std::mutex> lock(mLock);
354     auto it = mConfigStats.find(key);
355     if (it == mConfigStats.end()) {
356         ALOGE("Config key %s not found!", key.ToString().c_str());
357         return;
358     }
359     if (it->second->dump_report_stats.size() == kMaxTimestampCount) {
360         it->second->dump_report_stats.pop_front();
361     }
362     it->second->dump_report_stats.push_back(std::make_pair(timeSec, num_bytes));
363 }
364 
noteDeviceInfoTableCreationFailed(const ConfigKey & key)365 void StatsdStats::noteDeviceInfoTableCreationFailed(const ConfigKey& key) {
366     lock_guard<std::mutex> lock(mLock);
367     auto it = mConfigStats.find(key);
368     if (it == mConfigStats.end()) {
369         ALOGE("Config key %s not found!", key.ToString().c_str());
370         return;
371     }
372     it->second->device_info_table_creation_failed = true;
373 }
374 
noteDbCorrupted(const ConfigKey & key)375 void StatsdStats::noteDbCorrupted(const ConfigKey& key) {
376     lock_guard<std::mutex> lock(mLock);
377     auto it = mConfigStats.find(key);
378     if (it == mConfigStats.end()) {
379         ALOGE("Config key %s not found!", key.ToString().c_str());
380         return;
381     }
382     it->second->db_corrupted_count++;
383 }
384 
noteUidMapDropped(int deltas)385 void StatsdStats::noteUidMapDropped(int deltas) {
386     lock_guard<std::mutex> lock(mLock);
387     mUidMapStats.dropped_changes += mUidMapStats.dropped_changes + deltas;
388 }
389 
noteUidMapAppDeletionDropped()390 void StatsdStats::noteUidMapAppDeletionDropped() {
391     lock_guard<std::mutex> lock(mLock);
392     mUidMapStats.deleted_apps++;
393 }
394 
setUidMapChanges(int changes)395 void StatsdStats::setUidMapChanges(int changes) {
396     lock_guard<std::mutex> lock(mLock);
397     mUidMapStats.changes = changes;
398 }
399 
setCurrentUidMapMemory(int bytes)400 void StatsdStats::setCurrentUidMapMemory(int bytes) {
401     lock_guard<std::mutex> lock(mLock);
402     mUidMapStats.bytes_used = bytes;
403 }
404 
noteConditionDimensionSize(const ConfigKey & key,const int64_t & id,int size)405 void StatsdStats::noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
406     lock_guard<std::mutex> lock(mLock);
407     // if name doesn't exist before, it will create the key with count 0.
408     auto statsIt = mConfigStats.find(key);
409     if (statsIt == mConfigStats.end()) {
410         return;
411     }
412 
413     auto& conditionSizeMap = statsIt->second->condition_stats;
414     if (size > conditionSizeMap[id]) {
415         conditionSizeMap[id] = size;
416     }
417 }
418 
noteMetricDimensionSize(const ConfigKey & key,const int64_t & id,int size)419 void StatsdStats::noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size) {
420     lock_guard<std::mutex> lock(mLock);
421     // if name doesn't exist before, it will create the key with count 0.
422     auto statsIt = mConfigStats.find(key);
423     if (statsIt == mConfigStats.end()) {
424         return;
425     }
426     auto& metricsDimensionMap = statsIt->second->metric_stats;
427     if (size > metricsDimensionMap[id]) {
428         metricsDimensionMap[id] = size;
429     }
430 }
431 
noteMetricDimensionInConditionSize(const ConfigKey & key,const int64_t & id,int size)432 void StatsdStats::noteMetricDimensionInConditionSize(
433         const ConfigKey& key, const int64_t& id, int size) {
434     lock_guard<std::mutex> lock(mLock);
435     // if name doesn't exist before, it will create the key with count 0.
436     auto statsIt = mConfigStats.find(key);
437     if (statsIt == mConfigStats.end()) {
438         return;
439     }
440     auto& metricsDimensionMap = statsIt->second->metric_dimension_in_condition_stats;
441     if (size > metricsDimensionMap[id]) {
442         metricsDimensionMap[id] = size;
443     }
444 }
445 
noteMatcherMatched(const ConfigKey & key,const int64_t & id)446 void StatsdStats::noteMatcherMatched(const ConfigKey& key, const int64_t& id) {
447     lock_guard<std::mutex> lock(mLock);
448 
449     auto statsIt = mConfigStats.find(key);
450     if (statsIt == mConfigStats.end()) {
451         return;
452     }
453     statsIt->second->matcher_stats[id]++;
454 }
455 
noteAnomalyDeclared(const ConfigKey & key,const int64_t & id)456 void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const int64_t& id) {
457     lock_guard<std::mutex> lock(mLock);
458     auto statsIt = mConfigStats.find(key);
459     if (statsIt == mConfigStats.end()) {
460         return;
461     }
462     statsIt->second->alert_stats[id]++;
463 }
464 
noteRegisteredAnomalyAlarmChanged()465 void StatsdStats::noteRegisteredAnomalyAlarmChanged() {
466     lock_guard<std::mutex> lock(mLock);
467     mAnomalyAlarmRegisteredStats++;
468 }
469 
noteRegisteredPeriodicAlarmChanged()470 void StatsdStats::noteRegisteredPeriodicAlarmChanged() {
471     lock_guard<std::mutex> lock(mLock);
472     mPeriodicAlarmRegisteredStats++;
473 }
474 
updateMinPullIntervalSec(int pullAtomId,long intervalSec)475 void StatsdStats::updateMinPullIntervalSec(int pullAtomId, long intervalSec) {
476     lock_guard<std::mutex> lock(mLock);
477     mPulledAtomStats[pullAtomId].minPullIntervalSec =
478             std::min(mPulledAtomStats[pullAtomId].minPullIntervalSec, intervalSec);
479 }
480 
notePull(int pullAtomId)481 void StatsdStats::notePull(int pullAtomId) {
482     lock_guard<std::mutex> lock(mLock);
483     mPulledAtomStats[pullAtomId].totalPull++;
484 }
485 
notePullFromCache(int pullAtomId)486 void StatsdStats::notePullFromCache(int pullAtomId) {
487     lock_guard<std::mutex> lock(mLock);
488     mPulledAtomStats[pullAtomId].totalPullFromCache++;
489 }
490 
notePullTime(int pullAtomId,int64_t pullTimeNs)491 void StatsdStats::notePullTime(int pullAtomId, int64_t pullTimeNs) {
492     lock_guard<std::mutex> lock(mLock);
493     auto& pullStats = mPulledAtomStats[pullAtomId];
494     pullStats.maxPullTimeNs = std::max(pullStats.maxPullTimeNs, pullTimeNs);
495     pullStats.avgPullTimeNs = (pullStats.avgPullTimeNs * pullStats.numPullTime + pullTimeNs) /
496                               (pullStats.numPullTime + 1);
497     pullStats.numPullTime += 1;
498 }
499 
notePullDelay(int pullAtomId,int64_t pullDelayNs)500 void StatsdStats::notePullDelay(int pullAtomId, int64_t pullDelayNs) {
501     lock_guard<std::mutex> lock(mLock);
502     auto& pullStats = mPulledAtomStats[pullAtomId];
503     pullStats.maxPullDelayNs = std::max(pullStats.maxPullDelayNs, pullDelayNs);
504     pullStats.avgPullDelayNs =
505         (pullStats.avgPullDelayNs * pullStats.numPullDelay + pullDelayNs) /
506             (pullStats.numPullDelay + 1);
507     pullStats.numPullDelay += 1;
508 }
509 
notePullDataError(int pullAtomId)510 void StatsdStats::notePullDataError(int pullAtomId) {
511     lock_guard<std::mutex> lock(mLock);
512     mPulledAtomStats[pullAtomId].dataError++;
513 }
514 
notePullTimeout(int pullAtomId,int64_t pullUptimeMillis,int64_t pullElapsedMillis)515 void StatsdStats::notePullTimeout(int pullAtomId,
516                                   int64_t pullUptimeMillis,
517                                   int64_t pullElapsedMillis) {
518     lock_guard<std::mutex> lock(mLock);
519     PulledAtomStats& pulledAtomStats = mPulledAtomStats[pullAtomId];
520     pulledAtomStats.pullTimeout++;
521 
522     if (pulledAtomStats.pullTimeoutMetadata.size() == kMaxTimestampCount) {
523         pulledAtomStats.pullTimeoutMetadata.pop_front();
524     }
525 
526     pulledAtomStats.pullTimeoutMetadata.emplace_back(pullUptimeMillis, pullElapsedMillis);
527 }
528 
notePullExceedMaxDelay(int pullAtomId)529 void StatsdStats::notePullExceedMaxDelay(int pullAtomId) {
530     lock_guard<std::mutex> lock(mLock);
531     mPulledAtomStats[pullAtomId].pullExceedMaxDelay++;
532 }
533 
noteAtomLogged(int atomId,int32_t,bool isSkipped)534 void StatsdStats::noteAtomLogged(int atomId, int32_t /*timeSec*/, bool isSkipped) {
535     lock_guard<std::mutex> lock(mLock);
536 
537     noteAtomLoggedLocked(atomId, isSkipped);
538 }
539 
noteAtomLoggedLocked(int atomId,bool isSkipped)540 void StatsdStats::noteAtomLoggedLocked(int atomId, bool isSkipped) {
541     if (atomId >= 0 && atomId <= kMaxPushedAtomId) {
542         mPushedAtomStats[atomId].logCount++;
543         mPushedAtomStats[atomId].skipCount += isSkipped;
544     } else {
545         if (atomId < 0) {
546             android_errorWriteLog(0x534e4554, "187957589");
547         }
548         if (mNonPlatformPushedAtomStats.size() < kMaxNonPlatformPushedAtoms ||
549             mNonPlatformPushedAtomStats.find(atomId) != mNonPlatformPushedAtomStats.end()) {
550             mNonPlatformPushedAtomStats[atomId].logCount++;
551             mNonPlatformPushedAtomStats[atomId].skipCount += isSkipped;
552         }
553     }
554 }
555 
noteSystemServerRestart(int32_t timeSec)556 void StatsdStats::noteSystemServerRestart(int32_t timeSec) {
557     lock_guard<std::mutex> lock(mLock);
558 
559     if (mSystemServerRestartSec.size() == kMaxSystemServerRestarts) {
560         mSystemServerRestartSec.pop_front();
561     }
562     mSystemServerRestartSec.push_back(timeSec);
563 }
564 
notePullFailed(int atomId)565 void StatsdStats::notePullFailed(int atomId) {
566     lock_guard<std::mutex> lock(mLock);
567     mPulledAtomStats[atomId].pullFailed++;
568 }
569 
notePullUidProviderNotFound(int atomId)570 void StatsdStats::notePullUidProviderNotFound(int atomId) {
571     lock_guard<std::mutex> lock(mLock);
572     mPulledAtomStats[atomId].pullUidProviderNotFound++;
573 }
574 
notePullerNotFound(int atomId)575 void StatsdStats::notePullerNotFound(int atomId) {
576     lock_guard<std::mutex> lock(mLock);
577     mPulledAtomStats[atomId].pullerNotFound++;
578 }
579 
notePullBinderCallFailed(int atomId)580 void StatsdStats::notePullBinderCallFailed(int atomId) {
581     lock_guard<std::mutex> lock(mLock);
582     mPulledAtomStats[atomId].binderCallFailCount++;
583 }
584 
noteEmptyData(int atomId)585 void StatsdStats::noteEmptyData(int atomId) {
586     lock_guard<std::mutex> lock(mLock);
587     mPulledAtomStats[atomId].emptyData++;
588 }
589 
notePullerCallbackRegistrationChanged(int atomId,bool registered)590 void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
591     lock_guard<std::mutex> lock(mLock);
592     if (registered) {
593         mPulledAtomStats[atomId].registeredCount++;
594     } else {
595         mPulledAtomStats[atomId].unregisteredCount++;
596     }
597 }
598 
noteHardDimensionLimitReached(int64_t metricId)599 void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
600     lock_guard<std::mutex> lock(mLock);
601     getAtomMetricStats(metricId).hardDimensionLimitReached++;
602 }
603 
noteLateLogEventSkipped(int64_t metricId)604 void StatsdStats::noteLateLogEventSkipped(int64_t metricId) {
605     lock_guard<std::mutex> lock(mLock);
606     getAtomMetricStats(metricId).lateLogEventSkipped++;
607 }
608 
noteSkippedForwardBuckets(int64_t metricId)609 void StatsdStats::noteSkippedForwardBuckets(int64_t metricId) {
610     lock_guard<std::mutex> lock(mLock);
611     getAtomMetricStats(metricId).skippedForwardBuckets++;
612 }
613 
noteBadValueType(int64_t metricId)614 void StatsdStats::noteBadValueType(int64_t metricId) {
615     lock_guard<std::mutex> lock(mLock);
616     getAtomMetricStats(metricId).badValueType++;
617 }
618 
noteBucketDropped(int64_t metricId)619 void StatsdStats::noteBucketDropped(int64_t metricId) {
620     lock_guard<std::mutex> lock(mLock);
621     getAtomMetricStats(metricId).bucketDropped++;
622 }
623 
noteBucketUnknownCondition(int64_t metricId)624 void StatsdStats::noteBucketUnknownCondition(int64_t metricId) {
625     lock_guard<std::mutex> lock(mLock);
626     getAtomMetricStats(metricId).bucketUnknownCondition++;
627 }
628 
noteConditionChangeInNextBucket(int64_t metricId)629 void StatsdStats::noteConditionChangeInNextBucket(int64_t metricId) {
630     lock_guard<std::mutex> lock(mLock);
631     getAtomMetricStats(metricId).conditionChangeInNextBucket++;
632 }
633 
noteInvalidatedBucket(int64_t metricId)634 void StatsdStats::noteInvalidatedBucket(int64_t metricId) {
635     lock_guard<std::mutex> lock(mLock);
636     getAtomMetricStats(metricId).invalidatedBucket++;
637 }
638 
noteBucketCount(int64_t metricId)639 void StatsdStats::noteBucketCount(int64_t metricId) {
640     lock_guard<std::mutex> lock(mLock);
641     getAtomMetricStats(metricId).bucketCount++;
642 }
643 
noteBucketBoundaryDelayNs(int64_t metricId,int64_t timeDelayNs)644 void StatsdStats::noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs) {
645     lock_guard<std::mutex> lock(mLock);
646     AtomMetricStats& metricStats = getAtomMetricStats(metricId);
647     metricStats.maxBucketBoundaryDelayNs =
648             std::max(metricStats.maxBucketBoundaryDelayNs, timeDelayNs);
649     metricStats.minBucketBoundaryDelayNs =
650             std::min(metricStats.minBucketBoundaryDelayNs, timeDelayNs);
651 }
652 
noteAtomError(int atomTag,bool pull)653 void StatsdStats::noteAtomError(int atomTag, bool pull) {
654     lock_guard<std::mutex> lock(mLock);
655     if (pull) {
656         mPulledAtomStats[atomTag].atomErrorCount++;
657         return;
658     }
659 
660     bool present = (mPushedAtomErrorStats.find(atomTag) != mPushedAtomErrorStats.end());
661     bool full = (mPushedAtomErrorStats.size() >= (size_t)kMaxPushedAtomErrorStatsSize);
662     if (!full || present) {
663         mPushedAtomErrorStats[atomTag]++;
664     }
665 }
666 
noteQueryRestrictedMetricSucceed(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const int64_t latencyNs)667 void StatsdStats::noteQueryRestrictedMetricSucceed(const int64_t configId,
668                                                    const string& configPackage,
669                                                    const std::optional<int32_t> configUid,
670                                                    const int32_t callingUid,
671                                                    const int64_t latencyNs) {
672     lock_guard<std::mutex> lock(mLock);
673 
674     if (mRestrictedMetricQueryStats.size() == kMaxRestrictedMetricQueryCount) {
675         mRestrictedMetricQueryStats.pop_front();
676     }
677     mRestrictedMetricQueryStats.emplace_back(RestrictedMetricQueryStats(
678             callingUid, configId, configPackage, configUid, getWallClockNs(),
679             /*invalidQueryReason=*/std::nullopt, /*error=*/"", latencyNs));
680 }
681 
noteQueryRestrictedMetricFailed(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const InvalidQueryReason reason)682 void StatsdStats::noteQueryRestrictedMetricFailed(const int64_t configId,
683                                                   const string& configPackage,
684                                                   const std::optional<int32_t> configUid,
685                                                   const int32_t callingUid,
686                                                   const InvalidQueryReason reason) {
687     lock_guard<std::mutex> lock(mLock);
688     noteQueryRestrictedMetricFailedLocked(configId, configPackage, configUid, callingUid, reason,
689                                           /*error=*/"");
690 }
691 
noteQueryRestrictedMetricFailed(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const InvalidQueryReason reason,const string & error)692 void StatsdStats::noteQueryRestrictedMetricFailed(
693         const int64_t configId, const string& configPackage, const std::optional<int32_t> configUid,
694         const int32_t callingUid, const InvalidQueryReason reason, const string& error) {
695     lock_guard<std::mutex> lock(mLock);
696     noteQueryRestrictedMetricFailedLocked(configId, configPackage, configUid, callingUid, reason,
697                                           error);
698 }
699 
noteQueryRestrictedMetricFailedLocked(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const InvalidQueryReason reason,const string & error)700 void StatsdStats::noteQueryRestrictedMetricFailedLocked(
701         const int64_t configId, const string& configPackage, const std::optional<int32_t> configUid,
702         const int32_t callingUid, const InvalidQueryReason reason, const string& error) {
703     if (mRestrictedMetricQueryStats.size() == kMaxRestrictedMetricQueryCount) {
704         mRestrictedMetricQueryStats.pop_front();
705     }
706     mRestrictedMetricQueryStats.emplace_back(RestrictedMetricQueryStats(
707             callingUid, configId, configPackage, configUid, getWallClockNs(), reason, error,
708             /*queryLatencyNs=*/std::nullopt));
709 }
710 
noteRestrictedMetricInsertError(const ConfigKey & configKey,const int64_t metricId)711 void StatsdStats::noteRestrictedMetricInsertError(const ConfigKey& configKey,
712                                                   const int64_t metricId) {
713     lock_guard<std::mutex> lock(mLock);
714     auto it = mConfigStats.find(configKey);
715     if (it != mConfigStats.end()) {
716         it->second->restricted_metric_stats[metricId].insertError++;
717     }
718 }
719 
noteRestrictedMetricTableCreationError(const ConfigKey & configKey,const int64_t metricId)720 void StatsdStats::noteRestrictedMetricTableCreationError(const ConfigKey& configKey,
721                                                          const int64_t metricId) {
722     lock_guard<std::mutex> lock(mLock);
723     auto it = mConfigStats.find(configKey);
724     if (it != mConfigStats.end()) {
725         it->second->restricted_metric_stats[metricId].tableCreationError++;
726     }
727 }
728 
noteRestrictedMetricTableDeletionError(const ConfigKey & configKey,const int64_t metricId)729 void StatsdStats::noteRestrictedMetricTableDeletionError(const ConfigKey& configKey,
730                                                          const int64_t metricId) {
731     lock_guard<std::mutex> lock(mLock);
732     auto it = mConfigStats.find(configKey);
733     if (it != mConfigStats.end()) {
734         it->second->restricted_metric_stats[metricId].tableDeletionError++;
735     }
736 }
737 
noteRestrictedMetricFlushLatency(const ConfigKey & configKey,const int64_t metricId,const int64_t flushLatencyNs)738 void StatsdStats::noteRestrictedMetricFlushLatency(const ConfigKey& configKey,
739                                                    const int64_t metricId,
740                                                    const int64_t flushLatencyNs) {
741     lock_guard<std::mutex> lock(mLock);
742     auto it = mConfigStats.find(configKey);
743     if (it == mConfigStats.end()) {
744         ALOGE("Config key %s not found!", configKey.ToString().c_str());
745         return;
746     }
747     auto& restrictedMetricStats = it->second->restricted_metric_stats[metricId];
748     if (restrictedMetricStats.flushLatencyNs.size() == kMaxRestrictedMetricFlushLatencyCount) {
749         restrictedMetricStats.flushLatencyNs.pop_front();
750     }
751     restrictedMetricStats.flushLatencyNs.push_back(flushLatencyNs);
752 }
753 
noteRestrictedConfigFlushLatency(const ConfigKey & configKey,const int64_t totalFlushLatencyNs)754 void StatsdStats::noteRestrictedConfigFlushLatency(const ConfigKey& configKey,
755                                                    const int64_t totalFlushLatencyNs) {
756     lock_guard<std::mutex> lock(mLock);
757     auto it = mConfigStats.find(configKey);
758     if (it == mConfigStats.end()) {
759         ALOGE("Config key %s not found!", configKey.ToString().c_str());
760         return;
761     }
762     std::list<int64_t>& totalFlushLatencies = it->second->total_flush_latency_ns;
763     if (totalFlushLatencies.size() == kMaxRestrictedConfigFlushLatencyCount) {
764         totalFlushLatencies.pop_front();
765     }
766     totalFlushLatencies.push_back(totalFlushLatencyNs);
767 }
768 
noteRestrictedConfigDbSize(const ConfigKey & configKey,const int64_t elapsedTimeNs,const int64_t dbSize)769 void StatsdStats::noteRestrictedConfigDbSize(const ConfigKey& configKey,
770                                              const int64_t elapsedTimeNs, const int64_t dbSize) {
771     lock_guard<std::mutex> lock(mLock);
772     auto it = mConfigStats.find(configKey);
773     if (it == mConfigStats.end()) {
774         ALOGE("Config key %s not found!", configKey.ToString().c_str());
775         return;
776     }
777     std::list<int64_t>& totalDbSizeTimestamps = it->second->total_db_size_timestamps;
778     std::list<int64_t>& totaDbSizes = it->second->total_db_sizes;
779     if (totalDbSizeTimestamps.size() == kMaxRestrictedConfigDbSizeCount) {
780         totalDbSizeTimestamps.pop_front();
781         totaDbSizes.pop_front();
782     }
783     totalDbSizeTimestamps.push_back(elapsedTimeNs);
784     totaDbSizes.push_back(dbSize);
785 }
786 
noteRestrictedMetricCategoryChanged(const ConfigKey & configKey,const int64_t metricId)787 void StatsdStats::noteRestrictedMetricCategoryChanged(const ConfigKey& configKey,
788                                                       const int64_t metricId) {
789     lock_guard<std::mutex> lock(mLock);
790     auto it = mConfigStats.find(configKey);
791     if (it == mConfigStats.end()) {
792         ALOGE("Config key %s not found!", configKey.ToString().c_str());
793         return;
794     }
795     it->second->restricted_metric_stats[metricId].categoryChangedCount++;
796 }
797 
getAtomMetricStats(int64_t metricId)798 StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int64_t metricId) {
799     auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
800     if (atomMetricStatsIter != mAtomMetricStats.end()) {
801         return atomMetricStatsIter->second;
802     }
803     auto emplaceResult = mAtomMetricStats.emplace(metricId, AtomMetricStats());
804     return emplaceResult.first->second;
805 }
806 
reset()807 void StatsdStats::reset() {
808     lock_guard<std::mutex> lock(mLock);
809     resetInternalLocked();
810 }
811 
resetInternalLocked()812 void StatsdStats::resetInternalLocked() {
813     // Reset the historical data, but keep the active ConfigStats
814     mStartTimeSec = getWallClockSec();
815     mIceBox.clear();
816     std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), PushedAtomStats());
817     mNonPlatformPushedAtomStats.clear();
818     mAnomalyAlarmRegisteredStats = 0;
819     mPeriodicAlarmRegisteredStats = 0;
820     mSystemServerRestartSec.clear();
821     mLogLossStats.clear();
822     mOverflowCount = 0;
823     mMinQueueHistoryNs = kInt64Max;
824     mMaxQueueHistoryNs = 0;
825     for (auto& config : mConfigStats) {
826         config.second->broadcast_sent_time_sec.clear();
827         config.second->activation_time_sec.clear();
828         config.second->deactivation_time_sec.clear();
829         config.second->data_drop_time_sec.clear();
830         config.second->data_drop_bytes.clear();
831         config.second->dump_report_stats.clear();
832         config.second->annotations.clear();
833         config.second->matcher_stats.clear();
834         config.second->condition_stats.clear();
835         config.second->metric_stats.clear();
836         config.second->metric_dimension_in_condition_stats.clear();
837         config.second->alert_stats.clear();
838         config.second->restricted_metric_stats.clear();
839         config.second->db_corrupted_count = 0;
840         config.second->total_flush_latency_ns.clear();
841         config.second->total_db_size_timestamps.clear();
842         config.second->total_db_sizes.clear();
843     }
844     for (auto& pullStats : mPulledAtomStats) {
845         pullStats.second.totalPull = 0;
846         pullStats.second.totalPullFromCache = 0;
847         pullStats.second.minPullIntervalSec = LONG_MAX;
848         pullStats.second.avgPullTimeNs = 0;
849         pullStats.second.maxPullTimeNs = 0;
850         pullStats.second.numPullTime = 0;
851         pullStats.second.avgPullDelayNs = 0;
852         pullStats.second.maxPullDelayNs = 0;
853         pullStats.second.numPullDelay = 0;
854         pullStats.second.dataError = 0;
855         pullStats.second.pullTimeout = 0;
856         pullStats.second.pullExceedMaxDelay = 0;
857         pullStats.second.pullFailed = 0;
858         pullStats.second.pullUidProviderNotFound = 0;
859         pullStats.second.pullerNotFound = 0;
860         pullStats.second.registeredCount = 0;
861         pullStats.second.unregisteredCount = 0;
862         pullStats.second.atomErrorCount = 0;
863         pullStats.second.binderCallFailCount = 0;
864         pullStats.second.pullTimeoutMetadata.clear();
865     }
866     mAtomMetricStats.clear();
867     mActivationBroadcastGuardrailStats.clear();
868     mPushedAtomErrorStats.clear();
869     mPushedAtomDropsStats.clear();
870     mRestrictedMetricQueryStats.clear();
871 }
872 
buildTimeString(int64_t timeSec)873 string buildTimeString(int64_t timeSec) {
874     time_t t = timeSec;
875     struct tm* tm = localtime(&t);
876     char timeBuffer[80];
877     strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm);
878     return string(timeBuffer);
879 }
880 
getPushedAtomErrorsLocked(int atomId) const881 int StatsdStats::getPushedAtomErrorsLocked(int atomId) const {
882     const auto& it = mPushedAtomErrorStats.find(atomId);
883     if (it != mPushedAtomErrorStats.end()) {
884         return it->second;
885     } else {
886         return 0;
887     }
888 }
889 
getPushedAtomDropsLocked(int atomId) const890 int StatsdStats::getPushedAtomDropsLocked(int atomId) const {
891     const auto& it = mPushedAtomDropsStats.find(atomId);
892     if (it != mPushedAtomDropsStats.end()) {
893         return it->second;
894     } else {
895         return 0;
896     }
897 }
898 
dumpStats(int out) const899 void StatsdStats::dumpStats(int out) const {
900     lock_guard<std::mutex> lock(mLock);
901     time_t t = mStartTimeSec;
902     struct tm* tm = localtime(&t);
903     char timeBuffer[80];
904     strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
905     dprintf(out, "Stats collection start second: %s\n", timeBuffer);
906     dprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
907     for (const auto& configStats : mIceBox) {
908         dprintf(out,
909                 "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, "
910                 "#matcher=%d, #alert=%d, valid=%d, device_info_table_creation_failed=%d, "
911                 "db_corrupted_count=%d\n",
912                 configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
913                 configStats->deletion_time_sec, configStats->reset_time_sec,
914                 configStats->metric_count, configStats->condition_count, configStats->matcher_count,
915                 configStats->alert_count, configStats->is_valid,
916                 configStats->device_info_table_creation_failed, configStats->db_corrupted_count);
917 
918         if (!configStats->is_valid) {
919             dprintf(out, "\tinvalid config reason: %s\n",
920                     InvalidConfigReasonEnum_Name(configStats->reason->reason).c_str());
921         }
922 
923         for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
924             dprintf(out, "\tbroadcast time: %d\n", broadcastTime);
925         }
926 
927         for (const int& activationTime : configStats->activation_time_sec) {
928             dprintf(out, "\tactivation time: %d\n", activationTime);
929         }
930 
931         for (const int& deactivationTime : configStats->deactivation_time_sec) {
932             dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
933         }
934 
935         auto dropTimePtr = configStats->data_drop_time_sec.begin();
936         auto dropBytesPtr = configStats->data_drop_bytes.begin();
937         for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
938              i++, dropTimePtr++, dropBytesPtr++) {
939             dprintf(out, "\tdata drop time: %d with size %lld", *dropTimePtr,
940                     (long long)*dropBytesPtr);
941         }
942 
943         for (const int64_t flushLatency : configStats->total_flush_latency_ns) {
944             dprintf(out, "\tflush latency time ns: %lld\n", (long long)flushLatency);
945         }
946 
947         for (const int64_t dbSize : configStats->total_db_sizes) {
948             dprintf(out, "\tdb size: %lld\n", (long long)dbSize);
949         }
950     }
951     dprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
952     for (auto& pair : mConfigStats) {
953         auto& configStats = pair.second;
954         dprintf(out,
955                 "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
956                 "#matcher=%d, #alert=%d, valid=%d, device_info_table_creation_failed=%d, "
957                 "db_corrupted_count=%d\n",
958                 configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
959                 configStats->deletion_time_sec, configStats->metric_count,
960                 configStats->condition_count, configStats->matcher_count, configStats->alert_count,
961                 configStats->is_valid, configStats->device_info_table_creation_failed,
962                 configStats->db_corrupted_count);
963 
964         if (!configStats->is_valid) {
965             dprintf(out, "\tinvalid config reason: %s\n",
966                     InvalidConfigReasonEnum_Name(configStats->reason->reason).c_str());
967         }
968 
969         for (const auto& annotation : configStats->annotations) {
970             dprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
971                     annotation.second);
972         }
973 
974         for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
975             dprintf(out, "\tbroadcast time: %s(%lld)\n", buildTimeString(broadcastTime).c_str(),
976                     (long long)broadcastTime);
977         }
978 
979         for (const int& activationTime : configStats->activation_time_sec) {
980             dprintf(out, "\tactivation time: %d\n", activationTime);
981         }
982 
983         for (const int& deactivationTime : configStats->deactivation_time_sec) {
984             dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
985         }
986 
987         auto dropTimePtr = configStats->data_drop_time_sec.begin();
988         auto dropBytesPtr = configStats->data_drop_bytes.begin();
989         for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
990              i++, dropTimePtr++, dropBytesPtr++) {
991             dprintf(out, "\tdata drop time: %s(%lld) with %lld bytes\n",
992                     buildTimeString(*dropTimePtr).c_str(), (long long)*dropTimePtr,
993                     (long long)*dropBytesPtr);
994         }
995 
996         for (const auto& dump : configStats->dump_report_stats) {
997             dprintf(out, "\tdump report time: %s(%lld) bytes: %lld\n",
998                     buildTimeString(dump.first).c_str(), (long long)dump.first,
999                     (long long)dump.second);
1000         }
1001 
1002         for (const auto& stats : pair.second->matcher_stats) {
1003             dprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second);
1004         }
1005 
1006         for (const auto& stats : pair.second->condition_stats) {
1007             dprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
1008                     stats.second);
1009         }
1010 
1011         for (const auto& stats : pair.second->condition_stats) {
1012             dprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
1013                     stats.second);
1014         }
1015 
1016         for (const auto& stats : pair.second->alert_stats) {
1017             dprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second);
1018         }
1019 
1020         for (const auto& stats : configStats->restricted_metric_stats) {
1021             dprintf(out, "Restricted MetricId %lld: ", (long long)stats.first);
1022             dprintf(out, "Insert error %lld, ", (long long)stats.second.insertError);
1023             dprintf(out, "Table creation error %lld, ", (long long)stats.second.tableCreationError);
1024             dprintf(out, "Table deletion error %lld ", (long long)stats.second.tableDeletionError);
1025             dprintf(out, "Category changed count %lld\n ",
1026                     (long long)stats.second.categoryChangedCount);
1027             string flushLatencies = "Flush Latencies: ";
1028             for (const int64_t latencyNs : stats.second.flushLatencyNs) {
1029                 flushLatencies.append(to_string(latencyNs).append(","));
1030             }
1031             flushLatencies.pop_back();
1032             flushLatencies.push_back('\n');
1033             dprintf(out, "%s", flushLatencies.c_str());
1034         }
1035 
1036         for (const int64_t flushLatency : configStats->total_flush_latency_ns) {
1037             dprintf(out, "flush latency time ns: %lld\n", (long long)flushLatency);
1038         }
1039     }
1040     dprintf(out, "********Disk Usage stats***********\n");
1041     StorageManager::printStats(out);
1042     dprintf(out, "********Pushed Atom stats***********\n");
1043     const size_t atomCounts = mPushedAtomStats.size();
1044     for (size_t i = 2; i < atomCounts; i++) {
1045         if (mPushedAtomStats[i].logCount > 0) {
1046             dprintf(out,
1047                     "Atom %zu->(total count)%d, (error count)%d, (drop count)%d, (skip count)%d\n",
1048                     i, mPushedAtomStats[i].logCount, getPushedAtomErrorsLocked((int)i),
1049                     getPushedAtomDropsLocked((int)i), mPushedAtomStats[i].skipCount);
1050         }
1051     }
1052     for (const auto& pair : mNonPlatformPushedAtomStats) {
1053         dprintf(out, "Atom %d->(total count)%d, (error count)%d, (drop count)%d, (skip count)%d\n",
1054                 pair.first, pair.second.logCount, getPushedAtomErrorsLocked(pair.first),
1055                 getPushedAtomDropsLocked((int)pair.first), pair.second.skipCount);
1056     }
1057 
1058     dprintf(out, "********Pulled Atom stats***********\n");
1059     for (const auto& pair : mPulledAtomStats) {
1060         dprintf(out,
1061                 "Atom %d->(total pull)%ld, (pull from cache)%ld, "
1062                 "(pull failed)%ld, (min pull interval)%ld \n"
1063                 "  (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
1064                 "nanos)%lld, "
1065                 "  (max pull delay nanos)%lld, (data error)%ld\n"
1066                 "  (pull timeout)%ld, (pull exceed max delay)%ld"
1067                 "  (no uid provider count)%ld, (no puller found count)%ld\n"
1068                 "  (registered count) %ld, (unregistered count) %ld"
1069                 "  (atom error count) %d\n",
1070                 (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
1071                 (long)pair.second.pullFailed, (long)pair.second.minPullIntervalSec,
1072                 (long long)pair.second.avgPullTimeNs, (long long)pair.second.maxPullTimeNs,
1073                 (long long)pair.second.avgPullDelayNs, (long long)pair.second.maxPullDelayNs,
1074                 pair.second.dataError, pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
1075                 pair.second.pullUidProviderNotFound, pair.second.pullerNotFound,
1076                 pair.second.registeredCount, pair.second.unregisteredCount,
1077                 pair.second.atomErrorCount);
1078         if (pair.second.pullTimeoutMetadata.size() > 0) {
1079             string uptimeMillis = "(pull timeout system uptime millis) ";
1080             string pullTimeoutMillis = "(pull timeout elapsed time millis) ";
1081             for (const auto& stats : pair.second.pullTimeoutMetadata) {
1082                 uptimeMillis.append(to_string(stats.pullTimeoutUptimeMillis)).append(",");
1083                 pullTimeoutMillis.append(to_string(stats.pullTimeoutElapsedMillis)).append(",");
1084             }
1085             uptimeMillis.pop_back();
1086             uptimeMillis.push_back('\n');
1087             pullTimeoutMillis.pop_back();
1088             pullTimeoutMillis.push_back('\n');
1089             dprintf(out, "%s", uptimeMillis.c_str());
1090             dprintf(out, "%s", pullTimeoutMillis.c_str());
1091         }
1092     }
1093 
1094     if (mAnomalyAlarmRegisteredStats > 0) {
1095         dprintf(out, "********AnomalyAlarmStats stats***********\n");
1096         dprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
1097     }
1098 
1099     if (mPeriodicAlarmRegisteredStats > 0) {
1100         dprintf(out, "********SubscriberAlarmStats stats***********\n");
1101         dprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
1102     }
1103 
1104     dprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n",
1105             mUidMapStats.bytes_used, mUidMapStats.changes, mUidMapStats.deleted_apps,
1106             mUidMapStats.dropped_changes);
1107 
1108     for (const auto& restart : mSystemServerRestartSec) {
1109         dprintf(out, "System server restarts at %s(%lld)\n", buildTimeString(restart).c_str(),
1110                 (long long)restart);
1111     }
1112 
1113     for (const auto& loss : mLogLossStats) {
1114         dprintf(out,
1115                 "Log loss: %lld (wall clock sec) - %d (count), %d (last error), %d (last tag), %d "
1116                 "(uid), %d (pid)\n",
1117                 (long long)loss.mWallClockSec, loss.mCount, loss.mLastError, loss.mLastTag,
1118                 loss.mUid, loss.mPid);
1119     }
1120 
1121     dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n",
1122             mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs);
1123 
1124     if (mActivationBroadcastGuardrailStats.size() > 0) {
1125         dprintf(out, "********mActivationBroadcastGuardrail stats***********\n");
1126         for (const auto& pair: mActivationBroadcastGuardrailStats) {
1127             dprintf(out, "Uid %d: Times: ", pair.first);
1128             for (const auto& guardrailHitTime : pair.second) {
1129                 dprintf(out, "%d ", guardrailHitTime);
1130             }
1131         }
1132         dprintf(out, "\n");
1133     }
1134 
1135     if (mRestrictedMetricQueryStats.size() > 0) {
1136         dprintf(out, "********Restricted Metric Query stats***********\n");
1137         for (const auto& stat : mRestrictedMetricQueryStats) {
1138             if (stat.mHasError) {
1139                 dprintf(out,
1140                         "Query with error type: %d - %lld (query time ns), "
1141                         "%d (calling uid), %lld (config id), %s (config package), %s (error)\n",
1142                         stat.mInvalidQueryReason.value(), (long long)stat.mQueryWallTimeNs,
1143                         stat.mCallingUid, (long long)stat.mConfigId, stat.mConfigPackage.c_str(),
1144                         stat.mError.c_str());
1145             } else {
1146                 dprintf(out,
1147                         "Query succeed - %lld (query time ns), %d (calling uid), "
1148                         "%lld (config id), %s (config package), %d (config uid), "
1149                         "%lld (queryLatencyNs)\n",
1150                         (long long)stat.mQueryWallTimeNs, stat.mCallingUid,
1151                         (long long)stat.mConfigId, stat.mConfigPackage.c_str(),
1152                         stat.mConfigUid.value(), (long long)stat.mQueryLatencyNs.value());
1153             }
1154         }
1155     }
1156     dprintf(out, "********Shard Offset Provider stats***********\n");
1157     dprintf(out, "Shard Offset: %u\n", ShardOffsetProvider::getInstance().getShardOffset());
1158 }
1159 
addConfigStatsToProto(const ConfigStats & configStats,ProtoOutputStream * proto)1160 void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) {
1161     uint64_t token =
1162             proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS);
1163     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_UID, configStats.uid);
1164     proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ID, (long long)configStats.id);
1165     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CREATION, configStats.creation_time_sec);
1166     if (configStats.reset_time_sec != 0) {
1167         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESET, configStats.reset_time_sec);
1168     }
1169     if (configStats.deletion_time_sec != 0) {
1170         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DELETION,
1171                      configStats.deletion_time_sec);
1172     }
1173     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_METRIC_COUNT, configStats.metric_count);
1174     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CONDITION_COUNT,
1175                  configStats.condition_count);
1176     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_MATCHER_COUNT, configStats.matcher_count);
1177     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ALERT_COUNT, configStats.alert_count);
1178     proto->write(FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_VALID, configStats.is_valid);
1179 
1180     if (!configStats.is_valid) {
1181         uint64_t tmpToken =
1182                 proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_STATS_INVALID_CONFIG_REASON);
1183         proto->write(FIELD_TYPE_ENUM | FIELD_ID_INVALID_CONFIG_REASON_ENUM,
1184                      configStats.reason->reason);
1185         if (configStats.reason->metricId.has_value()) {
1186             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_METRIC_ID,
1187                          configStats.reason->metricId.value());
1188         }
1189         if (configStats.reason->stateId.has_value()) {
1190             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_STATE_ID,
1191                          configStats.reason->stateId.value());
1192         }
1193         if (configStats.reason->alertId.has_value()) {
1194             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_ALERT_ID,
1195                          configStats.reason->alertId.value());
1196         }
1197         if (configStats.reason->alarmId.has_value()) {
1198             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_ALARM_ID,
1199                          configStats.reason->alarmId.value());
1200         }
1201         if (configStats.reason->subscriptionId.has_value()) {
1202             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_SUBSCRIPTION_ID,
1203                          configStats.reason->subscriptionId.value());
1204         }
1205         for (const auto& matcherId : configStats.reason->matcherIds) {
1206             proto->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
1207                                  FIELD_ID_INVALID_CONFIG_REASON_MATCHER_ID,
1208                          matcherId);
1209         }
1210         for (const auto& conditionId : configStats.reason->conditionIds) {
1211             proto->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
1212                                  FIELD_ID_INVALID_CONFIG_REASON_CONDITION_ID,
1213                          conditionId);
1214         }
1215         proto->end(tmpToken);
1216     }
1217 
1218     for (const auto& broadcast : configStats.broadcast_sent_time_sec) {
1219         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_BROADCAST | FIELD_COUNT_REPEATED,
1220                      broadcast);
1221     }
1222 
1223     for (const auto& activation : configStats.activation_time_sec) {
1224         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ACTIVATION | FIELD_COUNT_REPEATED,
1225                      activation);
1226     }
1227 
1228     for (const auto& deactivation : configStats.deactivation_time_sec) {
1229         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DEACTIVATION | FIELD_COUNT_REPEATED,
1230                      deactivation);
1231     }
1232 
1233     for (const auto& drop_time : configStats.data_drop_time_sec) {
1234         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DATA_DROP_TIME | FIELD_COUNT_REPEATED,
1235                      drop_time);
1236     }
1237 
1238     for (const auto& drop_bytes : configStats.data_drop_bytes) {
1239         proto->write(
1240                 FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES | FIELD_COUNT_REPEATED,
1241                 (long long)drop_bytes);
1242     }
1243 
1244     for (const auto& dump : configStats.dump_report_stats) {
1245         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME |
1246                      FIELD_COUNT_REPEATED,
1247                      dump.first);
1248     }
1249 
1250     for (const auto& dump : configStats.dump_report_stats) {
1251         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES |
1252                      FIELD_COUNT_REPEATED,
1253                      (long long)dump.second);
1254     }
1255 
1256     for (const auto& annotation : configStats.annotations) {
1257         uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1258                                       FIELD_ID_CONFIG_STATS_ANNOTATION);
1259         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT64,
1260                      (long long)annotation.first);
1261         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT32, annotation.second);
1262         proto->end(token);
1263     }
1264 
1265     for (const auto& pair : configStats.matcher_stats) {
1266         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1267                                           FIELD_ID_CONFIG_STATS_MATCHER_STATS);
1268         proto->write(FIELD_TYPE_INT64 | FIELD_ID_MATCHER_STATS_ID, (long long)pair.first);
1269         proto->write(FIELD_TYPE_INT32 | FIELD_ID_MATCHER_STATS_COUNT, pair.second);
1270         proto->end(tmpToken);
1271     }
1272 
1273     for (const auto& pair : configStats.condition_stats) {
1274         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1275                                           FIELD_ID_CONFIG_STATS_CONDITION_STATS);
1276         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_STATS_ID, (long long)pair.first);
1277         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONDITION_STATS_COUNT, pair.second);
1278         proto->end(tmpToken);
1279     }
1280 
1281     for (const auto& pair : configStats.metric_stats) {
1282         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1283                                           FIELD_ID_CONFIG_STATS_METRIC_STATS);
1284         proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
1285         proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
1286         proto->end(tmpToken);
1287     }
1288     for (const auto& pair : configStats.metric_dimension_in_condition_stats) {
1289         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1290                                          FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS);
1291         proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
1292         proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
1293         proto->end(tmpToken);
1294     }
1295 
1296     for (const auto& pair : configStats.alert_stats) {
1297         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1298                                           FIELD_ID_CONFIG_STATS_ALERT_STATS);
1299         proto->write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_STATS_ID, (long long)pair.first);
1300         proto->write(FIELD_TYPE_INT32 | FIELD_ID_ALERT_STATS_COUNT, pair.second);
1301         proto->end(tmpToken);
1302     }
1303 
1304     for (const auto& pair : configStats.restricted_metric_stats) {
1305         uint64_t token =
1306                 proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_STATS_RESTRICTED_METRIC_STATS |
1307                              FIELD_COUNT_REPEATED);
1308 
1309         proto->write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_METRIC_ID, (long long)pair.first);
1310         writeNonZeroStatToStream(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_INSERT_ERROR,
1311                                  (long long)pair.second.insertError, proto);
1312         writeNonZeroStatToStream(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_TABLE_CREATION_ERROR,
1313                                  (long long)pair.second.tableCreationError, proto);
1314         writeNonZeroStatToStream(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_TABLE_DELETION_ERROR,
1315                                  (long long)pair.second.tableDeletionError, proto);
1316         for (const int64_t flushLatencyNs : pair.second.flushLatencyNs) {
1317             proto->write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_FLUSH_LATENCY |
1318                                  FIELD_COUNT_REPEATED,
1319                          flushLatencyNs);
1320         }
1321         writeNonZeroStatToStream(
1322                 FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_CATEGORY_CHANGED_COUNT,
1323                 (long long)pair.second.categoryChangedCount, proto);
1324         proto->end(token);
1325     }
1326     proto->write(FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_DEVICE_INFO_TABLE_CREATION_FAILED,
1327                  configStats.device_info_table_creation_failed);
1328     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESTRICTED_DB_CORRUPTED_COUNT,
1329                  configStats.db_corrupted_count);
1330     for (int64_t latency : configStats.total_flush_latency_ns) {
1331         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_FLUSH_LATENCY |
1332                              FIELD_COUNT_REPEATED,
1333                      latency);
1334     }
1335     for (int64_t dbSizeTimestamp : configStats.total_db_size_timestamps) {
1336         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_TIME_SEC |
1337                              FIELD_COUNT_REPEATED,
1338                      dbSizeTimestamp);
1339     }
1340     for (int64_t dbSize : configStats.total_db_sizes) {
1341         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_BYTES |
1342                              FIELD_COUNT_REPEATED,
1343                      dbSize);
1344     }
1345     proto->end(token);
1346 }
1347 
dumpStats(std::vector<uint8_t> * output,bool reset)1348 void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
1349     lock_guard<std::mutex> lock(mLock);
1350 
1351     ProtoOutputStream proto;
1352     proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec);
1353     proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)getWallClockSec());
1354 
1355     for (const auto& configStats : mIceBox) {
1356         addConfigStatsToProto(*configStats, &proto);
1357     }
1358 
1359     for (auto& pair : mConfigStats) {
1360         addConfigStatsToProto(*(pair.second), &proto);
1361     }
1362 
1363     const size_t atomCounts = mPushedAtomStats.size();
1364     for (size_t i = 2; i < atomCounts; i++) {
1365         if (mPushedAtomStats[i].logCount > 0) {
1366             uint64_t token =
1367                     proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
1368             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i);
1369             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i].logCount);
1370             const int errors = getPushedAtomErrorsLocked(i);
1371             writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors,
1372                                      &proto);
1373             const int drops = getPushedAtomDropsLocked(i);
1374             writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_DROPS_COUNT, drops,
1375                                      &proto);
1376             writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_SKIP_COUNT,
1377                                      mPushedAtomStats[i].skipCount, &proto);
1378             proto.end(token);
1379         }
1380     }
1381 
1382     for (const auto& pair : mNonPlatformPushedAtomStats) {
1383         uint64_t token =
1384                 proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
1385         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, pair.first);
1386         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, pair.second.logCount);
1387         const int errors = getPushedAtomErrorsLocked(pair.first);
1388         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors,
1389                                  &proto);
1390         const int drops = getPushedAtomDropsLocked(pair.first);
1391         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_DROPS_COUNT, drops, &proto);
1392         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_SKIP_COUNT,
1393                                  pair.second.skipCount, &proto);
1394         proto.end(token);
1395     }
1396 
1397     for (const auto& pair : mPulledAtomStats) {
1398         writePullerStatsToStream(pair, &proto);
1399     }
1400 
1401     for (const auto& pair : mAtomMetricStats) {
1402         writeAtomMetricStatsToStream(pair, &proto);
1403     }
1404 
1405     if (mAnomalyAlarmRegisteredStats > 0) {
1406         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
1407         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
1408                     mAnomalyAlarmRegisteredStats);
1409         proto.end(token);
1410     }
1411 
1412     if (mPeriodicAlarmRegisteredStats > 0) {
1413         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PERIODIC_ALARM_STATS);
1414         proto.write(FIELD_TYPE_INT32 | FIELD_ID_PERIODIC_ALARMS_REGISTERED,
1415                     mPeriodicAlarmRegisteredStats);
1416         proto.end(token);
1417     }
1418 
1419     uint64_t uidMapToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS);
1420     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_CHANGES, mUidMapStats.changes);
1421     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_BYTES_USED, mUidMapStats.bytes_used);
1422     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DROPPED_CHANGES, mUidMapStats.dropped_changes);
1423     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DELETED_APPS, mUidMapStats.deleted_apps);
1424     proto.end(uidMapToken);
1425 
1426     for (const auto& error : mLogLossStats) {
1427         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
1428                                       FIELD_COUNT_REPEATED);
1429         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TIME, error.mWallClockSec);
1430         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_COUNT, error.mCount);
1431         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_ERROR, error.mLastError);
1432         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TAG, error.mLastTag);
1433         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_UID, error.mUid);
1434         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_PID, error.mPid);
1435         proto.end(token);
1436     }
1437 
1438     if (mOverflowCount > 0) {
1439         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_OVERFLOW);
1440         proto.write(FIELD_TYPE_INT32 | FIELD_ID_OVERFLOW_COUNT, (int32_t)mOverflowCount);
1441         proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MAX_HISTORY,
1442                     (long long)mMaxQueueHistoryNs);
1443         proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MIN_HISTORY,
1444                     (long long)mMinQueueHistoryNs);
1445         proto.end(token);
1446     }
1447 
1448     for (const auto& restart : mSystemServerRestartSec) {
1449         proto.write(FIELD_TYPE_INT32 | FIELD_ID_SYSTEM_SERVER_RESTART | FIELD_COUNT_REPEATED,
1450                     restart);
1451     }
1452 
1453     for (const auto& pair: mActivationBroadcastGuardrailStats) {
1454         uint64_t token = proto.start(FIELD_TYPE_MESSAGE |
1455                                      FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL |
1456                                      FIELD_COUNT_REPEATED);
1457         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID,
1458                     (int32_t) pair.first);
1459         for (const auto& guardrailHitTime : pair.second) {
1460             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME |
1461                             FIELD_COUNT_REPEATED,
1462                         guardrailHitTime);
1463         }
1464         proto.end(token);
1465     }
1466 
1467     for (const auto& stat : mRestrictedMetricQueryStats) {
1468         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS |
1469                                      FIELD_COUNT_REPEATED);
1470         proto.write(FIELD_TYPE_INT32 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CALLING_UID,
1471                     stat.mCallingUid);
1472         proto.write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_ID,
1473                     stat.mConfigId);
1474         proto.write(FIELD_TYPE_STRING | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_PACKAGE,
1475                     stat.mConfigPackage);
1476         if (stat.mConfigUid.has_value()) {
1477             proto.write(FIELD_TYPE_INT32 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_UID,
1478                         stat.mConfigUid.value());
1479         }
1480         if (stat.mInvalidQueryReason.has_value()) {
1481             proto.write(
1482                     FIELD_TYPE_ENUM | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_INVALID_QUERY_REASON,
1483                     stat.mInvalidQueryReason.value());
1484         }
1485         proto.write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_QUERY_WALL_TIME_NS,
1486                     stat.mQueryWallTimeNs);
1487         proto.write(FIELD_TYPE_BOOL | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_HAS_ERROR,
1488                     stat.mHasError);
1489         if (stat.mHasError && !stat.mError.empty()) {
1490             proto.write(FIELD_TYPE_STRING | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_ERROR,
1491                         stat.mError);
1492         }
1493         if (stat.mQueryLatencyNs.has_value()) {
1494             proto.write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_LATENCY_NS,
1495                         stat.mQueryLatencyNs.value());
1496         }
1497         proto.end(token);
1498     }
1499 
1500     proto.write(FIELD_TYPE_UINT32 | FIELD_ID_SHARD_OFFSET,
1501                 static_cast<long>(ShardOffsetProvider::getInstance().getShardOffset()));
1502 
1503     output->clear();
1504     size_t bufferSize = proto.size();
1505     output->resize(bufferSize);
1506 
1507     size_t pos = 0;
1508     sp<android::util::ProtoReader> reader = proto.data();
1509     while (reader->readBuffer() != NULL) {
1510         size_t toRead = reader->currentToRead();
1511         std::memcpy(&((*output)[pos]), reader->readBuffer(), toRead);
1512         pos += toRead;
1513         reader->move(toRead);
1514     }
1515 
1516     if (reset) {
1517         resetInternalLocked();
1518     }
1519 
1520     VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize);
1521 }
1522 
getAtomDimensionKeySizeLimits(const int atomId)1523 std::pair<size_t, size_t> StatsdStats::getAtomDimensionKeySizeLimits(const int atomId) {
1524     return kAtomDimensionKeySizeLimitMap.find(atomId) != kAtomDimensionKeySizeLimitMap.end()
1525                    ? kAtomDimensionKeySizeLimitMap.at(atomId)
1526                    : std::make_pair<size_t, size_t>(kDimensionKeySizeSoftLimit,
1527                                                     kDimensionKeySizeHardLimit);
1528 }
1529 
createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,const int64_t matcherId)1530 InvalidConfigReason createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,
1531                                                          const int64_t matcherId) {
1532     InvalidConfigReason invalidConfigReason(reason);
1533     invalidConfigReason.matcherIds.push_back(matcherId);
1534     return invalidConfigReason;
1535 }
1536 
createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t matcherId)1537 InvalidConfigReason createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,
1538                                                          const int64_t metricId,
1539                                                          const int64_t matcherId) {
1540     InvalidConfigReason invalidConfigReason(reason, metricId);
1541     invalidConfigReason.matcherIds.push_back(matcherId);
1542     return invalidConfigReason;
1543 }
1544 
createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,const int64_t conditionId)1545 InvalidConfigReason createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,
1546                                                            const int64_t conditionId) {
1547     InvalidConfigReason invalidConfigReason(reason);
1548     invalidConfigReason.conditionIds.push_back(conditionId);
1549     return invalidConfigReason;
1550 }
1551 
createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t conditionId)1552 InvalidConfigReason createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,
1553                                                            const int64_t metricId,
1554                                                            const int64_t conditionId) {
1555     InvalidConfigReason invalidConfigReason(reason, metricId);
1556     invalidConfigReason.conditionIds.push_back(conditionId);
1557     return invalidConfigReason;
1558 }
1559 
createInvalidConfigReasonWithState(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t stateId)1560 InvalidConfigReason createInvalidConfigReasonWithState(const InvalidConfigReasonEnum reason,
1561                                                        const int64_t metricId,
1562                                                        const int64_t stateId) {
1563     InvalidConfigReason invalidConfigReason(reason, metricId);
1564     invalidConfigReason.stateId = stateId;
1565     return invalidConfigReason;
1566 }
1567 
createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,const int64_t alertId)1568 InvalidConfigReason createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,
1569                                                        const int64_t alertId) {
1570     InvalidConfigReason invalidConfigReason(reason);
1571     invalidConfigReason.alertId = alertId;
1572     return invalidConfigReason;
1573 }
1574 
createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t alertId)1575 InvalidConfigReason createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,
1576                                                        const int64_t metricId,
1577                                                        const int64_t alertId) {
1578     InvalidConfigReason invalidConfigReason(reason, metricId);
1579     invalidConfigReason.alertId = alertId;
1580     return invalidConfigReason;
1581 }
1582 
createInvalidConfigReasonWithAlarm(const InvalidConfigReasonEnum reason,const int64_t alarmId)1583 InvalidConfigReason createInvalidConfigReasonWithAlarm(const InvalidConfigReasonEnum reason,
1584                                                        const int64_t alarmId) {
1585     InvalidConfigReason invalidConfigReason(reason);
1586     invalidConfigReason.alarmId = alarmId;
1587     return invalidConfigReason;
1588 }
1589 
createInvalidConfigReasonWithSubscription(const InvalidConfigReasonEnum reason,const int64_t subscriptionId)1590 InvalidConfigReason createInvalidConfigReasonWithSubscription(const InvalidConfigReasonEnum reason,
1591                                                               const int64_t subscriptionId) {
1592     InvalidConfigReason invalidConfigReason(reason);
1593     invalidConfigReason.subscriptionId = subscriptionId;
1594     return invalidConfigReason;
1595 }
1596 
createInvalidConfigReasonWithSubscriptionAndAlarm(const InvalidConfigReasonEnum reason,const int64_t subscriptionId,const int64_t alarmId)1597 InvalidConfigReason createInvalidConfigReasonWithSubscriptionAndAlarm(
1598         const InvalidConfigReasonEnum reason, const int64_t subscriptionId, const int64_t alarmId) {
1599     InvalidConfigReason invalidConfigReason(reason);
1600     invalidConfigReason.subscriptionId = subscriptionId;
1601     invalidConfigReason.alarmId = alarmId;
1602     return invalidConfigReason;
1603 }
1604 
createInvalidConfigReasonWithSubscriptionAndAlert(const InvalidConfigReasonEnum reason,const int64_t subscriptionId,const int64_t alertId)1605 InvalidConfigReason createInvalidConfigReasonWithSubscriptionAndAlert(
1606         const InvalidConfigReasonEnum reason, const int64_t subscriptionId, const int64_t alertId) {
1607     InvalidConfigReason invalidConfigReason(reason);
1608     invalidConfigReason.subscriptionId = subscriptionId;
1609     invalidConfigReason.alertId = alertId;
1610     return invalidConfigReason;
1611 }
1612 
1613 }  // namespace statsd
1614 }  // namespace os
1615 }  // namespace android
1616