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