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