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