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