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