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