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 "shell/ShellSubscriber.h"
25 #include "statslog_statsd.h"
26 #include "storage/StorageManager.h"
27 #include "utils/ShardOffsetProvider.h"
28 
29 namespace android {
30 namespace os {
31 namespace statsd {
32 
33 using android::util::FIELD_COUNT_REPEATED;
34 using android::util::FIELD_TYPE_BOOL;
35 using android::util::FIELD_TYPE_ENUM;
36 using android::util::FIELD_TYPE_FLOAT;
37 using android::util::FIELD_TYPE_INT32;
38 using android::util::FIELD_TYPE_INT64;
39 using android::util::FIELD_TYPE_MESSAGE;
40 using android::util::FIELD_TYPE_STRING;
41 using android::util::FIELD_TYPE_UINT32;
42 using android::util::ProtoOutputStream;
43 using std::lock_guard;
44 using std::shared_ptr;
45 using std::string;
46 using std::to_string;
47 using std::vector;
48 
49 const int FIELD_ID_BEGIN_TIME = 1;
50 const int FIELD_ID_END_TIME = 2;
51 const int FIELD_ID_CONFIG_STATS = 3;
52 const int FIELD_ID_ATOM_STATS = 7;
53 const int FIELD_ID_UIDMAP_STATS = 8;
54 const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
55 const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
56 const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
57 const int FIELD_ID_LOGGER_ERROR_STATS = 16;
58 const int FIELD_ID_OVERFLOW = 18;
59 const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL = 19;
60 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS = 20;
61 const int FIELD_ID_SHARD_OFFSET = 21;
62 const int FIELD_ID_STATSD_STATS_ID = 22;
63 const int FIELD_ID_SUBSCRIPTION_STATS = 23;
64 const int FIELD_ID_SOCKET_LOSS_STATS = 24;
65 const int FIELD_ID_QUEUE_STATS = 25;
66 const int FIELD_ID_SOCKET_READ_STATS = 26;
67 
68 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CALLING_UID = 1;
69 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_ID = 2;
70 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_UID = 3;
71 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_PACKAGE = 4;
72 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_INVALID_QUERY_REASON = 5;
73 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_QUERY_WALL_TIME_NS = 6;
74 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_HAS_ERROR = 7;
75 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_ERROR = 8;
76 const int FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_LATENCY_NS = 9;
77 
78 const int FIELD_ID_ATOM_STATS_TAG = 1;
79 const int FIELD_ID_ATOM_STATS_COUNT = 2;
80 const int FIELD_ID_ATOM_STATS_ERROR_COUNT = 3;
81 const int FIELD_ID_ATOM_STATS_DROPS_COUNT = 4;
82 const int FIELD_ID_ATOM_STATS_SKIP_COUNT = 5;
83 
84 const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
85 const int FIELD_ID_PERIODIC_ALARMS_REGISTERED = 1;
86 
87 const int FIELD_ID_LOG_LOSS_STATS_TIME = 1;
88 const int FIELD_ID_LOG_LOSS_STATS_COUNT = 2;
89 const int FIELD_ID_LOG_LOSS_STATS_ERROR = 3;
90 const int FIELD_ID_LOG_LOSS_STATS_TAG = 4;
91 const int FIELD_ID_LOG_LOSS_STATS_UID = 5;
92 const int FIELD_ID_LOG_LOSS_STATS_PID = 6;
93 
94 const int FIELD_ID_OVERFLOW_COUNT = 1;
95 const int FIELD_ID_OVERFLOW_MAX_HISTORY = 2;
96 const int FIELD_ID_OVERFLOW_MIN_HISTORY = 3;
97 
98 const int FIELD_ID_QUEUE_MAX_SIZE_OBSERVED = 1;
99 const int FIELD_ID_QUEUE_MAX_SIZE_OBSERVED_ELAPSED_NANOS = 2;
100 
101 const int FIELD_ID_CONFIG_STATS_UID = 1;
102 const int FIELD_ID_CONFIG_STATS_ID = 2;
103 const int FIELD_ID_CONFIG_STATS_CREATION = 3;
104 const int FIELD_ID_CONFIG_STATS_RESET = 19;
105 const int FIELD_ID_CONFIG_STATS_DELETION = 4;
106 const int FIELD_ID_CONFIG_STATS_METRIC_COUNT = 5;
107 const int FIELD_ID_CONFIG_STATS_CONDITION_COUNT = 6;
108 const int FIELD_ID_CONFIG_STATS_MATCHER_COUNT = 7;
109 const int FIELD_ID_CONFIG_STATS_ALERT_COUNT = 8;
110 const int FIELD_ID_CONFIG_STATS_VALID = 9;
111 const int FIELD_ID_CONFIG_STATS_INVALID_CONFIG_REASON = 24;
112 const int FIELD_ID_CONFIG_STATS_BROADCAST = 10;
113 const int FIELD_ID_CONFIG_STATS_DATA_DROP_TIME = 11;
114 const int FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES = 21;
115 const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME = 12;
116 const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES = 20;
117 const int FIELD_ID_CONFIG_STATS_MATCHER_STATS = 13;
118 const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14;
119 const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15;
120 const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16;
121 const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17;
122 const int FIELD_ID_CONFIG_STATS_ANNOTATION = 18;
123 const int FIELD_ID_CONFIG_STATS_ACTIVATION = 22;
124 const int FIELD_ID_CONFIG_STATS_DEACTIVATION = 23;
125 const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT64 = 1;
126 const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT32 = 2;
127 const int FIELD_ID_CONFIG_STATS_RESTRICTED_METRIC_STATS = 25;
128 const int FIELD_ID_CONFIG_STATS_DEVICE_INFO_TABLE_CREATION_FAILED = 26;
129 const int FIELD_ID_CONFIG_STATS_RESTRICTED_DB_CORRUPTED_COUNT = 27;
130 const int FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_FLUSH_LATENCY = 28;
131 const int FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_TIME_SEC = 29;
132 const int FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_BYTES = 30;
133 const int FIELD_ID_CONFIG_STATS_DUMP_REPORT_NUMBER = 31;
134 const int FIELD_ID_DB_DELETION_STAT_FAILED = 32;
135 const int FIELD_ID_DB_DELETION_SIZE_EXCEEDED_LIMIT = 33;
136 const int FIELD_ID_DB_DELETION_CONFIG_INVALID = 34;
137 const int FIELD_ID_DB_DELETION_TOO_OLD = 35;
138 const int FIELD_ID_DB_DELETION_CONFIG_REMOVED = 36;
139 const int FIELD_ID_DB_DELETION_CONFIG_UPDATED = 37;
140 const int FIELD_ID_CONFIG_METADATA_PROVIDER_PROMOTION_FAILED = 38;
141 
142 const int FIELD_ID_INVALID_CONFIG_REASON_ENUM = 1;
143 const int FIELD_ID_INVALID_CONFIG_REASON_METRIC_ID = 2;
144 const int FIELD_ID_INVALID_CONFIG_REASON_STATE_ID = 3;
145 const int FIELD_ID_INVALID_CONFIG_REASON_ALERT_ID = 4;
146 const int FIELD_ID_INVALID_CONFIG_REASON_ALARM_ID = 5;
147 const int FIELD_ID_INVALID_CONFIG_REASON_SUBSCRIPTION_ID = 6;
148 const int FIELD_ID_INVALID_CONFIG_REASON_MATCHER_ID = 7;
149 const int FIELD_ID_INVALID_CONFIG_REASON_CONDITION_ID = 8;
150 
151 const int FIELD_ID_MATCHER_STATS_ID = 1;
152 const int FIELD_ID_MATCHER_STATS_COUNT = 2;
153 const int FIELD_ID_CONDITION_STATS_ID = 1;
154 const int FIELD_ID_CONDITION_STATS_COUNT = 2;
155 const int FIELD_ID_METRIC_STATS_ID = 1;
156 const int FIELD_ID_METRIC_STATS_COUNT = 2;
157 const int FIELD_ID_ALERT_STATS_ID = 1;
158 const int FIELD_ID_ALERT_STATS_COUNT = 2;
159 
160 const int FIELD_ID_UID_MAP_CHANGES = 1;
161 const int FIELD_ID_UID_MAP_BYTES_USED = 2;
162 const int FIELD_ID_UID_MAP_DROPPED_CHANGES = 3;
163 const int FIELD_ID_UID_MAP_DELETED_APPS = 4;
164 
165 const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID = 1;
166 const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME = 2;
167 
168 // SocketLossStats
169 const int FIELD_ID_SOCKET_LOSS_STATS_PER_UID = 1;
170 const int FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS = 2;
171 
172 // for LossStatsOverflowCounters proto
173 const int FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_UID = 1;
174 const int FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_COUNT = 2;
175 
176 // for LossStatsPerUid proto
177 const int FIELD_ID_SOCKET_LOSS_STATS_UID = 1;
178 const int FIELD_ID_SOCKET_LOSS_STATS_FIRST_TIMESTAMP_NANOS = 2;
179 const int FIELD_ID_SOCKET_LOSS_STATS_LAST_TIMESTAMP_NANOS = 3;
180 const int FIELD_ID_SOCKET_LOSS_ATOM_ID_LOSS_STATS = 4;
181 
182 // for AtomIdLossStats proto
183 const int FIELD_ID_ATOM_ID_LOSS_STATS_ATOM_ID = 1;
184 const int FIELD_ID_ATOM_ID_LOSS_STATS_ERROR = 2;
185 const int FIELD_ID_ATOM_ID_LOSS_STATS_COUNT = 3;
186 
187 // for RestrictedMetricStats proto
188 const int FIELD_ID_RESTRICTED_STATS_METRIC_ID = 1;
189 const int FIELD_ID_RESTRICTED_STATS_INSERT_ERROR = 2;
190 const int FIELD_ID_RESTRICTED_STATS_TABLE_CREATION_ERROR = 3;
191 const int FIELD_ID_RESTRICTED_STATS_TABLE_DELETION_ERROR = 4;
192 const int FIELD_ID_RESTRICTED_STATS_FLUSH_LATENCY = 5;
193 const int FIELD_ID_RESTRICTED_STATS_CATEGORY_CHANGED_COUNT = 6;
194 
195 const int FIELD_ID_SUBSCRIPTION_STATS_PER_SUBSCRIPTION_STATS = 1;
196 const int FIELD_ID_SUBSCRIPTION_STATS_PULL_THREAD_WAKEUP_COUNT = 2;
197 
198 const int FIELD_ID_PER_SUBSCRIPTION_STATS_ID = 1;
199 const int FIELD_ID_PER_SUBSCRIPTION_STATS_PUSHED_ATOM_COUNT = 2;
200 const int FIELD_ID_PER_SUBSCRIPTION_STATS_PULLED_ATOM_COUNT = 3;
201 const int FIELD_ID_PER_SUBSCRIPTION_STATS_START_TIME = 4;
202 const int FIELD_ID_PER_SUBSCRIPTION_STATS_END_TIME = 5;
203 const int FIELD_ID_PER_SUBSCRIPTION_STATS_FLUSH_COUNT = 6;
204 
205 // Socket read stats
206 const int FIELD_ID_SOCKET_READ_STATS_BATCHED_READ_SIZE = 1;
207 const int FIELD_ID_SOCKET_READ_STATS_LARGE_BATCH_STATS = 2;
208 
209 // Large socket batch stats
210 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_LAST_READ_TIME = 1;
211 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_CURR_READ_TIME = 2;
212 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_MIN_ATOM_TIME = 3;
213 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_MAX_ATOM_TIME = 4;
214 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_TOTAL_ATOMS = 5;
215 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_ATOM_STATS = 6;
216 
217 // Large batch socket read atom stats
218 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_ATOM_STATS_ATOM_ID = 1;
219 const int FIELD_ID_LARGE_BATCH_SOCKET_READ_ATOM_STATS_COUNT = 2;
220 
221 const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySizeLimitMap = {
222         {util::BINDER_CALLS, {6000, 10000}},
223         {util::LOOPER_STATS, {1500, 2500}},
224         {util::CPU_TIME_PER_UID_FREQ, {6000, 10000}},
225 };
226 
StatsdStats()227 StatsdStats::StatsdStats()
228     : mStatsdStatsId(rand()), mSocketBatchReadHistogram(kNumBinsInSocketBatchReadHistogram) {
229     mPushedAtomStats.resize(kMaxPushedAtomId + 1);
230     mStartTimeSec = getWallClockSec();
231 }
232 
getInstance()233 StatsdStats& StatsdStats::getInstance() {
234     static StatsdStats* statsInstance = new StatsdStats();
235     return *statsInstance;
236 }
237 
addToIceBoxLocked(shared_ptr<ConfigStats> & stats)238 void StatsdStats::addToIceBoxLocked(shared_ptr<ConfigStats>& stats) {
239     // The size of mIceBox grows strictly by one at a time. It won't be > kMaxIceBoxSize.
240     if (mIceBox.size() == kMaxIceBoxSize) {
241         mIceBox.pop_front();
242     }
243     mIceBox.push_back(stats);
244 }
245 
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)246 void StatsdStats::noteConfigReceived(
247         const ConfigKey& key, int metricsCount, int conditionsCount, int matchersCount,
248         int alertsCount, const std::list<std::pair<const int64_t, const int32_t>>& annotations,
249         const optional<InvalidConfigReason>& reason) {
250     lock_guard<std::mutex> lock(mLock);
251     int32_t nowTimeSec = getWallClockSec();
252 
253     // If there is an existing config for the same key, icebox the old config.
254     noteConfigRemovedInternalLocked(key);
255 
256     shared_ptr<ConfigStats> configStats = std::make_shared<ConfigStats>();
257     configStats->uid = key.GetUid();
258     configStats->id = key.GetId();
259     configStats->creation_time_sec = nowTimeSec;
260     configStats->metric_count = metricsCount;
261     configStats->condition_count = conditionsCount;
262     configStats->matcher_count = matchersCount;
263     configStats->alert_count = alertsCount;
264     configStats->is_valid = !reason.has_value();
265     configStats->reason = reason;
266     for (auto& v : annotations) {
267         configStats->annotations.emplace_back(v);
268     }
269 
270     if (!reason.has_value()) {
271         mConfigStats[key] = configStats;
272     } else {
273         configStats->deletion_time_sec = nowTimeSec;
274         addToIceBoxLocked(configStats);
275     }
276 }
277 
noteConfigRemovedInternalLocked(const ConfigKey & key)278 void StatsdStats::noteConfigRemovedInternalLocked(const ConfigKey& key) {
279     auto it = mConfigStats.find(key);
280     if (it != mConfigStats.end()) {
281         int32_t nowTimeSec = getWallClockSec();
282         it->second->deletion_time_sec = nowTimeSec;
283         addToIceBoxLocked(it->second);
284         mConfigStats.erase(it);
285     }
286 }
287 
noteConfigRemoved(const ConfigKey & key)288 void StatsdStats::noteConfigRemoved(const ConfigKey& key) {
289     lock_guard<std::mutex> lock(mLock);
290     noteConfigRemovedInternalLocked(key);
291 }
292 
noteConfigResetInternalLocked(const ConfigKey & key)293 void StatsdStats::noteConfigResetInternalLocked(const ConfigKey& key) {
294     auto it = mConfigStats.find(key);
295     if (it != mConfigStats.end()) {
296         it->second->reset_time_sec = getWallClockSec();
297     }
298 }
299 
noteConfigReset(const ConfigKey & key)300 void StatsdStats::noteConfigReset(const ConfigKey& key) {
301     lock_guard<std::mutex> lock(mLock);
302     noteConfigResetInternalLocked(key);
303 }
304 
noteLogLost(int32_t wallClockTimeSec,int32_t count,int32_t lastError,int32_t lastTag,int32_t uid,int32_t pid)305 void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
306                               int32_t lastTag, int32_t uid, int32_t pid) {
307     lock_guard<std::mutex> lock(mLock);
308     if (mLogLossStats.size() == kMaxLoggerErrors) {
309         mLogLossStats.pop_front();
310     }
311     mLogLossStats.emplace_back(wallClockTimeSec, count, lastError, lastTag, uid, pid);
312 }
313 
noteBatchSocketRead(int32_t size,int64_t lastReadTimeNs,int64_t currReadTimeNs,int64_t minAtomReadTimeNs,int64_t maxAtomReadTimeNs,const unordered_map<int32_t,int32_t> & atomCounts)314 void StatsdStats::noteBatchSocketRead(int32_t size, int64_t lastReadTimeNs, int64_t currReadTimeNs,
315                                       int64_t minAtomReadTimeNs, int64_t maxAtomReadTimeNs,
316                                       const unordered_map<int32_t, int32_t>& atomCounts) {
317     // Calculate the bin.
318     int bin = 0;
319     if (size < 0) {
320         ALOGE("Unexpected negative size read from socket. This should never happen");
321         bin = 0;
322     } else if (size < 5) {
323         bin = size;  // bin = [0,4].
324     } else if (size < 10) {
325         bin = 4 + (size / 5);  // bin = 5.
326     } else if (size < 100) {
327         bin = 5 + (size / 10);  // bin = [6,14].
328     } else if (size < 1000) {
329         bin = 14 + (size / 100);  // bin = [15-23].
330     } else if (size < 2000) {
331         bin = 19 + (size / 200);  // bin = [24-28].
332     } else {                      // 2000+
333         bin = 29;
334     }
335     lock_guard<std::mutex> lock(mLock);
336     mSocketBatchReadHistogram[bin] += 1;
337 
338     // More detailed stats for large batches.
339     if (size >= kLargeBatchReadThreshold) {
340         // make a local copy and filter the map to atoms that pass the threshold
341         unordered_map<int32_t, int32_t> localAtomCounts = atomCounts;
342         for (auto it = localAtomCounts.begin(); it != localAtomCounts.end();) {
343             if (it->second < kMaxLargeBatchReadAtomThreshold) {
344                 it = localAtomCounts.erase(it);
345             } else {
346                 ++it;
347             }
348         }
349         // Add to list.
350         if (mLargeBatchSocketReadStats.size() == kMaxLargeBatchReadSize) {
351             mLargeBatchSocketReadStats.pop_front();
352         }
353         mLargeBatchSocketReadStats.emplace_back(size, lastReadTimeNs, currReadTimeNs,
354                                                 minAtomReadTimeNs, maxAtomReadTimeNs,
355                                                 localAtomCounts);
356     }
357 }
noteBroadcastSent(const ConfigKey & key)358 void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
359     noteBroadcastSent(key, getWallClockSec());
360 }
361 
noteBroadcastSent(const ConfigKey & key,int32_t timeSec)362 void StatsdStats::noteBroadcastSent(const ConfigKey& key, int32_t timeSec) {
363     lock_guard<std::mutex> lock(mLock);
364     auto it = mConfigStats.find(key);
365     if (it == mConfigStats.end()) {
366         ALOGE("Config key %s not found!", key.ToString().c_str());
367         return;
368     }
369     if (it->second->broadcast_sent_time_sec.size() == kMaxTimestampCount) {
370         it->second->broadcast_sent_time_sec.pop_front();
371     }
372     it->second->broadcast_sent_time_sec.push_back(timeSec);
373 }
374 
noteActiveStatusChanged(const ConfigKey & key,bool activated)375 void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated) {
376     noteActiveStatusChanged(key, activated, getWallClockSec());
377 }
378 
noteActiveStatusChanged(const ConfigKey & key,bool activated,int32_t timeSec)379 void StatsdStats::noteActiveStatusChanged(const ConfigKey& key, bool activated, int32_t timeSec) {
380     lock_guard<std::mutex> lock(mLock);
381     auto it = mConfigStats.find(key);
382     if (it == mConfigStats.end()) {
383         ALOGE("Config key %s not found!", key.ToString().c_str());
384         return;
385     }
386     auto& vec = activated ? it->second->activation_time_sec
387                           : it->second->deactivation_time_sec;
388     if (vec.size() == kMaxTimestampCount) {
389         vec.pop_front();
390     }
391     vec.push_back(timeSec);
392 }
393 
noteActivationBroadcastGuardrailHit(const int uid)394 void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid) {
395     noteActivationBroadcastGuardrailHit(uid, getWallClockSec());
396 }
397 
noteActivationBroadcastGuardrailHit(const int uid,const int32_t timeSec)398 void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid, const int32_t timeSec) {
399     lock_guard<std::mutex> lock(mLock);
400     auto& guardrailTimes = mActivationBroadcastGuardrailStats[uid];
401     if (guardrailTimes.size() == kMaxTimestampCount) {
402         guardrailTimes.pop_front();
403     }
404     guardrailTimes.push_back(timeSec);
405 }
406 
noteDataDropped(const ConfigKey & key,const size_t totalBytes)407 void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes) {
408     noteDataDropped(key, totalBytes, getWallClockSec());
409 }
410 
noteEventQueueOverflow(int64_t oldestEventTimestampNs,int32_t atomId,bool isSkipped)411 void StatsdStats::noteEventQueueOverflow(int64_t oldestEventTimestampNs, int32_t atomId,
412                                          bool isSkipped) {
413     lock_guard<std::mutex> lock(mLock);
414 
415     mOverflowCount++;
416 
417     const int64_t history = getElapsedRealtimeNs() - oldestEventTimestampNs;
418 
419     if (history > mMaxQueueHistoryNs) {
420         mMaxQueueHistoryNs = history;
421     }
422 
423     if (history < mMinQueueHistoryNs) {
424         mMinQueueHistoryNs = history;
425     }
426 
427     noteAtomLoggedLocked(atomId, isSkipped);
428     noteAtomDroppedLocked(atomId);
429 }
430 
noteEventQueueSize(int32_t size,int64_t eventTimestampNs)431 void StatsdStats::noteEventQueueSize(int32_t size, int64_t eventTimestampNs) {
432     lock_guard<std::mutex> lock(mLock);
433 
434     if (mEventQueueMaxSizeObserved < size) {
435         mEventQueueMaxSizeObserved = size;
436         mEventQueueMaxSizeObservedElapsedNanos = eventTimestampNs;
437     }
438 }
439 
noteAtomDroppedLocked(int32_t atomId)440 void StatsdStats::noteAtomDroppedLocked(int32_t atomId) {
441     constexpr int kMaxPushedAtomDroppedStatsSize = kMaxPushedAtomId + kMaxNonPlatformPushedAtoms;
442     if (mPushedAtomDropsStats.size() < kMaxPushedAtomDroppedStatsSize ||
443         mPushedAtomDropsStats.find(atomId) != mPushedAtomDropsStats.end()) {
444         mPushedAtomDropsStats[atomId]++;
445     }
446 }
447 
noteAtomSocketLoss(const SocketLossInfo & lossInfo)448 void StatsdStats::noteAtomSocketLoss(const SocketLossInfo& lossInfo) {
449     ALOGW("SocketLossEvent detected: %lld (firstLossTsNanos), %lld (lastLossTsNanos)",
450           (long long)lossInfo.firstLossTsNanos, (long long)lossInfo.lastLossTsNanos);
451     lock_guard<std::mutex> lock(mLock);
452 
453     if (mSocketLossStats.size() == kMaxSocketLossStatsSize) {
454         // erase the oldest record
455         mSocketLossStats.pop_front();
456     }
457     mSocketLossStats.emplace_back(lossInfo.uid, lossInfo.firstLossTsNanos,
458                                   lossInfo.lastLossTsNanos);
459     for (size_t i = 0; i < lossInfo.atomIds.size(); i++) {
460         ALOGW("For uid %d atom %d was lost %d times with error %d", lossInfo.uid,
461               lossInfo.atomIds[i], lossInfo.counts[i], lossInfo.errors[i]);
462         mSocketLossStats.back().mLossCountPerErrorAtomId.emplace_back(
463                 lossInfo.atomIds[i], lossInfo.errors[i], lossInfo.counts[i]);
464     }
465 
466     if (lossInfo.overflowCounter > 0) {
467         auto overflowPerUid = mSocketLossStatsOverflowCounters.find(lossInfo.uid);
468         if (overflowPerUid != mSocketLossStatsOverflowCounters.end()) {
469             overflowPerUid->second += lossInfo.overflowCounter;
470         } else if (mSocketLossStatsOverflowCounters.size() < kMaxSocketLossStatsSize) {
471             mSocketLossStatsOverflowCounters[lossInfo.uid] = lossInfo.overflowCounter;
472         }
473     }
474 }
475 
noteDataDropped(const ConfigKey & key,const size_t totalBytes,int32_t timeSec)476 void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec) {
477     lock_guard<std::mutex> lock(mLock);
478     auto it = mConfigStats.find(key);
479     if (it == mConfigStats.end()) {
480         ALOGE("Config key %s not found!", key.ToString().c_str());
481         return;
482     }
483     if (it->second->data_drop_time_sec.size() == kMaxTimestampCount) {
484         it->second->data_drop_time_sec.pop_front();
485         it->second->data_drop_bytes.pop_front();
486     }
487     it->second->data_drop_time_sec.push_back(timeSec);
488     it->second->data_drop_bytes.push_back(totalBytes);
489 }
490 
noteMetricsReportSent(const ConfigKey & key,const size_t numBytes,const int32_t reportNumber)491 void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t numBytes,
492                                         const int32_t reportNumber) {
493     noteMetricsReportSent(key, numBytes, getWallClockSec(), reportNumber);
494 }
495 
noteMetricsReportSent(const ConfigKey & key,const size_t numBytes,int32_t timeSec,const int32_t reportNumber)496 void StatsdStats::noteMetricsReportSent(const ConfigKey& key, const size_t numBytes,
497                                         int32_t timeSec, const int32_t reportNumber) {
498     lock_guard<std::mutex> lock(mLock);
499     auto it = mConfigStats.find(key);
500     if (it == mConfigStats.end()) {
501         ALOGE("Config key %s not found!", key.ToString().c_str());
502         return;
503     }
504 
505     if (it->second->dump_report_stats.size() == kMaxTimestampCount) {
506         it->second->dump_report_stats.pop_front();
507     }
508     it->second->dump_report_stats.emplace_back(timeSec, numBytes, reportNumber);
509 }
510 
noteDeviceInfoTableCreationFailed(const ConfigKey & key)511 void StatsdStats::noteDeviceInfoTableCreationFailed(const ConfigKey& key) {
512     lock_guard<std::mutex> lock(mLock);
513     auto it = mConfigStats.find(key);
514     if (it == mConfigStats.end()) {
515         ALOGE("Config key %s not found!", key.ToString().c_str());
516         return;
517     }
518     it->second->device_info_table_creation_failed = true;
519 }
520 
noteDbCorrupted(const ConfigKey & key)521 void StatsdStats::noteDbCorrupted(const ConfigKey& key) {
522     lock_guard<std::mutex> lock(mLock);
523     auto it = mConfigStats.find(key);
524     if (it == mConfigStats.end()) {
525         ALOGE("Config key %s not found!", key.ToString().c_str());
526         return;
527     }
528     it->second->db_corrupted_count++;
529 }
530 
noteDbSizeExceeded(const ConfigKey & key)531 void StatsdStats::noteDbSizeExceeded(const ConfigKey& key) {
532     lock_guard<std::mutex> lock(mLock);
533     auto it = mConfigStats.find(key);
534     if (it == mConfigStats.end()) {
535         ALOGE("Config key %s not found!", key.ToString().c_str());
536         return;
537     }
538     it->second->db_deletion_size_exceeded_limit++;
539 }
540 
noteDbStatFailed(const ConfigKey & key)541 void StatsdStats::noteDbStatFailed(const ConfigKey& key) {
542     lock_guard<std::mutex> lock(mLock);
543     auto it = mConfigStats.find(key);
544     if (it == mConfigStats.end()) {
545         ALOGE("Config key %s not found!", key.ToString().c_str());
546         return;
547     }
548     it->second->db_deletion_stat_failed++;
549 }
550 
noteDbConfigInvalid(const ConfigKey & key)551 void StatsdStats::noteDbConfigInvalid(const ConfigKey& key) {
552     lock_guard<std::mutex> lock(mLock);
553     auto it = mConfigStats.find(key);
554     if (it == mConfigStats.end()) {
555         ALOGE("Config key %s not found!", key.ToString().c_str());
556         return;
557     }
558     it->second->db_deletion_config_invalid++;
559 }
560 
noteDbTooOld(const ConfigKey & key)561 void StatsdStats::noteDbTooOld(const ConfigKey& key) {
562     lock_guard<std::mutex> lock(mLock);
563     auto it = mConfigStats.find(key);
564     if (it == mConfigStats.end()) {
565         ALOGE("Config key %s not found!", key.ToString().c_str());
566         return;
567     }
568     it->second->db_deletion_too_old++;
569 }
570 
noteDbDeletionConfigRemoved(const ConfigKey & key)571 void StatsdStats::noteDbDeletionConfigRemoved(const ConfigKey& key) {
572     lock_guard<std::mutex> lock(mLock);
573     auto it = mConfigStats.find(key);
574     if (it == mConfigStats.end()) {
575         ALOGE("Config key %s not found!", key.ToString().c_str());
576         return;
577     }
578     it->second->db_deletion_config_removed++;
579 }
580 
noteDbDeletionConfigUpdated(const ConfigKey & key)581 void StatsdStats::noteDbDeletionConfigUpdated(const ConfigKey& key) {
582     lock_guard<std::mutex> lock(mLock);
583     auto it = mConfigStats.find(key);
584     if (it == mConfigStats.end()) {
585         ALOGE("Config key %s not found!", key.ToString().c_str());
586         return;
587     }
588     it->second->db_deletion_config_updated++;
589 }
590 
noteConfigMetadataProviderPromotionFailed(const ConfigKey & key)591 void StatsdStats::noteConfigMetadataProviderPromotionFailed(const ConfigKey& key) {
592     lock_guard<std::mutex> lock(mLock);
593     auto it = mConfigStats.find(key);
594     if (it == mConfigStats.end()) {
595         ALOGE("Config key %s not found!", key.ToString().c_str());
596         return;
597     }
598     it->second->config_metadata_provider_promote_failure++;
599 }
600 
noteUidMapDropped(int deltas)601 void StatsdStats::noteUidMapDropped(int deltas) {
602     lock_guard<std::mutex> lock(mLock);
603     mUidMapStats.dropped_changes += mUidMapStats.dropped_changes + deltas;
604 }
605 
noteUidMapAppDeletionDropped()606 void StatsdStats::noteUidMapAppDeletionDropped() {
607     lock_guard<std::mutex> lock(mLock);
608     mUidMapStats.deleted_apps++;
609 }
610 
setUidMapChanges(int changes)611 void StatsdStats::setUidMapChanges(int changes) {
612     lock_guard<std::mutex> lock(mLock);
613     mUidMapStats.changes = changes;
614 }
615 
setCurrentUidMapMemory(int bytes)616 void StatsdStats::setCurrentUidMapMemory(int bytes) {
617     lock_guard<std::mutex> lock(mLock);
618     mUidMapStats.bytes_used = bytes;
619 }
620 
noteConditionDimensionSize(const ConfigKey & key,const int64_t id,int size)621 void StatsdStats::noteConditionDimensionSize(const ConfigKey& key, const int64_t id, int size) {
622     lock_guard<std::mutex> lock(mLock);
623     // if name doesn't exist before, it will create the key with count 0.
624     auto statsIt = mConfigStats.find(key);
625     if (statsIt == mConfigStats.end()) {
626         return;
627     }
628 
629     auto& conditionSizeMap = statsIt->second->condition_stats;
630     if (size > conditionSizeMap[id]) {
631         conditionSizeMap[id] = size;
632     }
633 }
634 
noteMetricDimensionSize(const ConfigKey & key,const int64_t id,int size)635 void StatsdStats::noteMetricDimensionSize(const ConfigKey& key, const int64_t id, int size) {
636     lock_guard<std::mutex> lock(mLock);
637     // if name doesn't exist before, it will create the key with count 0.
638     auto statsIt = mConfigStats.find(key);
639     if (statsIt == mConfigStats.end()) {
640         return;
641     }
642     auto& metricsDimensionMap = statsIt->second->metric_stats;
643     if (size > metricsDimensionMap[id]) {
644         metricsDimensionMap[id] = size;
645     }
646 }
647 
noteMetricDimensionInConditionSize(const ConfigKey & key,const int64_t id,int size)648 void StatsdStats::noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t id,
649                                                      int size) {
650     lock_guard<std::mutex> lock(mLock);
651     // if name doesn't exist before, it will create the key with count 0.
652     auto statsIt = mConfigStats.find(key);
653     if (statsIt == mConfigStats.end()) {
654         return;
655     }
656     auto& metricsDimensionMap = statsIt->second->metric_dimension_in_condition_stats;
657     if (size > metricsDimensionMap[id]) {
658         metricsDimensionMap[id] = size;
659     }
660 }
661 
noteMatcherMatched(const ConfigKey & key,const int64_t id)662 void StatsdStats::noteMatcherMatched(const ConfigKey& key, const int64_t id) {
663     lock_guard<std::mutex> lock(mLock);
664 
665     auto statsIt = mConfigStats.find(key);
666     if (statsIt == mConfigStats.end()) {
667         return;
668     }
669     statsIt->second->matcher_stats[id]++;
670 }
671 
noteAnomalyDeclared(const ConfigKey & key,const int64_t id)672 void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const int64_t id) {
673     lock_guard<std::mutex> lock(mLock);
674     auto statsIt = mConfigStats.find(key);
675     if (statsIt == mConfigStats.end()) {
676         return;
677     }
678     statsIt->second->alert_stats[id]++;
679 }
680 
noteRegisteredAnomalyAlarmChanged()681 void StatsdStats::noteRegisteredAnomalyAlarmChanged() {
682     lock_guard<std::mutex> lock(mLock);
683     mAnomalyAlarmRegisteredStats++;
684 }
685 
noteRegisteredPeriodicAlarmChanged()686 void StatsdStats::noteRegisteredPeriodicAlarmChanged() {
687     lock_guard<std::mutex> lock(mLock);
688     mPeriodicAlarmRegisteredStats++;
689 }
690 
updateMinPullIntervalSec(int pullAtomId,long intervalSec)691 void StatsdStats::updateMinPullIntervalSec(int pullAtomId, long intervalSec) {
692     lock_guard<std::mutex> lock(mLock);
693     mPulledAtomStats[pullAtomId].minPullIntervalSec =
694             std::min(mPulledAtomStats[pullAtomId].minPullIntervalSec, intervalSec);
695 }
696 
notePull(int pullAtomId)697 void StatsdStats::notePull(int pullAtomId) {
698     lock_guard<std::mutex> lock(mLock);
699     mPulledAtomStats[pullAtomId].totalPull++;
700 }
701 
notePullFromCache(int pullAtomId)702 void StatsdStats::notePullFromCache(int pullAtomId) {
703     lock_guard<std::mutex> lock(mLock);
704     mPulledAtomStats[pullAtomId].totalPullFromCache++;
705 }
706 
notePullTime(int pullAtomId,int64_t pullTimeNs)707 void StatsdStats::notePullTime(int pullAtomId, int64_t pullTimeNs) {
708     lock_guard<std::mutex> lock(mLock);
709     auto& pullStats = mPulledAtomStats[pullAtomId];
710     pullStats.maxPullTimeNs = std::max(pullStats.maxPullTimeNs, pullTimeNs);
711     pullStats.avgPullTimeNs = (pullStats.avgPullTimeNs * pullStats.numPullTime + pullTimeNs) /
712                               (pullStats.numPullTime + 1);
713     pullStats.numPullTime += 1;
714 }
715 
notePullDelay(int pullAtomId,int64_t pullDelayNs)716 void StatsdStats::notePullDelay(int pullAtomId, int64_t pullDelayNs) {
717     lock_guard<std::mutex> lock(mLock);
718     auto& pullStats = mPulledAtomStats[pullAtomId];
719     pullStats.maxPullDelayNs = std::max(pullStats.maxPullDelayNs, pullDelayNs);
720     pullStats.avgPullDelayNs =
721         (pullStats.avgPullDelayNs * pullStats.numPullDelay + pullDelayNs) /
722             (pullStats.numPullDelay + 1);
723     pullStats.numPullDelay += 1;
724 }
725 
notePullDataError(int pullAtomId)726 void StatsdStats::notePullDataError(int pullAtomId) {
727     lock_guard<std::mutex> lock(mLock);
728     mPulledAtomStats[pullAtomId].dataError++;
729 }
730 
notePullTimeout(int pullAtomId,int64_t pullUptimeMillis,int64_t pullElapsedMillis)731 void StatsdStats::notePullTimeout(int pullAtomId,
732                                   int64_t pullUptimeMillis,
733                                   int64_t pullElapsedMillis) {
734     lock_guard<std::mutex> lock(mLock);
735     PulledAtomStats& pulledAtomStats = mPulledAtomStats[pullAtomId];
736     pulledAtomStats.pullTimeout++;
737 
738     if (pulledAtomStats.pullTimeoutMetadata.size() == kMaxTimestampCount) {
739         pulledAtomStats.pullTimeoutMetadata.pop_front();
740     }
741 
742     pulledAtomStats.pullTimeoutMetadata.emplace_back(pullUptimeMillis, pullElapsedMillis);
743 }
744 
notePullExceedMaxDelay(int pullAtomId)745 void StatsdStats::notePullExceedMaxDelay(int pullAtomId) {
746     lock_guard<std::mutex> lock(mLock);
747     mPulledAtomStats[pullAtomId].pullExceedMaxDelay++;
748 }
749 
noteAtomLogged(int atomId,int32_t,bool isSkipped)750 void StatsdStats::noteAtomLogged(int atomId, int32_t /*timeSec*/, bool isSkipped) {
751     lock_guard<std::mutex> lock(mLock);
752 
753     noteAtomLoggedLocked(atomId, isSkipped);
754 }
755 
noteAtomLoggedLocked(int atomId,bool isSkipped)756 void StatsdStats::noteAtomLoggedLocked(int atomId, bool isSkipped) {
757     if (atomId >= 0 && atomId <= kMaxPushedAtomId) {
758         mPushedAtomStats[atomId].logCount++;
759         mPushedAtomStats[atomId].skipCount += isSkipped;
760     } else {
761         if (atomId < 0) {
762             android_errorWriteLog(0x534e4554, "187957589");
763         }
764         if (mNonPlatformPushedAtomStats.size() < kMaxNonPlatformPushedAtoms ||
765             mNonPlatformPushedAtomStats.find(atomId) != mNonPlatformPushedAtomStats.end()) {
766             mNonPlatformPushedAtomStats[atomId].logCount++;
767             mNonPlatformPushedAtomStats[atomId].skipCount += isSkipped;
768         }
769     }
770 }
771 
noteSystemServerRestart(int32_t timeSec)772 void StatsdStats::noteSystemServerRestart(int32_t timeSec) {
773     lock_guard<std::mutex> lock(mLock);
774 
775     if (mSystemServerRestartSec.size() == kMaxSystemServerRestarts) {
776         mSystemServerRestartSec.pop_front();
777     }
778     mSystemServerRestartSec.push_back(timeSec);
779 }
780 
notePullFailed(int atomId)781 void StatsdStats::notePullFailed(int atomId) {
782     lock_guard<std::mutex> lock(mLock);
783     mPulledAtomStats[atomId].pullFailed++;
784 }
785 
notePullUidProviderNotFound(int atomId)786 void StatsdStats::notePullUidProviderNotFound(int atomId) {
787     lock_guard<std::mutex> lock(mLock);
788     mPulledAtomStats[atomId].pullUidProviderNotFound++;
789 }
790 
notePullerNotFound(int atomId)791 void StatsdStats::notePullerNotFound(int atomId) {
792     lock_guard<std::mutex> lock(mLock);
793     mPulledAtomStats[atomId].pullerNotFound++;
794 }
795 
notePullBinderCallFailed(int atomId)796 void StatsdStats::notePullBinderCallFailed(int atomId) {
797     lock_guard<std::mutex> lock(mLock);
798     mPulledAtomStats[atomId].binderCallFailCount++;
799 }
800 
noteEmptyData(int atomId)801 void StatsdStats::noteEmptyData(int atomId) {
802     lock_guard<std::mutex> lock(mLock);
803     mPulledAtomStats[atomId].emptyData++;
804 }
805 
notePullerCallbackRegistrationChanged(int atomId,bool registered)806 void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
807     lock_guard<std::mutex> lock(mLock);
808     if (registered) {
809         mPulledAtomStats[atomId].registeredCount++;
810     } else {
811         mPulledAtomStats[atomId].unregisteredCount++;
812     }
813 }
814 
noteHardDimensionLimitReached(int64_t metricId)815 void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
816     lock_guard<std::mutex> lock(mLock);
817     getAtomMetricStats(metricId).hardDimensionLimitReached++;
818 }
819 
noteLateLogEventSkipped(int64_t metricId)820 void StatsdStats::noteLateLogEventSkipped(int64_t metricId) {
821     lock_guard<std::mutex> lock(mLock);
822     getAtomMetricStats(metricId).lateLogEventSkipped++;
823 }
824 
noteSkippedForwardBuckets(int64_t metricId)825 void StatsdStats::noteSkippedForwardBuckets(int64_t metricId) {
826     lock_guard<std::mutex> lock(mLock);
827     getAtomMetricStats(metricId).skippedForwardBuckets++;
828 }
829 
noteBadValueType(int64_t metricId)830 void StatsdStats::noteBadValueType(int64_t metricId) {
831     lock_guard<std::mutex> lock(mLock);
832     getAtomMetricStats(metricId).badValueType++;
833 }
834 
noteBucketDropped(int64_t metricId)835 void StatsdStats::noteBucketDropped(int64_t metricId) {
836     lock_guard<std::mutex> lock(mLock);
837     getAtomMetricStats(metricId).bucketDropped++;
838 }
839 
noteBucketUnknownCondition(int64_t metricId)840 void StatsdStats::noteBucketUnknownCondition(int64_t metricId) {
841     lock_guard<std::mutex> lock(mLock);
842     getAtomMetricStats(metricId).bucketUnknownCondition++;
843 }
844 
noteConditionChangeInNextBucket(int64_t metricId)845 void StatsdStats::noteConditionChangeInNextBucket(int64_t metricId) {
846     lock_guard<std::mutex> lock(mLock);
847     getAtomMetricStats(metricId).conditionChangeInNextBucket++;
848 }
849 
noteInvalidatedBucket(int64_t metricId)850 void StatsdStats::noteInvalidatedBucket(int64_t metricId) {
851     lock_guard<std::mutex> lock(mLock);
852     getAtomMetricStats(metricId).invalidatedBucket++;
853 }
854 
noteBucketCount(int64_t metricId)855 void StatsdStats::noteBucketCount(int64_t metricId) {
856     lock_guard<std::mutex> lock(mLock);
857     getAtomMetricStats(metricId).bucketCount++;
858 }
859 
noteBucketBoundaryDelayNs(int64_t metricId,int64_t timeDelayNs)860 void StatsdStats::noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs) {
861     lock_guard<std::mutex> lock(mLock);
862     AtomMetricStats& metricStats = getAtomMetricStats(metricId);
863     metricStats.maxBucketBoundaryDelayNs =
864             std::max(metricStats.maxBucketBoundaryDelayNs, timeDelayNs);
865     metricStats.minBucketBoundaryDelayNs =
866             std::min(metricStats.minBucketBoundaryDelayNs, timeDelayNs);
867 }
868 
noteAtomError(int atomTag,bool pull)869 void StatsdStats::noteAtomError(int atomTag, bool pull) {
870     lock_guard<std::mutex> lock(mLock);
871     if (pull) {
872         mPulledAtomStats[atomTag].atomErrorCount++;
873         return;
874     }
875 
876     bool present = (mPushedAtomErrorStats.find(atomTag) != mPushedAtomErrorStats.end());
877     bool full = (mPushedAtomErrorStats.size() >= (size_t)kMaxPushedAtomErrorStatsSize);
878     if (!full || present) {
879         mPushedAtomErrorStats[atomTag]++;
880     }
881 }
882 
hasHitDimensionGuardrail(int64_t metricId) const883 bool StatsdStats::hasHitDimensionGuardrail(int64_t metricId) const {
884     lock_guard<std::mutex> lock(mLock);
885     auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
886     if (atomMetricStatsIter != mAtomMetricStats.end()) {
887         return atomMetricStatsIter->second.hardDimensionLimitReached > 0;
888     }
889     return false;
890 }
891 
noteQueryRestrictedMetricSucceed(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const int64_t latencyNs)892 void StatsdStats::noteQueryRestrictedMetricSucceed(const int64_t configId,
893                                                    const string& configPackage,
894                                                    const std::optional<int32_t> configUid,
895                                                    const int32_t callingUid,
896                                                    const int64_t latencyNs) {
897     lock_guard<std::mutex> lock(mLock);
898 
899     if (mRestrictedMetricQueryStats.size() == kMaxRestrictedMetricQueryCount) {
900         mRestrictedMetricQueryStats.pop_front();
901     }
902     mRestrictedMetricQueryStats.emplace_back(RestrictedMetricQueryStats(
903             callingUid, configId, configPackage, configUid, getWallClockNs(),
904             /*invalidQueryReason=*/std::nullopt, /*error=*/"", latencyNs));
905 }
906 
noteQueryRestrictedMetricFailed(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const InvalidQueryReason reason)907 void StatsdStats::noteQueryRestrictedMetricFailed(const int64_t configId,
908                                                   const string& configPackage,
909                                                   const std::optional<int32_t> configUid,
910                                                   const int32_t callingUid,
911                                                   const InvalidQueryReason reason) {
912     lock_guard<std::mutex> lock(mLock);
913     noteQueryRestrictedMetricFailedLocked(configId, configPackage, configUid, callingUid, reason,
914                                           /*error=*/"");
915 }
916 
noteQueryRestrictedMetricFailed(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const InvalidQueryReason reason,const string & error)917 void StatsdStats::noteQueryRestrictedMetricFailed(
918         const int64_t configId, const string& configPackage, const std::optional<int32_t> configUid,
919         const int32_t callingUid, const InvalidQueryReason reason, const string& error) {
920     lock_guard<std::mutex> lock(mLock);
921     noteQueryRestrictedMetricFailedLocked(configId, configPackage, configUid, callingUid, reason,
922                                           error);
923 }
924 
noteQueryRestrictedMetricFailedLocked(const int64_t configId,const string & configPackage,const std::optional<int32_t> configUid,const int32_t callingUid,const InvalidQueryReason reason,const string & error)925 void StatsdStats::noteQueryRestrictedMetricFailedLocked(
926         const int64_t configId, const string& configPackage, const std::optional<int32_t> configUid,
927         const int32_t callingUid, const InvalidQueryReason reason, const string& error) {
928     if (mRestrictedMetricQueryStats.size() == kMaxRestrictedMetricQueryCount) {
929         mRestrictedMetricQueryStats.pop_front();
930     }
931     mRestrictedMetricQueryStats.emplace_back(RestrictedMetricQueryStats(
932             callingUid, configId, configPackage, configUid, getWallClockNs(), reason, error,
933             /*queryLatencyNs=*/std::nullopt));
934 }
935 
noteRestrictedMetricInsertError(const ConfigKey & configKey,const int64_t metricId)936 void StatsdStats::noteRestrictedMetricInsertError(const ConfigKey& configKey,
937                                                   const int64_t metricId) {
938     lock_guard<std::mutex> lock(mLock);
939     auto it = mConfigStats.find(configKey);
940     if (it != mConfigStats.end()) {
941         it->second->restricted_metric_stats[metricId].insertError++;
942     }
943 }
944 
noteRestrictedMetricTableCreationError(const ConfigKey & configKey,const int64_t metricId)945 void StatsdStats::noteRestrictedMetricTableCreationError(const ConfigKey& configKey,
946                                                          const int64_t metricId) {
947     lock_guard<std::mutex> lock(mLock);
948     auto it = mConfigStats.find(configKey);
949     if (it != mConfigStats.end()) {
950         it->second->restricted_metric_stats[metricId].tableCreationError++;
951     }
952 }
953 
noteRestrictedMetricTableDeletionError(const ConfigKey & configKey,const int64_t metricId)954 void StatsdStats::noteRestrictedMetricTableDeletionError(const ConfigKey& configKey,
955                                                          const int64_t metricId) {
956     lock_guard<std::mutex> lock(mLock);
957     auto it = mConfigStats.find(configKey);
958     if (it != mConfigStats.end()) {
959         it->second->restricted_metric_stats[metricId].tableDeletionError++;
960     }
961 }
962 
noteRestrictedMetricFlushLatency(const ConfigKey & configKey,const int64_t metricId,const int64_t flushLatencyNs)963 void StatsdStats::noteRestrictedMetricFlushLatency(const ConfigKey& configKey,
964                                                    const int64_t metricId,
965                                                    const int64_t flushLatencyNs) {
966     lock_guard<std::mutex> lock(mLock);
967     auto it = mConfigStats.find(configKey);
968     if (it == mConfigStats.end()) {
969         ALOGE("Config key %s not found!", configKey.ToString().c_str());
970         return;
971     }
972     auto& restrictedMetricStats = it->second->restricted_metric_stats[metricId];
973     if (restrictedMetricStats.flushLatencyNs.size() == kMaxRestrictedMetricFlushLatencyCount) {
974         restrictedMetricStats.flushLatencyNs.pop_front();
975     }
976     restrictedMetricStats.flushLatencyNs.push_back(flushLatencyNs);
977 }
978 
noteRestrictedConfigFlushLatency(const ConfigKey & configKey,const int64_t totalFlushLatencyNs)979 void StatsdStats::noteRestrictedConfigFlushLatency(const ConfigKey& configKey,
980                                                    const int64_t totalFlushLatencyNs) {
981     lock_guard<std::mutex> lock(mLock);
982     auto it = mConfigStats.find(configKey);
983     if (it == mConfigStats.end()) {
984         ALOGE("Config key %s not found!", configKey.ToString().c_str());
985         return;
986     }
987     std::list<int64_t>& totalFlushLatencies = it->second->total_flush_latency_ns;
988     if (totalFlushLatencies.size() == kMaxRestrictedConfigFlushLatencyCount) {
989         totalFlushLatencies.pop_front();
990     }
991     totalFlushLatencies.push_back(totalFlushLatencyNs);
992 }
993 
noteRestrictedConfigDbSize(const ConfigKey & configKey,const int64_t elapsedTimeNs,const int64_t dbSize)994 void StatsdStats::noteRestrictedConfigDbSize(const ConfigKey& configKey,
995                                              const int64_t elapsedTimeNs, const int64_t dbSize) {
996     lock_guard<std::mutex> lock(mLock);
997     auto it = mConfigStats.find(configKey);
998     if (it == mConfigStats.end()) {
999         ALOGE("Config key %s not found!", configKey.ToString().c_str());
1000         return;
1001     }
1002     std::list<int64_t>& totalDbSizeTimestamps = it->second->total_db_size_timestamps;
1003     std::list<int64_t>& totaDbSizes = it->second->total_db_sizes;
1004     if (totalDbSizeTimestamps.size() == kMaxRestrictedConfigDbSizeCount) {
1005         totalDbSizeTimestamps.pop_front();
1006         totaDbSizes.pop_front();
1007     }
1008     totalDbSizeTimestamps.push_back(elapsedTimeNs);
1009     totaDbSizes.push_back(dbSize);
1010 }
1011 
noteRestrictedMetricCategoryChanged(const ConfigKey & configKey,const int64_t metricId)1012 void StatsdStats::noteRestrictedMetricCategoryChanged(const ConfigKey& configKey,
1013                                                       const int64_t metricId) {
1014     lock_guard<std::mutex> lock(mLock);
1015     auto it = mConfigStats.find(configKey);
1016     if (it == mConfigStats.end()) {
1017         ALOGE("Config key %s not found!", configKey.ToString().c_str());
1018         return;
1019     }
1020     it->second->restricted_metric_stats[metricId].categoryChangedCount++;
1021 }
1022 
noteSubscriptionStarted(int subId,int32_t pushedAtomCount,int32_t pulledAtomCount)1023 void StatsdStats::noteSubscriptionStarted(int subId, int32_t pushedAtomCount,
1024                                           int32_t pulledAtomCount) {
1025     lock_guard<std::mutex> lock(mLock);
1026 
1027     // If we're already keeping track of max # subscriptions, remove the earliest added
1028     // SubscriptionStats for which the corresponding subscription has ended.
1029     if (mSubscriptionStats.size() >= ShellSubscriber::getMaxSubscriptions()) {
1030         for (auto it = mSubscriptionStats.begin();;) {
1031             if (it == mSubscriptionStats.end()) {
1032                 // Didn't find any ended subscriptions; don't track new subscription.
1033                 // We should not really enter this block since ShellSubscriber will refuse more than
1034                 // ShellSubscriber::kMaxSubscriptions active subscriptions to be added. So for
1035                 // (kMaxSubscriptions + 1)th subscription being added, ShellSubscriber should reject
1036                 // it and noteSubscriptionStarted should not be called for it.
1037                 return;
1038             } else if (it->second.end_time_sec > 0) {
1039                 // Remove the first ended subscription.
1040                 mSubscriptionStats.erase(it);
1041                 break;
1042             } else {
1043                 it++;
1044             }
1045         }
1046     }
1047 
1048     const int32_t nowTimeSec = getWallClockSec();
1049 
1050     SubscriptionStats& subscriptionStats = mSubscriptionStats[subId];
1051     subscriptionStats.pushed_atom_count = pushedAtomCount;
1052     subscriptionStats.pulled_atom_count = pulledAtomCount;
1053     subscriptionStats.start_time_sec = nowTimeSec;
1054 }
1055 
noteSubscriptionEnded(int subId)1056 void StatsdStats::noteSubscriptionEnded(int subId) {
1057     lock_guard<std::mutex> lock(mLock);
1058     auto it = mSubscriptionStats.find(subId);
1059     if (it == mSubscriptionStats.end()) {
1060         // We should not enter here since noteSubscriptionStarted should be called first and that
1061         // should successfully add an entry in mSubscriptionStats. See the comment in
1062         // noteSubscriptionStarted.
1063         return;
1064     }
1065     const int32_t nowTimeSec = getWallClockSec();
1066     it->second.end_time_sec = nowTimeSec;
1067 }
1068 
noteSubscriptionFlushed(int subId)1069 void StatsdStats::noteSubscriptionFlushed(int subId) {
1070     lock_guard<std::mutex> lock(mLock);
1071     auto it = mSubscriptionStats.find(subId);
1072     if (it == mSubscriptionStats.end()) {
1073         // We should not enter here since noteSubscriptionStarted should be called first and that
1074         // should successfully add an entry in mSubscriptionStats. See the comment in
1075         // noteSubscriptionStarted.
1076         return;
1077     }
1078     it->second.flush_count++;
1079 }
1080 
noteSubscriptionAtomPulled(int atomId)1081 void StatsdStats::noteSubscriptionAtomPulled(int atomId) {
1082     lock_guard<std::mutex> lock(mLock);
1083     mPulledAtomStats[atomId].subscriptionPullCount++;
1084 }
1085 
noteSubscriptionPullThreadWakeup()1086 void StatsdStats::noteSubscriptionPullThreadWakeup() {
1087     lock_guard<std::mutex> lock(mLock);
1088     mSubscriptionPullThreadWakeupCount++;
1089 }
1090 
getAtomMetricStats(int64_t metricId)1091 StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int64_t metricId) {
1092     auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
1093     if (atomMetricStatsIter != mAtomMetricStats.end()) {
1094         return atomMetricStatsIter->second;
1095     }
1096     auto emplaceResult = mAtomMetricStats.emplace(metricId, AtomMetricStats());
1097     return emplaceResult.first->second;
1098 }
1099 
reset()1100 void StatsdStats::reset() {
1101     lock_guard<std::mutex> lock(mLock);
1102     resetInternalLocked();
1103 }
1104 
resetInternalLocked()1105 void StatsdStats::resetInternalLocked() {
1106     // Reset the historical data, but keep the active ConfigStats
1107     mStartTimeSec = getWallClockSec();
1108     mIceBox.clear();
1109     std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), PushedAtomStats());
1110     mNonPlatformPushedAtomStats.clear();
1111     mAnomalyAlarmRegisteredStats = 0;
1112     mPeriodicAlarmRegisteredStats = 0;
1113     mSystemServerRestartSec.clear();
1114     mLogLossStats.clear();
1115     mOverflowCount = 0;
1116     mMinQueueHistoryNs = kInt64Max;
1117     mMaxQueueHistoryNs = 0;
1118     mEventQueueMaxSizeObserved = 0;
1119     mEventQueueMaxSizeObservedElapsedNanos = 0;
1120     for (auto& config : mConfigStats) {
1121         config.second->broadcast_sent_time_sec.clear();
1122         config.second->activation_time_sec.clear();
1123         config.second->deactivation_time_sec.clear();
1124         config.second->data_drop_time_sec.clear();
1125         config.second->data_drop_bytes.clear();
1126         config.second->dump_report_stats.clear();
1127         config.second->annotations.clear();
1128         config.second->matcher_stats.clear();
1129         config.second->condition_stats.clear();
1130         config.second->metric_stats.clear();
1131         config.second->metric_dimension_in_condition_stats.clear();
1132         config.second->alert_stats.clear();
1133         config.second->restricted_metric_stats.clear();
1134         config.second->db_corrupted_count = 0;
1135         config.second->total_flush_latency_ns.clear();
1136         config.second->total_db_size_timestamps.clear();
1137         config.second->total_db_sizes.clear();
1138         config.second->db_deletion_size_exceeded_limit = 0;
1139         config.second->db_deletion_stat_failed = 0;
1140         config.second->db_deletion_config_invalid = 0;
1141         config.second->db_deletion_too_old = 0;
1142         config.second->db_deletion_config_removed = 0;
1143         config.second->db_deletion_config_updated = 0;
1144         config.second->config_metadata_provider_promote_failure = 0;
1145     }
1146     for (auto& pullStats : mPulledAtomStats) {
1147         pullStats.second.totalPull = 0;
1148         pullStats.second.totalPullFromCache = 0;
1149         pullStats.second.minPullIntervalSec = LONG_MAX;
1150         pullStats.second.avgPullTimeNs = 0;
1151         pullStats.second.maxPullTimeNs = 0;
1152         pullStats.second.numPullTime = 0;
1153         pullStats.second.avgPullDelayNs = 0;
1154         pullStats.second.maxPullDelayNs = 0;
1155         pullStats.second.numPullDelay = 0;
1156         pullStats.second.dataError = 0;
1157         pullStats.second.pullTimeout = 0;
1158         pullStats.second.pullExceedMaxDelay = 0;
1159         pullStats.second.pullFailed = 0;
1160         pullStats.second.pullUidProviderNotFound = 0;
1161         pullStats.second.pullerNotFound = 0;
1162         pullStats.second.registeredCount = 0;
1163         pullStats.second.unregisteredCount = 0;
1164         pullStats.second.atomErrorCount = 0;
1165         pullStats.second.binderCallFailCount = 0;
1166         pullStats.second.pullTimeoutMetadata.clear();
1167         pullStats.second.subscriptionPullCount = 0;
1168     }
1169     mAtomMetricStats.clear();
1170     mActivationBroadcastGuardrailStats.clear();
1171     mPushedAtomErrorStats.clear();
1172     mSocketLossStats.clear();
1173     mSocketLossStatsOverflowCounters.clear();
1174     mPushedAtomDropsStats.clear();
1175     mRestrictedMetricQueryStats.clear();
1176     mSubscriptionPullThreadWakeupCount = 0;
1177     std::fill(mSocketBatchReadHistogram.begin(), mSocketBatchReadHistogram.end(), 0);
1178     mLargeBatchSocketReadStats.clear();
1179 
1180     for (auto it = mSubscriptionStats.begin(); it != mSubscriptionStats.end();) {
1181         if (it->second.end_time_sec > 0) {
1182             // Remove finished subscriptions
1183             it = mSubscriptionStats.erase(it);
1184         } else {
1185             // Reset dynamic properties of active subscriptions.
1186             it->second.flush_count = 0;
1187             ++it;
1188         }
1189     }
1190 }
1191 
buildTimeString(int64_t timeSec)1192 string buildTimeString(int64_t timeSec) {
1193     time_t t = timeSec;
1194     struct tm* tm = localtime(&t);
1195     char timeBuffer[80];
1196     strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm);
1197     return string(timeBuffer);
1198 }
1199 
getPushedAtomErrorsLocked(int atomId) const1200 int StatsdStats::getPushedAtomErrorsLocked(int atomId) const {
1201     const auto& it = mPushedAtomErrorStats.find(atomId);
1202     if (it != mPushedAtomErrorStats.end()) {
1203         return it->second;
1204     } else {
1205         return 0;
1206     }
1207 }
1208 
getPushedAtomDropsLocked(int atomId) const1209 int StatsdStats::getPushedAtomDropsLocked(int atomId) const {
1210     const auto& it = mPushedAtomDropsStats.find(atomId);
1211     if (it != mPushedAtomDropsStats.end()) {
1212         return it->second;
1213     } else {
1214         return 0;
1215     }
1216 }
1217 
hasRestrictedConfigErrors(const std::shared_ptr<ConfigStats> & configStats) const1218 bool StatsdStats::hasRestrictedConfigErrors(const std::shared_ptr<ConfigStats>& configStats) const {
1219     return configStats->device_info_table_creation_failed || configStats->db_corrupted_count ||
1220            configStats->db_deletion_size_exceeded_limit || configStats->db_deletion_stat_failed ||
1221            configStats->db_deletion_config_invalid || configStats->db_deletion_too_old ||
1222            configStats->db_deletion_config_removed || configStats->db_deletion_config_updated;
1223 }
1224 
hasEventQueueOverflow() const1225 bool StatsdStats::hasEventQueueOverflow() const {
1226     lock_guard<std::mutex> lock(mLock);
1227     return mOverflowCount != 0;
1228 }
1229 
getQueueOverflowAtomsStats() const1230 StatsdStats::QueueOverflowAtomsStatsMap StatsdStats::getQueueOverflowAtomsStats() const {
1231     lock_guard<std::mutex> lock(mLock);
1232     return mPushedAtomDropsStats;
1233 }
1234 
hasSocketLoss() const1235 bool StatsdStats::hasSocketLoss() const {
1236     lock_guard<std::mutex> lock(mLock);
1237     return !mLogLossStats.empty();
1238 }
1239 
dumpStats(int out) const1240 void StatsdStats::dumpStats(int out) const {
1241     lock_guard<std::mutex> lock(mLock);
1242     time_t t = mStartTimeSec;
1243     struct tm* tm = localtime(&t);
1244     char timeBuffer[80];
1245     strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm);
1246     dprintf(out, "Stats collection start second: %s\n", timeBuffer);
1247     dprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
1248     for (const auto& configStats : mIceBox) {
1249         dprintf(out,
1250                 "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, "
1251                 "#matcher=%d, #alert=%d, valid=%d",
1252                 configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
1253                 configStats->deletion_time_sec, configStats->reset_time_sec,
1254                 configStats->metric_count, configStats->condition_count, configStats->matcher_count,
1255                 configStats->alert_count, configStats->is_valid);
1256         if (hasRestrictedConfigErrors(configStats)) {
1257             dprintf(out,
1258                     ", device_info_table_creation_failed=%d, db_corrupted_count=%d, "
1259                     "db_size_exceeded=%d, db_stat_failed=%d, "
1260                     "db_config_invalid=%d, db_too_old=%d, db_deletion_config_removed=%d, "
1261                     "db_deletion_config_updated=%d",
1262                     configStats->device_info_table_creation_failed, configStats->db_corrupted_count,
1263                     configStats->db_deletion_size_exceeded_limit,
1264                     configStats->db_deletion_stat_failed, configStats->db_deletion_config_invalid,
1265                     configStats->db_deletion_too_old, configStats->db_deletion_config_removed,
1266                     configStats->db_deletion_config_updated);
1267         }
1268         if (configStats->config_metadata_provider_promote_failure > 0) {
1269             dprintf(out, "ConfigMetadataProviderPromotionFailure=%d",
1270                     configStats->config_metadata_provider_promote_failure);
1271         }
1272         dprintf(out, "\n");
1273         if (!configStats->is_valid) {
1274             dprintf(out, "\tinvalid config reason: %s\n",
1275                     InvalidConfigReasonEnum_Name(configStats->reason->reason).c_str());
1276         }
1277 
1278         for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
1279             dprintf(out, "\tbroadcast time: %d\n", broadcastTime);
1280         }
1281 
1282         for (const int& activationTime : configStats->activation_time_sec) {
1283             dprintf(out, "\tactivation time: %d\n", activationTime);
1284         }
1285 
1286         for (const int& deactivationTime : configStats->deactivation_time_sec) {
1287             dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
1288         }
1289 
1290         auto dropTimePtr = configStats->data_drop_time_sec.begin();
1291         auto dropBytesPtr = configStats->data_drop_bytes.begin();
1292         for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
1293              i++, dropTimePtr++, dropBytesPtr++) {
1294             dprintf(out, "\tdata drop time: %s(%lld) with %lld bytes\n",
1295                     buildTimeString(*dropTimePtr).c_str(), (long long)*dropTimePtr,
1296                     (long long)*dropBytesPtr);
1297         }
1298 
1299         for (const auto& stats : configStats->restricted_metric_stats) {
1300             dprintf(out, "Restricted MetricId %lld: ", (long long)stats.first);
1301             dprintf(out, "Insert error %lld, ", (long long)stats.second.insertError);
1302             dprintf(out, "Table creation error %lld, ", (long long)stats.second.tableCreationError);
1303             dprintf(out, "Table deletion error %lld ", (long long)stats.second.tableDeletionError);
1304             dprintf(out, "Category changed count %lld\n ",
1305                     (long long)stats.second.categoryChangedCount);
1306             string flushLatencies = "Flush Latencies: ";
1307             for (const int64_t latencyNs : stats.second.flushLatencyNs) {
1308                 flushLatencies.append(to_string(latencyNs).append(","));
1309             }
1310             flushLatencies.pop_back();
1311             flushLatencies.push_back('\n');
1312             dprintf(out, "%s", flushLatencies.c_str());
1313         }
1314 
1315         for (const int64_t flushLatency : configStats->total_flush_latency_ns) {
1316             dprintf(out, "\tflush latency time ns: %lld\n", (long long)flushLatency);
1317         }
1318 
1319         for (const int64_t dbSize : configStats->total_db_sizes) {
1320             dprintf(out, "\tdb size: %lld\n", (long long)dbSize);
1321         }
1322     }
1323     dprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size());
1324     for (auto& pair : mConfigStats) {
1325         auto& configStats = pair.second;
1326         dprintf(out,
1327                 "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
1328                 "#matcher=%d, #alert=%d, valid=%d",
1329                 configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
1330                 configStats->deletion_time_sec, configStats->metric_count,
1331                 configStats->condition_count, configStats->matcher_count, configStats->alert_count,
1332                 configStats->is_valid);
1333         if (hasRestrictedConfigErrors(configStats)) {
1334             dprintf(out,
1335                     ", device_info_table_creation_failed=%d, db_corrupted_count=%d, "
1336                     "db_size_exceeded=%d, db_stat_failed=%d, "
1337                     "db_config_invalid=%d, db_too_old=%d, db_deletion_config_removed=%d, "
1338                     "db_deletion_config_updated=%d",
1339                     configStats->device_info_table_creation_failed, configStats->db_corrupted_count,
1340                     configStats->db_deletion_size_exceeded_limit,
1341                     configStats->db_deletion_stat_failed, configStats->db_deletion_config_invalid,
1342                     configStats->db_deletion_too_old, configStats->db_deletion_config_removed,
1343                     configStats->db_deletion_config_updated);
1344         }
1345         dprintf(out, "\n");
1346         if (!configStats->is_valid) {
1347             dprintf(out, "\tinvalid config reason: %s\n",
1348                     InvalidConfigReasonEnum_Name(configStats->reason->reason).c_str());
1349         }
1350 
1351         for (const auto& annotation : configStats->annotations) {
1352             dprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
1353                     annotation.second);
1354         }
1355 
1356         for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
1357             dprintf(out, "\tbroadcast time: %s(%lld)\n", buildTimeString(broadcastTime).c_str(),
1358                     (long long)broadcastTime);
1359         }
1360 
1361         for (const int& activationTime : configStats->activation_time_sec) {
1362             dprintf(out, "\tactivation time: %d\n", activationTime);
1363         }
1364 
1365         for (const int& deactivationTime : configStats->deactivation_time_sec) {
1366             dprintf(out, "\tdeactivation time: %d\n", deactivationTime);
1367         }
1368 
1369         auto dropTimePtr = configStats->data_drop_time_sec.begin();
1370         auto dropBytesPtr = configStats->data_drop_bytes.begin();
1371         for (int i = 0; i < (int)configStats->data_drop_time_sec.size();
1372              i++, dropTimePtr++, dropBytesPtr++) {
1373             dprintf(out, "\tdata drop time: %s(%lld) with %lld bytes\n",
1374                     buildTimeString(*dropTimePtr).c_str(), (long long)*dropTimePtr,
1375                     (long long)*dropBytesPtr);
1376         }
1377 
1378         for (const auto& dump : configStats->dump_report_stats) {
1379             dprintf(out, "\tdump report time: %s(%lld) bytes: %d reportNumber: %d\n",
1380                     buildTimeString(dump.mDumpReportTimeSec).c_str(),
1381                     (long long)dump.mDumpReportTimeSec, dump.mDumpReportSizeBytes,
1382                     dump.mDumpReportNumber);
1383         }
1384 
1385         for (const auto& stats : pair.second->matcher_stats) {
1386             dprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second);
1387         }
1388 
1389         for (const auto& stats : pair.second->condition_stats) {
1390             dprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first,
1391                     stats.second);
1392         }
1393 
1394         for (const auto& stats : pair.second->condition_stats) {
1395             dprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first,
1396                     stats.second);
1397         }
1398 
1399         for (const auto& stats : pair.second->alert_stats) {
1400             dprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second);
1401         }
1402 
1403         for (const auto& stats : configStats->restricted_metric_stats) {
1404             dprintf(out, "Restricted MetricId %lld: ", (long long)stats.first);
1405             dprintf(out, "Insert error %lld, ", (long long)stats.second.insertError);
1406             dprintf(out, "Table creation error %lld, ", (long long)stats.second.tableCreationError);
1407             dprintf(out, "Table deletion error %lld ", (long long)stats.second.tableDeletionError);
1408             dprintf(out, "Category changed count %lld\n ",
1409                     (long long)stats.second.categoryChangedCount);
1410             string flushLatencies = "Flush Latencies: ";
1411             for (const int64_t latencyNs : stats.second.flushLatencyNs) {
1412                 flushLatencies.append(to_string(latencyNs).append(","));
1413             }
1414             flushLatencies.pop_back();
1415             flushLatencies.push_back('\n');
1416             dprintf(out, "%s", flushLatencies.c_str());
1417         }
1418 
1419         for (const int64_t flushLatency : configStats->total_flush_latency_ns) {
1420             dprintf(out, "flush latency time ns: %lld\n", (long long)flushLatency);
1421         }
1422 
1423         for (const int64_t dbSize : configStats->total_db_sizes) {
1424             dprintf(out, "\tdb size: %lld\n", (long long)dbSize);
1425         }
1426     }
1427     dprintf(out, "********Disk Usage stats***********\n");
1428     StorageManager::printStats(out);
1429     dprintf(out, "********Pushed Atom stats***********\n");
1430     const size_t atomCounts = mPushedAtomStats.size();
1431     for (size_t i = 2; i < atomCounts; i++) {
1432         if (mPushedAtomStats[i].logCount > 0) {
1433             dprintf(out,
1434                     "Atom %zu->(total count)%d, (error count)%d, (drop count)%d, (skip count)%d\n",
1435                     i, mPushedAtomStats[i].logCount, getPushedAtomErrorsLocked((int)i),
1436                     getPushedAtomDropsLocked((int)i), mPushedAtomStats[i].skipCount);
1437         }
1438     }
1439     for (const auto& pair : mNonPlatformPushedAtomStats) {
1440         dprintf(out, "Atom %d->(total count)%d, (error count)%d, (drop count)%d, (skip count)%d\n",
1441                 pair.first, pair.second.logCount, getPushedAtomErrorsLocked(pair.first),
1442                 getPushedAtomDropsLocked((int)pair.first), pair.second.skipCount);
1443     }
1444 
1445     dprintf(out, "********Pulled Atom stats***********\n");
1446     for (const auto& pair : mPulledAtomStats) {
1447         dprintf(out,
1448                 "Atom %d->(total pull)%ld, (pull from cache)%ld, "
1449                 "(pull failed)%ld, (min pull interval)%ld \n"
1450                 "  (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
1451                 "nanos)%lld, "
1452                 "  (max pull delay nanos)%lld, (data error)%ld\n"
1453                 "  (pull timeout)%ld, (pull exceed max delay)%ld"
1454                 "  (no uid provider count)%ld, (no puller found count)%ld\n"
1455                 "  (registered count) %ld, (unregistered count) %ld"
1456                 "  (atom error count) %d, (subscription pull count) %d, (binder call failed) %ld\n",
1457                 (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
1458                 (long)pair.second.pullFailed, (long)pair.second.minPullIntervalSec,
1459                 (long long)pair.second.avgPullTimeNs, (long long)pair.second.maxPullTimeNs,
1460                 (long long)pair.second.avgPullDelayNs, (long long)pair.second.maxPullDelayNs,
1461                 pair.second.dataError, pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
1462                 pair.second.pullUidProviderNotFound, pair.second.pullerNotFound,
1463                 pair.second.registeredCount, pair.second.unregisteredCount,
1464                 pair.second.atomErrorCount, pair.second.subscriptionPullCount,
1465                 pair.second.binderCallFailCount);
1466         if (pair.second.pullTimeoutMetadata.size() > 0) {
1467             string uptimeMillis = "(pull timeout system uptime millis) ";
1468             string pullTimeoutMillis = "(pull timeout elapsed time millis) ";
1469             for (const auto& stats : pair.second.pullTimeoutMetadata) {
1470                 uptimeMillis.append(to_string(stats.pullTimeoutUptimeMillis)).append(",");
1471                 pullTimeoutMillis.append(to_string(stats.pullTimeoutElapsedMillis)).append(",");
1472             }
1473             uptimeMillis.pop_back();
1474             uptimeMillis.push_back('\n');
1475             pullTimeoutMillis.pop_back();
1476             pullTimeoutMillis.push_back('\n');
1477             dprintf(out, "%s", uptimeMillis.c_str());
1478             dprintf(out, "%s", pullTimeoutMillis.c_str());
1479         }
1480     }
1481 
1482     if (mAnomalyAlarmRegisteredStats > 0) {
1483         dprintf(out, "********AnomalyAlarmStats stats***********\n");
1484         dprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats);
1485     }
1486 
1487     if (mPeriodicAlarmRegisteredStats > 0) {
1488         dprintf(out, "********SubscriberAlarmStats stats***********\n");
1489         dprintf(out, "Subscriber alarm registrations: %d\n", mPeriodicAlarmRegisteredStats);
1490     }
1491 
1492     dprintf(out, "UID map stats: bytes=%d, changes=%d, deleted=%d, changes lost=%d\n",
1493             mUidMapStats.bytes_used, mUidMapStats.changes, mUidMapStats.deleted_apps,
1494             mUidMapStats.dropped_changes);
1495 
1496     for (const auto& restart : mSystemServerRestartSec) {
1497         dprintf(out, "System server restarts at %s(%lld)\n", buildTimeString(restart).c_str(),
1498                 (long long)restart);
1499     }
1500 
1501     dprintf(out, "********Socket batch read size stats***********\n");
1502     for (int i = 0; i < kNumBinsInSocketBatchReadHistogram; i++) {
1503         if (mSocketBatchReadHistogram[i] == 0) {
1504             continue;
1505         }
1506         string range;
1507         if (i < 5) {
1508             range = "[" + to_string(i) + "]";
1509         } else if (i == 5) {
1510             range = "[5-9]";
1511         } else if (i < 15) {
1512             range = "[" + to_string(i - 5) + "0-" + to_string(i - 5) + "9]";
1513         } else if (i < 24) {
1514             range = "[" + to_string(i - 14) + "00-" + to_string(i - 14) + "99]";
1515         } else if (i < 29) {
1516             range = "[" + to_string((i - 19) * 2) + "00-" + to_string((i - 19) * 2 + 1) + "99]";
1517         } else {
1518             range = "[2000+]";
1519         }
1520         dprintf(out, "%s: %lld\n", range.c_str(), (long long)mSocketBatchReadHistogram[i]);
1521     }
1522 
1523     if (mLargeBatchSocketReadStats.size() > 0) {
1524         dprintf(out, "Large socket read batch stats: \n");
1525         for (const auto& batchRead : mLargeBatchSocketReadStats) {
1526             dprintf(out,
1527                     "Num atoms: %d - read time elapsed ms: %lld, prev read time: %lld, min atom "
1528                     "elapsed ms: %lld, max atom elapsed ns: %lld\n",
1529                     batchRead.mSize, (long long)NanoToMillis(batchRead.mCurrReadTimeNs),
1530                     (long long)NanoToMillis(batchRead.mLastReadTimeNs),
1531                     (long long)NanoToMillis(batchRead.mMinAtomReadTimeNs),
1532                     (long long)NanoToMillis(batchRead.mMaxAtomReadTimeNs));
1533             if (batchRead.mCommonAtomCounts.size() > 0) {
1534                 string commonAtoms = "  Common atoms: ";
1535                 auto it = batchRead.mCommonAtomCounts.begin();
1536                 commonAtoms.append(to_string(it->first).append(": ").append(to_string(it->second)));
1537                 for (++it; it != batchRead.mCommonAtomCounts.end(); ++it) {
1538                     commonAtoms.append(
1539                             ", " + to_string(it->first).append(": ").append(to_string(it->second)));
1540                 }
1541                 dprintf(out, "%s\n", commonAtoms.c_str());
1542             }
1543         }
1544         dprintf(out, "\n");
1545     }
1546 
1547     for (const auto& loss : mLogLossStats) {
1548         dprintf(out,
1549                 "Log loss: %lld (wall clock sec) - %d (count), %d (last error), %d (last tag), %d "
1550                 "(uid), %d (pid)\n",
1551                 (long long)loss.mWallClockSec, loss.mCount, loss.mLastError, loss.mLastTag,
1552                 loss.mUid, loss.mPid);
1553     }
1554 
1555     if (mSocketLossStats.size()) {
1556         dprintf(out, "********SocketLossStats stats***********\n");
1557         for (const auto& loss : mSocketLossStats) {
1558             dprintf(out, "Socket loss: %d (uid), first loss at %lld, last loss at %lld\n",
1559                     loss.mUid, (long long)loss.mFirstLossTsNanos, (long long)loss.mLastLossTsNanos);
1560             for (const auto& counterInfo : loss.mLossCountPerErrorAtomId) {
1561                 dprintf(out, "\t\t %d (atomId) %d (error), %d (count)\n", counterInfo.mAtomId,
1562                         counterInfo.mError, counterInfo.mCount);
1563             }
1564         }
1565     }
1566 
1567     if (mSocketLossStatsOverflowCounters.size()) {
1568         dprintf(out, "********mSocketLossStatsOverflowCounters stats***********\n");
1569         for (const auto& overflow : mSocketLossStatsOverflowCounters) {
1570             dprintf(out, "Socket loss overflow for %d uid is %d times\n", overflow.first,
1571                     overflow.second);
1572         }
1573     }
1574 
1575     dprintf(out, "********EventQueueOverflow stats***********\n");
1576     dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n",
1577             mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs);
1578     dprintf(out, "Event queue max size: %d; Observed at : %lld\n", mEventQueueMaxSizeObserved,
1579             (long long)mEventQueueMaxSizeObservedElapsedNanos);
1580 
1581     if (mActivationBroadcastGuardrailStats.size() > 0) {
1582         dprintf(out, "********mActivationBroadcastGuardrail stats***********\n");
1583         for (const auto& pair: mActivationBroadcastGuardrailStats) {
1584             dprintf(out, "Uid %d: Times: ", pair.first);
1585             for (const auto& guardrailHitTime : pair.second) {
1586                 dprintf(out, "%d ", guardrailHitTime);
1587             }
1588         }
1589         dprintf(out, "\n");
1590     }
1591 
1592     dprintf(out, "********Atom Subscription stats***********\n");
1593     dprintf(out, "Pull thread wakeup count: %d\n", mSubscriptionPullThreadWakeupCount);
1594     for (const auto& [id, subStats] : mSubscriptionStats) {
1595         dprintf(out,
1596                 "Subscription %d: pushed_atom_count=%d, pulled_atom_count=%d, flush_count=%d\n", id,
1597                 subStats.pushed_atom_count, subStats.pulled_atom_count, subStats.flush_count);
1598         dprintf(out, "\n");
1599     }
1600 
1601     if (mRestrictedMetricQueryStats.size() > 0) {
1602         dprintf(out, "********Restricted Metric Query stats***********\n");
1603         for (const auto& stat : mRestrictedMetricQueryStats) {
1604             if (stat.mHasError) {
1605                 dprintf(out,
1606                         "Query with error type: %d - %lld (query time ns), "
1607                         "%d (calling uid), %lld (config id), %s (config package), %s (error)\n",
1608                         stat.mInvalidQueryReason.value(), (long long)stat.mQueryWallTimeNs,
1609                         stat.mCallingUid, (long long)stat.mConfigId, stat.mConfigPackage.c_str(),
1610                         stat.mError.c_str());
1611             } else {
1612                 dprintf(out,
1613                         "Query succeed - %lld (query time ns), %d (calling uid), "
1614                         "%lld (config id), %s (config package), %d (config uid), "
1615                         "%lld (queryLatencyNs)\n",
1616                         (long long)stat.mQueryWallTimeNs, stat.mCallingUid,
1617                         (long long)stat.mConfigId, stat.mConfigPackage.c_str(),
1618                         stat.mConfigUid.value(), (long long)stat.mQueryLatencyNs.value());
1619             }
1620         }
1621     }
1622     dprintf(out, "********Statsd Stats Id***********\n");
1623     dprintf(out, "Statsd Stats Id %d\n", mStatsdStatsId);
1624     dprintf(out, "********Shard Offset Provider stats***********\n");
1625     dprintf(out, "Shard Offset: %u\n", ShardOffsetProvider::getInstance().getShardOffset());
1626     dprintf(out, "\n");
1627 }
1628 
addConfigStatsToProto(const ConfigStats & configStats,ProtoOutputStream * proto)1629 void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) {
1630     uint64_t token =
1631             proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS);
1632     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_UID, configStats.uid);
1633     proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ID, (long long)configStats.id);
1634     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CREATION, configStats.creation_time_sec);
1635     if (configStats.reset_time_sec != 0) {
1636         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESET, configStats.reset_time_sec);
1637     }
1638     if (configStats.deletion_time_sec != 0) {
1639         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DELETION,
1640                      configStats.deletion_time_sec);
1641     }
1642     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_METRIC_COUNT, configStats.metric_count);
1643     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CONDITION_COUNT,
1644                  configStats.condition_count);
1645     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_MATCHER_COUNT, configStats.matcher_count);
1646     proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ALERT_COUNT, configStats.alert_count);
1647     proto->write(FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_VALID, configStats.is_valid);
1648 
1649     if (!configStats.is_valid) {
1650         uint64_t tmpToken =
1651                 proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_STATS_INVALID_CONFIG_REASON);
1652         proto->write(FIELD_TYPE_ENUM | FIELD_ID_INVALID_CONFIG_REASON_ENUM,
1653                      configStats.reason->reason);
1654         if (configStats.reason->metricId.has_value()) {
1655             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_METRIC_ID,
1656                          configStats.reason->metricId.value());
1657         }
1658         if (configStats.reason->stateId.has_value()) {
1659             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_STATE_ID,
1660                          configStats.reason->stateId.value());
1661         }
1662         if (configStats.reason->alertId.has_value()) {
1663             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_ALERT_ID,
1664                          configStats.reason->alertId.value());
1665         }
1666         if (configStats.reason->alarmId.has_value()) {
1667             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_ALARM_ID,
1668                          configStats.reason->alarmId.value());
1669         }
1670         if (configStats.reason->subscriptionId.has_value()) {
1671             proto->write(FIELD_TYPE_INT64 | FIELD_ID_INVALID_CONFIG_REASON_SUBSCRIPTION_ID,
1672                          configStats.reason->subscriptionId.value());
1673         }
1674         for (const auto& matcherId : configStats.reason->matcherIds) {
1675             proto->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
1676                                  FIELD_ID_INVALID_CONFIG_REASON_MATCHER_ID,
1677                          matcherId);
1678         }
1679         for (const auto& conditionId : configStats.reason->conditionIds) {
1680             proto->write(FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
1681                                  FIELD_ID_INVALID_CONFIG_REASON_CONDITION_ID,
1682                          conditionId);
1683         }
1684         proto->end(tmpToken);
1685     }
1686 
1687     for (const auto& broadcast : configStats.broadcast_sent_time_sec) {
1688         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_BROADCAST | FIELD_COUNT_REPEATED,
1689                      broadcast);
1690     }
1691 
1692     for (const auto& activation : configStats.activation_time_sec) {
1693         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ACTIVATION | FIELD_COUNT_REPEATED,
1694                      activation);
1695     }
1696 
1697     for (const auto& deactivation : configStats.deactivation_time_sec) {
1698         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DEACTIVATION | FIELD_COUNT_REPEATED,
1699                      deactivation);
1700     }
1701 
1702     for (const auto& drop_time : configStats.data_drop_time_sec) {
1703         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DATA_DROP_TIME | FIELD_COUNT_REPEATED,
1704                      drop_time);
1705     }
1706 
1707     for (const auto& drop_bytes : configStats.data_drop_bytes) {
1708         proto->write(
1709                 FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_DATA_DROP_BYTES | FIELD_COUNT_REPEATED,
1710                 (long long)drop_bytes);
1711     }
1712 
1713     for (const auto& dump : configStats.dump_report_stats) {
1714         proto->write(
1715                 FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_TIME | FIELD_COUNT_REPEATED,
1716                 dump.mDumpReportTimeSec);
1717     }
1718 
1719     for (const auto& dump : configStats.dump_report_stats) {
1720         proto->write(
1721                 FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_BYTES | FIELD_COUNT_REPEATED,
1722                 (long long)dump.mDumpReportSizeBytes);
1723     }
1724 
1725     for (const auto& dump : configStats.dump_report_stats) {
1726         proto->write(
1727                 FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DUMP_REPORT_NUMBER | FIELD_COUNT_REPEATED,
1728                 dump.mDumpReportNumber);
1729     }
1730 
1731     for (const auto& annotation : configStats.annotations) {
1732         uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1733                                       FIELD_ID_CONFIG_STATS_ANNOTATION);
1734         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT64,
1735                      (long long)annotation.first);
1736         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT32, annotation.second);
1737         proto->end(token);
1738     }
1739 
1740     for (const auto& pair : configStats.matcher_stats) {
1741         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1742                                           FIELD_ID_CONFIG_STATS_MATCHER_STATS);
1743         proto->write(FIELD_TYPE_INT64 | FIELD_ID_MATCHER_STATS_ID, (long long)pair.first);
1744         proto->write(FIELD_TYPE_INT32 | FIELD_ID_MATCHER_STATS_COUNT, pair.second);
1745         proto->end(tmpToken);
1746     }
1747 
1748     for (const auto& pair : configStats.condition_stats) {
1749         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1750                                           FIELD_ID_CONFIG_STATS_CONDITION_STATS);
1751         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONDITION_STATS_ID, (long long)pair.first);
1752         proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONDITION_STATS_COUNT, pair.second);
1753         proto->end(tmpToken);
1754     }
1755 
1756     for (const auto& pair : configStats.metric_stats) {
1757         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1758                                           FIELD_ID_CONFIG_STATS_METRIC_STATS);
1759         proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
1760         proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
1761         proto->end(tmpToken);
1762     }
1763     for (const auto& pair : configStats.metric_dimension_in_condition_stats) {
1764         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1765                                          FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS);
1766         proto->write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_STATS_ID, (long long)pair.first);
1767         proto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_STATS_COUNT, pair.second);
1768         proto->end(tmpToken);
1769     }
1770 
1771     for (const auto& pair : configStats.alert_stats) {
1772         uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
1773                                           FIELD_ID_CONFIG_STATS_ALERT_STATS);
1774         proto->write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_STATS_ID, (long long)pair.first);
1775         proto->write(FIELD_TYPE_INT32 | FIELD_ID_ALERT_STATS_COUNT, pair.second);
1776         proto->end(tmpToken);
1777     }
1778 
1779     for (const auto& pair : configStats.restricted_metric_stats) {
1780         uint64_t token =
1781                 proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_STATS_RESTRICTED_METRIC_STATS |
1782                              FIELD_COUNT_REPEATED);
1783 
1784         proto->write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_METRIC_ID, (long long)pair.first);
1785         writeNonZeroStatToStream(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_INSERT_ERROR,
1786                                  (long long)pair.second.insertError, proto);
1787         writeNonZeroStatToStream(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_TABLE_CREATION_ERROR,
1788                                  (long long)pair.second.tableCreationError, proto);
1789         writeNonZeroStatToStream(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_TABLE_DELETION_ERROR,
1790                                  (long long)pair.second.tableDeletionError, proto);
1791         for (const int64_t flushLatencyNs : pair.second.flushLatencyNs) {
1792             proto->write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_FLUSH_LATENCY |
1793                                  FIELD_COUNT_REPEATED,
1794                          flushLatencyNs);
1795         }
1796         writeNonZeroStatToStream(
1797                 FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_STATS_CATEGORY_CHANGED_COUNT,
1798                 (long long)pair.second.categoryChangedCount, proto);
1799         proto->end(token);
1800     }
1801     writeNonZeroStatToStream(
1802             FIELD_TYPE_BOOL | FIELD_ID_CONFIG_STATS_DEVICE_INFO_TABLE_CREATION_FAILED,
1803             configStats.device_info_table_creation_failed, proto);
1804     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESTRICTED_DB_CORRUPTED_COUNT,
1805                              configStats.db_corrupted_count, proto);
1806     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_DB_DELETION_STAT_FAILED,
1807                              configStats.db_deletion_size_exceeded_limit, proto);
1808     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_DB_DELETION_SIZE_EXCEEDED_LIMIT,
1809                              configStats.db_deletion_size_exceeded_limit, proto);
1810     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_DB_DELETION_CONFIG_INVALID,
1811                              configStats.db_deletion_config_invalid, proto);
1812     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_DB_DELETION_TOO_OLD,
1813                              configStats.db_deletion_too_old, proto);
1814     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_DB_DELETION_CONFIG_REMOVED,
1815                              configStats.db_deletion_config_removed, proto);
1816     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_DB_DELETION_CONFIG_UPDATED,
1817                              configStats.db_deletion_config_updated, proto);
1818     writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_METADATA_PROVIDER_PROMOTION_FAILED,
1819                              configStats.config_metadata_provider_promote_failure, proto);
1820     for (int64_t latency : configStats.total_flush_latency_ns) {
1821         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_FLUSH_LATENCY |
1822                              FIELD_COUNT_REPEATED,
1823                      latency);
1824     }
1825     for (int64_t dbSizeTimestamp : configStats.total_db_size_timestamps) {
1826         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_TIME_SEC |
1827                              FIELD_COUNT_REPEATED,
1828                      dbSizeTimestamp);
1829     }
1830     for (int64_t dbSize : configStats.total_db_sizes) {
1831         proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_RESTRICTED_CONFIG_DB_SIZE_BYTES |
1832                              FIELD_COUNT_REPEATED,
1833                      dbSize);
1834     }
1835     proto->end(token);
1836 }
1837 
dumpStats(vector<uint8_t> * output,bool reset)1838 void StatsdStats::dumpStats(vector<uint8_t>* output, bool reset) {
1839     lock_guard<std::mutex> lock(mLock);
1840 
1841     ProtoOutputStream proto;
1842     proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec);
1843     proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)getWallClockSec());
1844 
1845     for (const auto& configStats : mIceBox) {
1846         addConfigStatsToProto(*configStats, &proto);
1847     }
1848 
1849     for (auto& pair : mConfigStats) {
1850         addConfigStatsToProto(*(pair.second), &proto);
1851     }
1852 
1853     const size_t atomCounts = mPushedAtomStats.size();
1854     for (size_t i = 2; i < atomCounts; i++) {
1855         if (mPushedAtomStats[i].logCount > 0) {
1856             uint64_t token =
1857                     proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
1858             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i);
1859             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i].logCount);
1860             const int errors = getPushedAtomErrorsLocked(i);
1861             writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors,
1862                                      &proto);
1863             const int drops = getPushedAtomDropsLocked(i);
1864             writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_DROPS_COUNT, drops,
1865                                      &proto);
1866             writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_SKIP_COUNT,
1867                                      mPushedAtomStats[i].skipCount, &proto);
1868             proto.end(token);
1869         }
1870     }
1871 
1872     for (const auto& pair : mNonPlatformPushedAtomStats) {
1873         uint64_t token =
1874                 proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOM_STATS | FIELD_COUNT_REPEATED);
1875         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, pair.first);
1876         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, pair.second.logCount);
1877         const int errors = getPushedAtomErrorsLocked(pair.first);
1878         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_ERROR_COUNT, errors,
1879                                  &proto);
1880         const int drops = getPushedAtomDropsLocked(pair.first);
1881         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_DROPS_COUNT, drops, &proto);
1882         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_SKIP_COUNT,
1883                                  pair.second.skipCount, &proto);
1884         proto.end(token);
1885     }
1886 
1887     for (const auto& pair : mPulledAtomStats) {
1888         writePullerStatsToStream(pair, &proto);
1889     }
1890 
1891     for (const auto& pair : mAtomMetricStats) {
1892         writeAtomMetricStatsToStream(pair, &proto);
1893     }
1894 
1895     if (mAnomalyAlarmRegisteredStats > 0) {
1896         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS);
1897         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED,
1898                     mAnomalyAlarmRegisteredStats);
1899         proto.end(token);
1900     }
1901 
1902     if (mPeriodicAlarmRegisteredStats > 0) {
1903         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_PERIODIC_ALARM_STATS);
1904         proto.write(FIELD_TYPE_INT32 | FIELD_ID_PERIODIC_ALARMS_REGISTERED,
1905                     mPeriodicAlarmRegisteredStats);
1906         proto.end(token);
1907     }
1908 
1909     uint64_t uidMapToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS);
1910     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_CHANGES, mUidMapStats.changes);
1911     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_BYTES_USED, mUidMapStats.bytes_used);
1912     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DROPPED_CHANGES, mUidMapStats.dropped_changes);
1913     proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID_MAP_DELETED_APPS, mUidMapStats.deleted_apps);
1914     proto.end(uidMapToken);
1915 
1916     for (const auto& error : mLogLossStats) {
1917         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
1918                                       FIELD_COUNT_REPEATED);
1919         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TIME, error.mWallClockSec);
1920         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_COUNT, error.mCount);
1921         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_ERROR, error.mLastError);
1922         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TAG, error.mLastTag);
1923         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_UID, error.mUid);
1924         proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_PID, error.mPid);
1925         proto.end(token);
1926     }
1927 
1928     if (mOverflowCount > 0) {
1929         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_OVERFLOW);
1930         proto.write(FIELD_TYPE_INT32 | FIELD_ID_OVERFLOW_COUNT, (int32_t)mOverflowCount);
1931         proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MAX_HISTORY,
1932                     (long long)mMaxQueueHistoryNs);
1933         proto.write(FIELD_TYPE_INT64 | FIELD_ID_OVERFLOW_MIN_HISTORY,
1934                     (long long)mMinQueueHistoryNs);
1935         proto.end(token);
1936     }
1937 
1938     uint64_t queueStatsToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_QUEUE_STATS);
1939     proto.write(FIELD_TYPE_INT32 | FIELD_ID_QUEUE_MAX_SIZE_OBSERVED,
1940                 (int32_t)mEventQueueMaxSizeObserved);
1941     proto.write(FIELD_TYPE_INT64 | FIELD_ID_QUEUE_MAX_SIZE_OBSERVED_ELAPSED_NANOS,
1942                 (long long)mEventQueueMaxSizeObservedElapsedNanos);
1943     proto.end(queueStatsToken);
1944 
1945     for (const auto& restart : mSystemServerRestartSec) {
1946         proto.write(FIELD_TYPE_INT32 | FIELD_ID_SYSTEM_SERVER_RESTART | FIELD_COUNT_REPEATED,
1947                     restart);
1948     }
1949 
1950     for (const auto& pair: mActivationBroadcastGuardrailStats) {
1951         uint64_t token = proto.start(FIELD_TYPE_MESSAGE |
1952                                      FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL |
1953                                      FIELD_COUNT_REPEATED);
1954         proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID,
1955                     (int32_t) pair.first);
1956         for (const auto& guardrailHitTime : pair.second) {
1957             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME |
1958                             FIELD_COUNT_REPEATED,
1959                         guardrailHitTime);
1960         }
1961         proto.end(token);
1962     }
1963 
1964     for (const auto& stat : mRestrictedMetricQueryStats) {
1965         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS |
1966                                      FIELD_COUNT_REPEATED);
1967         proto.write(FIELD_TYPE_INT32 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CALLING_UID,
1968                     stat.mCallingUid);
1969         proto.write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_ID,
1970                     stat.mConfigId);
1971         proto.write(FIELD_TYPE_STRING | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_PACKAGE,
1972                     stat.mConfigPackage);
1973         if (stat.mConfigUid.has_value()) {
1974             proto.write(FIELD_TYPE_INT32 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_CONFIG_UID,
1975                         stat.mConfigUid.value());
1976         }
1977         if (stat.mInvalidQueryReason.has_value()) {
1978             proto.write(
1979                     FIELD_TYPE_ENUM | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_INVALID_QUERY_REASON,
1980                     stat.mInvalidQueryReason.value());
1981         }
1982         proto.write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_QUERY_WALL_TIME_NS,
1983                     stat.mQueryWallTimeNs);
1984         proto.write(FIELD_TYPE_BOOL | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_HAS_ERROR,
1985                     stat.mHasError);
1986         if (stat.mHasError && !stat.mError.empty()) {
1987             proto.write(FIELD_TYPE_STRING | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_ERROR,
1988                         stat.mError);
1989         }
1990         if (stat.mQueryLatencyNs.has_value()) {
1991             proto.write(FIELD_TYPE_INT64 | FIELD_ID_RESTRICTED_METRIC_QUERY_STATS_LATENCY_NS,
1992                         stat.mQueryLatencyNs.value());
1993         }
1994         proto.end(token);
1995     }
1996 
1997     proto.write(FIELD_TYPE_UINT32 | FIELD_ID_SHARD_OFFSET,
1998                 static_cast<long>(ShardOffsetProvider::getInstance().getShardOffset()));
1999 
2000     proto.write(FIELD_TYPE_INT32 | FIELD_ID_STATSD_STATS_ID, mStatsdStatsId);
2001 
2002     // Write subscription stats
2003     const uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SUBSCRIPTION_STATS);
2004     for (const auto& [id, subStats] : mSubscriptionStats) {
2005         const uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
2006                                            FIELD_ID_SUBSCRIPTION_STATS_PER_SUBSCRIPTION_STATS);
2007         proto.write(FIELD_TYPE_INT32 | FIELD_ID_PER_SUBSCRIPTION_STATS_ID, id);
2008         writeNonZeroStatToStream(
2009                 FIELD_TYPE_INT32 | FIELD_ID_PER_SUBSCRIPTION_STATS_PUSHED_ATOM_COUNT,
2010                 subStats.pushed_atom_count, &proto);
2011         writeNonZeroStatToStream(
2012                 FIELD_TYPE_INT32 | FIELD_ID_PER_SUBSCRIPTION_STATS_PULLED_ATOM_COUNT,
2013                 subStats.pulled_atom_count, &proto);
2014         proto.write(FIELD_TYPE_INT32 | FIELD_ID_PER_SUBSCRIPTION_STATS_START_TIME,
2015                     subStats.start_time_sec);
2016         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_PER_SUBSCRIPTION_STATS_END_TIME,
2017                                  subStats.end_time_sec, &proto);
2018         writeNonZeroStatToStream(FIELD_TYPE_INT32 | FIELD_ID_PER_SUBSCRIPTION_STATS_FLUSH_COUNT,
2019                                  subStats.flush_count, &proto);
2020         proto.end(token);
2021     }
2022     writeNonZeroStatToStream(
2023             FIELD_TYPE_INT32 | FIELD_ID_SUBSCRIPTION_STATS_PULL_THREAD_WAKEUP_COUNT,
2024             mSubscriptionPullThreadWakeupCount, &proto);
2025     proto.end(token);
2026 
2027     // libstatssocket specific stats
2028 
2029     const uint64_t socketLossStatsToken =
2030             proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_STATS);
2031 
2032     // socket loss stats info per uid/error/atom id counter
2033     for (const auto& perUidLossInfo : mSocketLossStats) {
2034         uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_STATS_PER_UID |
2035                                      FIELD_COUNT_REPEATED);
2036         proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_UID, perUidLossInfo.mUid);
2037         proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_FIRST_TIMESTAMP_NANOS,
2038                     perUidLossInfo.mFirstLossTsNanos);
2039         proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_LAST_TIMESTAMP_NANOS,
2040                     perUidLossInfo.mLastLossTsNanos);
2041         for (const auto& counterInfo : perUidLossInfo.mLossCountPerErrorAtomId) {
2042             uint64_t token =
2043                     proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_ATOM_ID_LOSS_STATS |
2044                                 FIELD_COUNT_REPEATED);
2045             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ID_LOSS_STATS_ATOM_ID,
2046                         counterInfo.mAtomId);
2047             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ID_LOSS_STATS_ERROR, counterInfo.mError);
2048             proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_ID_LOSS_STATS_COUNT, counterInfo.mCount);
2049             proto.end(token);
2050         }
2051         proto.end(token);
2052     }
2053 
2054     // socket loss stats overflow counters
2055     for (const auto& overflowInfo : mSocketLossStatsOverflowCounters) {
2056         uint64_t token =
2057                 proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS |
2058                             FIELD_COUNT_REPEATED);
2059         proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_UID,
2060                     overflowInfo.first);
2061         proto.write(FIELD_TYPE_INT32 | FIELD_ID_SOCKET_LOSS_STATS_OVERFLOW_COUNTERS_COUNT,
2062                     overflowInfo.second);
2063         proto.end(token);
2064     }
2065 
2066     proto.end(socketLossStatsToken);
2067 
2068     // Socket batch read stats.
2069     const uint64_t socketReadStatsToken =
2070             proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_SOCKET_READ_STATS);
2071     for (const auto& it : mSocketBatchReadHistogram) {
2072         proto.write(FIELD_TYPE_INT64 | FIELD_ID_SOCKET_READ_STATS_BATCHED_READ_SIZE |
2073                             FIELD_COUNT_REPEATED,
2074                     it);
2075     }
2076 
2077     for (const auto& batchRead : mLargeBatchSocketReadStats) {
2078         const uint64_t largeBatchStatsToken =
2079                 proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
2080                             FIELD_ID_SOCKET_READ_STATS_LARGE_BATCH_STATS);
2081         proto.write(FIELD_TYPE_INT64 | FIELD_ID_LARGE_BATCH_SOCKET_READ_LAST_READ_TIME,
2082                     batchRead.mLastReadTimeNs);
2083         proto.write(FIELD_TYPE_INT64 | FIELD_ID_LARGE_BATCH_SOCKET_READ_CURR_READ_TIME,
2084                     batchRead.mCurrReadTimeNs);
2085         proto.write(FIELD_TYPE_INT64 | FIELD_ID_LARGE_BATCH_SOCKET_READ_MIN_ATOM_TIME,
2086                     batchRead.mMinAtomReadTimeNs);
2087         proto.write(FIELD_TYPE_INT64 | FIELD_ID_LARGE_BATCH_SOCKET_READ_MAX_ATOM_TIME,
2088                     batchRead.mMaxAtomReadTimeNs);
2089         proto.write(FIELD_TYPE_INT64 | FIELD_ID_LARGE_BATCH_SOCKET_READ_TOTAL_ATOMS,
2090                     batchRead.mSize);
2091         for (const auto& [batchAtomId, batchAtomCount] : batchRead.mCommonAtomCounts) {
2092             const uint64_t largeBatchAtomStatsToken =
2093                     proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
2094                                 FIELD_ID_LARGE_BATCH_SOCKET_READ_ATOM_STATS);
2095             proto.write(FIELD_TYPE_INT32 | FIELD_ID_LARGE_BATCH_SOCKET_READ_ATOM_STATS_ATOM_ID,
2096                         batchAtomId);
2097             proto.write(FIELD_TYPE_INT32 | FIELD_ID_LARGE_BATCH_SOCKET_READ_ATOM_STATS_COUNT,
2098                         batchAtomCount);
2099             proto.end(largeBatchAtomStatsToken);
2100         }
2101         proto.end(largeBatchStatsToken);
2102     }
2103     proto.end(socketReadStatsToken);
2104 
2105     output->clear();
2106     proto.serializeToVector(output);
2107 
2108     if (reset) {
2109         resetInternalLocked();
2110     }
2111 
2112     VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)output->size());
2113 }
2114 
getAtomDimensionKeySizeLimits(int atomId,size_t defaultHardLimit)2115 std::pair<size_t, size_t> StatsdStats::getAtomDimensionKeySizeLimits(int atomId,
2116                                                                      size_t defaultHardLimit) {
2117     return kAtomDimensionKeySizeLimitMap.find(atomId) != kAtomDimensionKeySizeLimitMap.end()
2118                    ? kAtomDimensionKeySizeLimitMap.at(atomId)
2119                    : std::pair<size_t, size_t>(kDimensionKeySizeSoftLimit, defaultHardLimit);
2120 }
2121 
createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,const int64_t matcherId)2122 InvalidConfigReason createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,
2123                                                          const int64_t matcherId) {
2124     InvalidConfigReason invalidConfigReason(reason);
2125     invalidConfigReason.matcherIds.push_back(matcherId);
2126     return invalidConfigReason;
2127 }
2128 
createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t matcherId)2129 InvalidConfigReason createInvalidConfigReasonWithMatcher(const InvalidConfigReasonEnum reason,
2130                                                          const int64_t metricId,
2131                                                          const int64_t matcherId) {
2132     InvalidConfigReason invalidConfigReason(reason, metricId);
2133     invalidConfigReason.matcherIds.push_back(matcherId);
2134     return invalidConfigReason;
2135 }
2136 
createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,const int64_t conditionId)2137 InvalidConfigReason createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,
2138                                                            const int64_t conditionId) {
2139     InvalidConfigReason invalidConfigReason(reason);
2140     invalidConfigReason.conditionIds.push_back(conditionId);
2141     return invalidConfigReason;
2142 }
2143 
createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t conditionId)2144 InvalidConfigReason createInvalidConfigReasonWithPredicate(const InvalidConfigReasonEnum reason,
2145                                                            const int64_t metricId,
2146                                                            const int64_t conditionId) {
2147     InvalidConfigReason invalidConfigReason(reason, metricId);
2148     invalidConfigReason.conditionIds.push_back(conditionId);
2149     return invalidConfigReason;
2150 }
2151 
createInvalidConfigReasonWithState(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t stateId)2152 InvalidConfigReason createInvalidConfigReasonWithState(const InvalidConfigReasonEnum reason,
2153                                                        const int64_t metricId,
2154                                                        const int64_t stateId) {
2155     InvalidConfigReason invalidConfigReason(reason, metricId);
2156     invalidConfigReason.stateId = stateId;
2157     return invalidConfigReason;
2158 }
2159 
createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,const int64_t alertId)2160 InvalidConfigReason createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,
2161                                                        const int64_t alertId) {
2162     InvalidConfigReason invalidConfigReason(reason);
2163     invalidConfigReason.alertId = alertId;
2164     return invalidConfigReason;
2165 }
2166 
createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,const int64_t metricId,const int64_t alertId)2167 InvalidConfigReason createInvalidConfigReasonWithAlert(const InvalidConfigReasonEnum reason,
2168                                                        const int64_t metricId,
2169                                                        const int64_t alertId) {
2170     InvalidConfigReason invalidConfigReason(reason, metricId);
2171     invalidConfigReason.alertId = alertId;
2172     return invalidConfigReason;
2173 }
2174 
createInvalidConfigReasonWithAlarm(const InvalidConfigReasonEnum reason,const int64_t alarmId)2175 InvalidConfigReason createInvalidConfigReasonWithAlarm(const InvalidConfigReasonEnum reason,
2176                                                        const int64_t alarmId) {
2177     InvalidConfigReason invalidConfigReason(reason);
2178     invalidConfigReason.alarmId = alarmId;
2179     return invalidConfigReason;
2180 }
2181 
createInvalidConfigReasonWithSubscription(const InvalidConfigReasonEnum reason,const int64_t subscriptionId)2182 InvalidConfigReason createInvalidConfigReasonWithSubscription(const InvalidConfigReasonEnum reason,
2183                                                               const int64_t subscriptionId) {
2184     InvalidConfigReason invalidConfigReason(reason);
2185     invalidConfigReason.subscriptionId = subscriptionId;
2186     return invalidConfigReason;
2187 }
2188 
createInvalidConfigReasonWithSubscriptionAndAlarm(const InvalidConfigReasonEnum reason,const int64_t subscriptionId,const int64_t alarmId)2189 InvalidConfigReason createInvalidConfigReasonWithSubscriptionAndAlarm(
2190         const InvalidConfigReasonEnum reason, const int64_t subscriptionId, const int64_t alarmId) {
2191     InvalidConfigReason invalidConfigReason(reason);
2192     invalidConfigReason.subscriptionId = subscriptionId;
2193     invalidConfigReason.alarmId = alarmId;
2194     return invalidConfigReason;
2195 }
2196 
createInvalidConfigReasonWithSubscriptionAndAlert(const InvalidConfigReasonEnum reason,const int64_t subscriptionId,const int64_t alertId)2197 InvalidConfigReason createInvalidConfigReasonWithSubscriptionAndAlert(
2198         const InvalidConfigReasonEnum reason, const int64_t subscriptionId, const int64_t alertId) {
2199     InvalidConfigReason invalidConfigReason(reason);
2200     invalidConfigReason.subscriptionId = subscriptionId;
2201     invalidConfigReason.alertId = alertId;
2202     return invalidConfigReason;
2203 }
2204 
PrintTo(const InvalidConfigReason & obj,std::ostream * os)2205 void PrintTo(const InvalidConfigReason& obj, std::ostream* os) {
2206     *os << "{ reason: " << obj.reason;
2207     if (obj.metricId.has_value()) {
2208         *os << ", metricId: " << obj.metricId.value();
2209     }
2210     if (obj.stateId.has_value()) {
2211         *os << ", stateId: " << obj.stateId.value();
2212     }
2213     if (obj.alertId.has_value()) {
2214         *os << ", alertId: " << obj.alertId.value();
2215     }
2216     if (obj.alarmId.has_value()) {
2217         *os << ", alarmId: " << obj.alarmId.value();
2218     }
2219     if (obj.subscriptionId.has_value()) {
2220         *os << ", subscriptionId: " << obj.subscriptionId.value();
2221     }
2222     if (!obj.matcherIds.empty()) {
2223         *os << ", matcherIds: [";
2224         std::copy(obj.matcherIds.begin(), obj.matcherIds.end(),
2225                   std::ostream_iterator<int64_t>(*os, ", "));
2226         *os << "]";
2227     }
2228     if (!obj.conditionIds.empty()) {
2229         *os << ", conditionIds: [";
2230         std::copy(obj.conditionIds.begin(), obj.conditionIds.end(),
2231                   std::ostream_iterator<int64_t>(*os, ", "));
2232         *os << "]";
2233     }
2234     *os << " }";
2235 }
2236 
2237 }  // namespace statsd
2238 }  // namespace os
2239 }  // namespace android
2240