blob: 434920ebe8c724b797cc3ff9ad8686b64506a844 [file] [log] [blame]
Yao Chenb3561512017-11-21 18:07:17 -08001/*
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#pragma once
17
18#include "config/ConfigKey.h"
Chenjie Yub038b702017-12-18 15:15:34 -080019#include "statslog.h"
Yao Chenb3561512017-11-21 18:07:17 -080020
Yao Chen69f1baf2017-11-27 17:25:36 -080021#include <gtest/gtest_prod.h>
David Chend9269e22017-12-05 13:43:51 -080022#include <log/log_time.h>
Yao Chenf6723df2018-01-08 15:11:58 -080023#include <list>
Yao Chenb3561512017-11-21 18:07:17 -080024#include <mutex>
25#include <string>
26#include <vector>
27
28namespace android {
29namespace os {
30namespace statsd {
31
Yao Chen20e9e622018-02-28 11:18:51 -080032struct ConfigStats {
33 int32_t uid;
34 int64_t id;
35 int32_t creation_time_sec;
36 int32_t deletion_time_sec = 0;
Yangster-macb142cc82018-03-30 15:22:08 -070037 int32_t reset_time_sec = 0;
Yao Chen20e9e622018-02-28 11:18:51 -080038 int32_t metric_count;
39 int32_t condition_count;
40 int32_t matcher_count;
41 int32_t alert_count;
42 bool is_valid;
43
44 std::list<int32_t> broadcast_sent_time_sec;
Tej Singh6ede28b2019-01-29 17:06:54 -080045
46 // Times at which this config is activated.
47 std::list<int32_t> activation_time_sec;
48
49 // Times at which this config is deactivated.
50 std::list<int32_t> deactivation_time_sec;
51
Yao Chen20e9e622018-02-28 11:18:51 -080052 std::list<int32_t> data_drop_time_sec;
Chenjie Yuc3c30c02018-10-26 09:48:07 -070053 // Number of bytes dropped at corresponding time.
54 std::list<int64_t> data_drop_bytes;
Yangster-mace68f3a52018-04-04 00:01:43 -070055 std::list<std::pair<int32_t, int64_t>> dump_report_stats;
Yao Chen20e9e622018-02-28 11:18:51 -080056
57 // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount.
58 std::map<const int64_t, int> matcher_stats;
59
60 // Stores the number of output tuple of condition trackers when it's bigger than
61 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
62 // it means some data has been dropped. The map size is capped by kMaxConfigCount.
63 std::map<const int64_t, int> condition_stats;
64
65 // Stores the number of output tuple of metric producers when it's bigger than
66 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
67 // it means some data has been dropped. The map size is capped by kMaxConfigCount.
68 std::map<const int64_t, int> metric_stats;
69
Yangster-mac306ccc22018-03-24 15:03:40 -070070 // Stores the max number of output tuple of dimensions in condition across dimensions in what
71 // when it's bigger than kDimensionKeySizeSoftLimit. When you see the number is
72 // kDimensionKeySizeHardLimit +1, it means some data has been dropped. The map size is capped by
73 // kMaxConfigCount.
74 std::map<const int64_t, int> metric_dimension_in_condition_stats;
75
Yao Chen20e9e622018-02-28 11:18:51 -080076 // Stores the number of times an anomaly detection alert has been declared.
77 // The map size is capped by kMaxConfigCount.
78 std::map<const int64_t, int> alert_stats;
David Chenfaa1af52018-03-30 15:14:04 -070079
80 // Stores the config ID for each sub-config used.
81 std::list<std::pair<const int64_t, const int32_t>> annotations;
Yao Chen20e9e622018-02-28 11:18:51 -080082};
83
84struct UidMapStats {
Yao Chen20e9e622018-02-28 11:18:51 -080085 int32_t changes;
86 int32_t bytes_used;
Yao Chen20e9e622018-02-28 11:18:51 -080087 int32_t dropped_changes;
David Chenbd125272018-04-04 19:02:50 -070088 int32_t deleted_apps = 0;
Yao Chen20e9e622018-02-28 11:18:51 -080089};
90
Yao Chenb3561512017-11-21 18:07:17 -080091// Keeps track of stats of statsd.
Yao Chen20e9e622018-02-28 11:18:51 -080092// Single instance shared across the process. All public methods are thread safe.
Yao Chenb3561512017-11-21 18:07:17 -080093class StatsdStats {
94public:
95 static StatsdStats& getInstance();
96 ~StatsdStats(){};
97
Yao Chen52b478b2018-03-27 10:59:45 -070098 const static int kDimensionKeySizeSoftLimit = 500;
99 const static int kDimensionKeySizeHardLimit = 800;
Yao Chenb3561512017-11-21 18:07:17 -0800100
Chenjie Yuc5875052018-03-09 10:13:11 -0800101 // Per atom dimension key size limit
102 static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
103
Yao Chen52b478b2018-03-27 10:59:45 -0700104 const static int kMaxConfigCountPerUid = 10;
Bookatz1476ef22018-02-13 12:26:01 -0800105 const static int kMaxAlertCountPerConfig = 100;
Yao Chen52b478b2018-03-27 10:59:45 -0700106 const static int kMaxConditionCountPerConfig = 300;
107 const static int kMaxMetricCountPerConfig = 1000;
108 const static int kMaxMatcherCountPerConfig = 800;
Yao Chenb3561512017-11-21 18:07:17 -0800109
Yao Chenf6723df2018-01-08 15:11:58 -0800110 // The max number of old config stats we keep.
111 const static int kMaxIceBoxSize = 20;
112
Yao Chen163d2602018-04-10 10:39:53 -0700113 const static int kMaxLoggerErrors = 20;
Yangster-macb8382a12018-04-04 10:39:12 -0700114
Yangster-mac892f3d32018-05-02 14:16:48 -0700115 const static int kMaxSystemServerRestarts = 20;
116
Yao Chen0fac5b12017-11-28 16:07:02 -0800117 const static int kMaxTimestampCount = 20;
118
Yao Chend10f7b12017-12-18 12:53:50 -0800119 const static int kMaxLogSourceCount = 50;
120
David Chen4c6d97a2018-03-22 16:31:40 -0700121 // Max memory allowed for storing metrics per configuration. If this limit is exceeded, statsd
122 // drops the metrics data in memory.
Yao Chenbd88bde2018-11-26 15:31:53 -0800123 static const size_t kMaxMetricsBytesPerConfig = 2 * 1024 * 1024;
David Chen4c6d97a2018-03-22 16:31:40 -0700124
125 // Soft memory limit per configuration. Once this limit is exceeded, we begin notifying the
126 // data subscriber that it's time to call getData.
Yangster-macdb185c92018-04-19 10:54:30 -0700127 static const size_t kBytesPerConfigTriggerGetData = 192 * 1024;
David Chend9269e22017-12-05 13:43:51 -0800128
David Chenc136f452017-11-27 11:52:26 -0800129 // Cap the UID map's memory usage to this. This should be fairly high since the UID information
130 // is critical for understanding the metrics.
131 const static size_t kMaxBytesUsedUidMap = 50 * 1024;
132
David Chenbd125272018-04-04 19:02:50 -0700133 // The number of deleted apps that are stored in the uid map.
134 const static int kMaxDeletedAppsInUidMap = 100;
135
David Chend9269e22017-12-05 13:43:51 -0800136 /* Minimum period between two broadcasts in nanoseconds. */
Yangster-macb142cc82018-03-30 15:22:08 -0700137 static const int64_t kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
David Chend9269e22017-12-05 13:43:51 -0800138
139 /* Min period between two checks of byte size per config key in nanoseconds. */
Yao Chenbd88bde2018-11-26 15:31:53 -0800140 static const int64_t kMinByteSizeCheckPeriodNs = 60 * NS_PER_SEC;
David Chend9269e22017-12-05 13:43:51 -0800141
Tej Singh6ede28b2019-01-29 17:06:54 -0800142 /* Minimum period between two activation broadcasts in nanoseconds. */
143 static const int64_t kMinActivationBroadcastPeriodNs = 10 * NS_PER_SEC;
144
yro98a28502018-01-18 17:00:14 -0800145 // Maximum age (30 days) that files on disk can exist in seconds.
146 static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
147
148 // Maximum number of files (1000) that can be in stats directory on disk.
149 static const int kMaxFileNumber = 1000;
150
151 // Maximum size of all files that can be written to stats directory on disk.
152 static const int kMaxFileSize = 50 * 1024 * 1024;
153
Chenjie Yufa22d652018-02-05 14:37:48 -0800154 // How long to try to clear puller cache from last time
155 static const long kPullerCacheClearIntervalSec = 1;
156
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800157 // Max time to do a pull.
158 static const int64_t kPullMaxDelayNs = 10 * NS_PER_SEC;
Tej Singha0c89dd2019-01-25 16:39:18 -0800159
160 // Max platform atom tag number.
161 static const int32_t kMaxPlatformAtomTag = 100000;
162
Yao Chenb3561512017-11-21 18:07:17 -0800163 /**
164 * Report a new config has been received and report the static stats about the config.
165 *
166 * The static stats include: the count of metrics, conditions, matchers, and alerts.
167 * If the config is not valid, this config stats will be put into icebox immediately.
168 */
169 void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
David Chenfaa1af52018-03-30 15:14:04 -0700170 int matchersCount, int alertCount,
171 const std::list<std::pair<const int64_t, const int32_t>>& annotations,
172 bool isValid);
Yao Chenb3561512017-11-21 18:07:17 -0800173 /**
174 * Report a config has been removed.
175 */
176 void noteConfigRemoved(const ConfigKey& key);
Yao Chena80e5c02018-09-04 13:55:29 -0700177 /**
Yangster-macb142cc82018-03-30 15:22:08 -0700178 * Report a config has been reset when ttl expires.
179 */
180 void noteConfigReset(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -0800181
182 /**
183 * Report a broadcast has been sent to a config owner to collect the data.
184 */
185 void noteBroadcastSent(const ConfigKey& key);
186
187 /**
Tej Singh6ede28b2019-01-29 17:06:54 -0800188 * Report that a config has become activated or deactivated.
189 * This can be different from whether or not a broadcast is sent if the
190 * guardrail prevented the broadcast from being sent.
191 */
192 void noteActiveStatusChanged(const ConfigKey& key, bool activate);
193
194 /**
Yao Chenb3561512017-11-21 18:07:17 -0800195 * Report a config's metrics data has been dropped.
196 */
Chenjie Yuc3c30c02018-10-26 09:48:07 -0700197 void noteDataDropped(const ConfigKey& key, const size_t totalBytes);
Yao Chen69f1baf2017-11-27 17:25:36 -0800198
199 /**
200 * Report metrics data report has been sent.
201 *
202 * The report may be requested via StatsManager API, or through adb cmd.
203 */
Yangster-mace68f3a52018-04-04 00:01:43 -0700204 void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes);
Yao Chenb3561512017-11-21 18:07:17 -0800205
206 /**
207 * Report the size of output tuple of a condition.
208 *
209 * Note: only report when the condition has an output dimension, and the tuple
210 * count > kDimensionKeySizeSoftLimit.
211 *
212 * [key]: The config key that this condition belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800213 * [id]: The id of the condition.
Yao Chenb3561512017-11-21 18:07:17 -0800214 * [size]: The output tuple size.
215 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800216 void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800217
218 /**
219 * Report the size of output tuple of a metric.
220 *
221 * Note: only report when the metric has an output dimension, and the tuple
222 * count > kDimensionKeySizeSoftLimit.
223 *
224 * [key]: The config key that this metric belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800225 * [id]: The id of the metric.
Yao Chenb3561512017-11-21 18:07:17 -0800226 * [size]: The output tuple size.
227 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800228 void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800229
Yangster-mac306ccc22018-03-24 15:03:40 -0700230 /**
231 * Report the max size of output tuple of dimension in condition across dimensions in what.
232 *
233 * Note: only report when the metric has an output dimension in condition, and the max tuple
234 * count > kDimensionKeySizeSoftLimit.
235 *
236 * [key]: The config key that this metric belongs to.
237 * [id]: The id of the metric.
238 * [size]: The output tuple size.
239 */
240 void noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t& id, int size);
241
Yao Chenb3561512017-11-21 18:07:17 -0800242 /**
243 * Report a matcher has been matched.
244 *
245 * [key]: The config key that this matcher belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800246 * [id]: The id of the matcher.
Yao Chenb3561512017-11-21 18:07:17 -0800247 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800248 void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
Yao Chenb3561512017-11-21 18:07:17 -0800249
250 /**
Bookatz8f2f3d82017-12-07 13:53:21 -0800251 * Report that an anomaly detection alert has been declared.
252 *
253 * [key]: The config key that this alert belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800254 * [id]: The id of the alert.
Bookatz8f2f3d82017-12-07 13:53:21 -0800255 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800256 void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
Bookatz8f2f3d82017-12-07 13:53:21 -0800257
258 /**
Yao Chenb3561512017-11-21 18:07:17 -0800259 * Report an atom event has been logged.
260 */
261 void noteAtomLogged(int atomId, int32_t timeSec);
262
263 /**
Bookatz1d0136d2017-12-01 11:13:32 -0800264 * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
265 */
266 void noteRegisteredAnomalyAlarmChanged();
267
268 /**
Yangster-mac932ecec2018-02-01 10:23:52 -0800269 * Report that statsd modified the periodic alarm registered with StatsCompanionService.
270 */
271 void noteRegisteredPeriodicAlarmChanged();
272
273 /**
David Chenbd125272018-04-04 19:02:50 -0700274 * Records the number of delta entries that are being dropped from the uid map.
David Chenc136f452017-11-27 11:52:26 -0800275 */
David Chenbd125272018-04-04 19:02:50 -0700276 void noteUidMapDropped(int deltas);
David Chenc136f452017-11-27 11:52:26 -0800277
278 /**
David Chenbd125272018-04-04 19:02:50 -0700279 * Records that an app was deleted (from statsd's map).
David Chenc136f452017-11-27 11:52:26 -0800280 */
David Chenbd125272018-04-04 19:02:50 -0700281 void noteUidMapAppDeletionDropped();
282
283 /**
284 * Updates the number of changes currently stored in the uid map.
285 */
David Chenc136f452017-11-27 11:52:26 -0800286 void setUidMapChanges(int changes);
287 void setCurrentUidMapMemory(int bytes);
288
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700289 /*
290 * Updates minimum interval between pulls for an pulled atom.
291 */
Chenjie Yub038b702017-12-18 15:15:34 -0800292 void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
293
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700294 /*
295 * Notes an atom is pulled.
296 */
Chenjie Yub038b702017-12-18 15:15:34 -0800297 void notePull(int pullAtomId);
298
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700299 /*
300 * Notes an atom is served from puller cache.
301 */
Chenjie Yub038b702017-12-18 15:15:34 -0800302 void notePullFromCache(int pullAtomId);
303
Yangster-mac892f3d32018-05-02 14:16:48 -0700304 /*
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700305 * Notify data error for pulled atom.
306 */
307 void notePullDataError(int pullAtomId);
308
309 /*
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700310 * Records time for actual pulling, not including those served from cache and not including
311 * statsd processing delays.
312 */
313 void notePullTime(int pullAtomId, int64_t pullTimeNs);
314
315 /*
316 * Records pull delay for a pulled atom, including those served from cache and including statsd
317 * processing delays.
318 */
319 void notePullDelay(int pullAtomId, int64_t pullDelayNs);
320
321 /*
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800322 * Records pull exceeds timeout for the puller.
323 */
324 void notePullTimeout(int pullAtomId);
325
326 /*
327 * Records pull exceeds max delay for a metric.
328 */
329 void notePullExceedMaxDelay(int pullAtomId);
330
331 /*
Yao Chena80e5c02018-09-04 13:55:29 -0700332 * Records when system server restarts.
333 */
Yangster-mac892f3d32018-05-02 14:16:48 -0700334 void noteSystemServerRestart(int32_t timeSec);
335
Yao Chen884c8c12018-01-26 10:36:25 -0800336 /**
Yangster-macb8382a12018-04-04 10:39:12 -0700337 * Records statsd skipped an event.
338 */
Yao Chen49d7dd72019-03-26 14:02:11 -0700339 void noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError,
340 int32_t lastAtomTag, int32_t uid, int32_t pid);
Yangster-macb8382a12018-04-04 10:39:12 -0700341
342 /**
Misha Wagner1eee2212019-01-22 11:47:11 +0000343 * Records that the pull of an atom has failed
344 */
345 void notePullFailed(int atomId);
346
347 /**
348 * Records that the pull of StatsCompanionService atom has failed
349 */
350 void noteStatsCompanionPullFailed(int atomId);
351
352 /**
353 * Records that the pull of a StatsCompanionService atom has failed due to a failed binder
354 * transaction. This can happen when StatsCompanionService returns too
355 * much data (the max Binder parcel size is 1MB)
356 */
357 void noteStatsCompanionPullBinderTransactionFailed(int atomId);
358
359 /**
360 * A pull with no data occurred
361 */
362 void noteEmptyData(int atomId);
363
364 /**
Tej Singha0c89dd2019-01-25 16:39:18 -0800365 * Records that a puller callback for the given atomId was registered or unregistered.
366 *
367 * @param registered True if the callback was registered, false if was unregistered.
368 */
369 void notePullerCallbackRegistrationChanged(int atomId, bool registered);
370
371 /**
Misha Wagner1eee2212019-01-22 11:47:11 +0000372 * Hard limit was reached in the cardinality of an atom
373 */
Olivier Gaillard2310b192019-02-08 10:23:05 +0000374 void noteHardDimensionLimitReached(int64_t metricId);
Misha Wagner1eee2212019-01-22 11:47:11 +0000375
376 /**
377 * A log event was too late, arrived in the wrong bucket and was skipped
378 */
Olivier Gaillard2310b192019-02-08 10:23:05 +0000379 void noteLateLogEventSkipped(int64_t metricId);
Misha Wagner1eee2212019-01-22 11:47:11 +0000380
381 /**
382 * Buckets were skipped as time elapsed without any data for them
383 */
Olivier Gaillard2310b192019-02-08 10:23:05 +0000384 void noteSkippedForwardBuckets(int64_t metricId);
Misha Wagner1eee2212019-01-22 11:47:11 +0000385
386 /**
387 * An unsupported value type was received
388 */
Olivier Gaillard2310b192019-02-08 10:23:05 +0000389 void noteBadValueType(int64_t metricId);
Misha Wagner1eee2212019-01-22 11:47:11 +0000390
391 /**
Olivier Gaillard320952b2019-02-06 13:57:24 +0000392 * Buckets were dropped due to reclaim memory.
393 */
Olivier Gaillard2310b192019-02-08 10:23:05 +0000394 void noteBucketDropped(int64_t metricId);
Olivier Gaillard320952b2019-02-06 13:57:24 +0000395
396 /**
Misha Wagner1eee2212019-01-22 11:47:11 +0000397 * A condition change was too late, arrived in the wrong bucket and was skipped
398 */
Olivier Gaillard2310b192019-02-08 10:23:05 +0000399 void noteConditionChangeInNextBucket(int64_t metricId);
Misha Wagner1eee2212019-01-22 11:47:11 +0000400
401 /**
Olivier Gaillard9a5d3592019-02-05 15:12:39 +0000402 * A bucket has been tagged as invalid.
403 */
Olivier Gaillard2310b192019-02-08 10:23:05 +0000404 void noteInvalidatedBucket(int64_t metricId);
Olivier Gaillard9a5d3592019-02-05 15:12:39 +0000405
406 /**
Olivier Gaillardf248c0d2019-02-21 15:56:58 +0000407 * Tracks the total number of buckets (include skipped/invalid buckets).
408 */
409 void noteBucketCount(int64_t metricId);
410
411 /**
Olivier Gaillard3ba2e932019-02-08 14:25:35 +0000412 * For pulls at bucket boundaries, it represents the misalignment between the real timestamp and
413 * the end of the bucket.
414 */
415 void noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs);
416
417 /**
Olivier Gaillarde63d9e02019-02-12 14:43:59 +0000418 * Number of buckets with unknown condition.
419 */
420 void noteBucketUnknownCondition(int64_t metricId);
421
422 /**
Yao Chenb3561512017-11-21 18:07:17 -0800423 * Reset the historical stats. Including all stats in icebox, and the tracked stats about
424 * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
425 * to collect stats after reset() has been called.
426 */
427 void reset();
428
429 /**
430 * Output the stats in protobuf binary format to [buffer].
431 *
432 * [reset]: whether to clear the historical stats after the call.
433 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800434 void dumpStats(std::vector<uint8_t>* buffer, bool reset);
Yao Chenb3561512017-11-21 18:07:17 -0800435
Yao Chenf5acabe2018-01-17 14:10:34 -0800436 /**
Yao Chena80e5c02018-09-04 13:55:29 -0700437 * Output statsd stats in human readable format to [out] file descriptor.
Yao Chenf5acabe2018-01-17 14:10:34 -0800438 */
Yao Chena80e5c02018-09-04 13:55:29 -0700439 void dumpStats(int outFd) const;
Yao Chenf5acabe2018-01-17 14:10:34 -0800440
Chenjie Yub038b702017-12-18 15:15:34 -0800441 typedef struct {
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700442 long totalPull = 0;
443 long totalPullFromCache = 0;
444 long minPullIntervalSec = LONG_MAX;
445 int64_t avgPullTimeNs = 0;
446 int64_t maxPullTimeNs = 0;
447 long numPullTime = 0;
448 int64_t avgPullDelayNs = 0;
449 int64_t maxPullDelayNs = 0;
450 long numPullDelay = 0;
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700451 long dataError = 0;
Chenjie Yu0bd73db2018-12-16 07:37:04 -0800452 long pullTimeout = 0;
453 long pullExceedMaxDelay = 0;
Misha Wagner1eee2212019-01-22 11:47:11 +0000454 long pullFailed = 0;
455 long statsCompanionPullFailed = 0;
456 long statsCompanionPullBinderTransactionFailed = 0;
457 long emptyData = 0;
Tej Singha0c89dd2019-01-25 16:39:18 -0800458 long registeredCount = 0;
459 long unregisteredCount = 0;
Chenjie Yub038b702017-12-18 15:15:34 -0800460 } PulledAtomStats;
461
Misha Wagner1eee2212019-01-22 11:47:11 +0000462 typedef struct {
463 long hardDimensionLimitReached = 0;
464 long lateLogEventSkipped = 0;
465 long skippedForwardBuckets = 0;
466 long badValueType = 0;
467 long conditionChangeInNextBucket = 0;
Olivier Gaillard9a5d3592019-02-05 15:12:39 +0000468 long invalidatedBucket = 0;
Olivier Gaillard320952b2019-02-06 13:57:24 +0000469 long bucketDropped = 0;
Olivier Gaillard3ba2e932019-02-08 14:25:35 +0000470 int64_t minBucketBoundaryDelayNs = 0;
471 int64_t maxBucketBoundaryDelayNs = 0;
Olivier Gaillarde63d9e02019-02-12 14:43:59 +0000472 long bucketUnknownCondition = 0;
Olivier Gaillardf248c0d2019-02-21 15:56:58 +0000473 long bucketCount = 0;
Misha Wagner1eee2212019-01-22 11:47:11 +0000474 } AtomMetricStats;
475
Yao Chenb3561512017-11-21 18:07:17 -0800476private:
477 StatsdStats();
478
479 mutable std::mutex mLock;
480
Yao Chen69f1baf2017-11-27 17:25:36 -0800481 int32_t mStartTimeSec;
Yao Chenb3561512017-11-21 18:07:17 -0800482
David Chenc136f452017-11-27 11:52:26 -0800483 // Track the number of dropped entries used by the uid map.
Yao Chen20e9e622018-02-28 11:18:51 -0800484 UidMapStats mUidMapStats;
David Chenc136f452017-11-27 11:52:26 -0800485
Yao Chenb3561512017-11-21 18:07:17 -0800486 // The stats about the configs that are still in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800487 // The map size is capped by kMaxConfigCount.
Yao Chen20e9e622018-02-28 11:18:51 -0800488 std::map<const ConfigKey, std::shared_ptr<ConfigStats>> mConfigStats;
Yao Chenb3561512017-11-21 18:07:17 -0800489
490 // Stores the stats for the configs that are no longer in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800491 // The size of the vector is capped by kMaxIceBoxSize.
Yao Chen20e9e622018-02-28 11:18:51 -0800492 std::list<const std::shared_ptr<ConfigStats>> mIceBox;
Yao Chenb3561512017-11-21 18:07:17 -0800493
494 // Stores the number of times a pushed atom is logged.
495 // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
496 // out of that range will be dropped (it's either pulled atoms or test atoms).
497 // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
498 std::vector<int> mPushedAtomStats;
499
Yao Chenf6723df2018-01-08 15:11:58 -0800500 // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
Chenjie Yub038b702017-12-18 15:15:34 -0800501 std::map<int, PulledAtomStats> mPulledAtomStats;
502
Misha Wagner1eee2212019-01-22 11:47:11 +0000503 // Maps metric ID to its stats. The size is capped by the number of metrics.
Olivier Gaillardf48fb042019-02-13 11:03:20 +0000504 std::map<int64_t, AtomMetricStats> mAtomMetricStats;
Misha Wagner1eee2212019-01-22 11:47:11 +0000505
Yao Chen39b67992018-11-08 15:32:17 -0800506 struct LogLossStats {
Yao Chen49d7dd72019-03-26 14:02:11 -0700507 LogLossStats(int32_t sec, int32_t count, int32_t error, int32_t tag, int32_t uid,
508 int32_t pid)
509 : mWallClockSec(sec),
510 mCount(count),
511 mLastError(error),
512 mLastTag(tag),
513 mUid(uid),
514 mPid(pid) {
Yao Chen39b67992018-11-08 15:32:17 -0800515 }
516 int32_t mWallClockSec;
517 int32_t mCount;
518 // error code defined in linux/errno.h
519 int32_t mLastError;
Yao Chen49d7dd72019-03-26 14:02:11 -0700520 int32_t mLastTag;
521 int32_t mUid;
522 int32_t mPid;
Yao Chen39b67992018-11-08 15:32:17 -0800523 };
524
Yao Chen3ff3a492018-08-06 16:17:37 -0700525 // Timestamps when we detect log loss, and the number of logs lost.
Yao Chen39b67992018-11-08 15:32:17 -0800526 std::list<LogLossStats> mLogLossStats;
Yangster-macb8382a12018-04-04 10:39:12 -0700527
Yangster-mac892f3d32018-05-02 14:16:48 -0700528 std::list<int32_t> mSystemServerRestartSec;
529
Bookatz1d0136d2017-12-01 11:13:32 -0800530 // Stores the number of times statsd modified the anomaly alarm registered with
531 // StatsCompanionService.
532 int mAnomalyAlarmRegisteredStats = 0;
533
Yangster-mac932ecec2018-02-01 10:23:52 -0800534 // Stores the number of times statsd registers the periodic alarm changes
535 int mPeriodicAlarmRegisteredStats = 0;
536
Yangster-macb142cc82018-03-30 15:22:08 -0700537 void noteConfigResetInternalLocked(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -0800538
539 void noteConfigRemovedInternalLocked(const ConfigKey& key);
540
541 void resetInternalLocked();
542
Chenjie Yuc3c30c02018-10-26 09:48:07 -0700543 void noteDataDropped(const ConfigKey& key, const size_t totalBytes, int32_t timeSec);
Yao Chen0fac5b12017-11-28 16:07:02 -0800544
Yangster-mace68f3a52018-04-04 00:01:43 -0700545 void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, int32_t timeSec);
Yao Chen0fac5b12017-11-28 16:07:02 -0800546
547 void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
548
Tej Singh6ede28b2019-01-29 17:06:54 -0800549 void noteActiveStatusChanged(const ConfigKey& key, bool activate, int32_t timeSec);
550
Yao Chen20e9e622018-02-28 11:18:51 -0800551 void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
Yao Chenf6723df2018-01-08 15:11:58 -0800552
Misha Wagner1eee2212019-01-22 11:47:11 +0000553 /**
554 * Get a reference to AtomMetricStats for a metric. If none exists, create it. The reference
555 * will live as long as `this`.
556 */
Olivier Gaillardf48fb042019-02-13 11:03:20 +0000557 StatsdStats::AtomMetricStats& getAtomMetricStats(int64_t metricId);
Misha Wagner1eee2212019-01-22 11:47:11 +0000558
Yao Chen69f1baf2017-11-27 17:25:36 -0800559 FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
560 FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
561 FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
562 FRIEND_TEST(StatsdStatsTest, TestSubStats);
563 FRIEND_TEST(StatsdStatsTest, TestAtomLog);
Yao Chen0fac5b12017-11-28 16:07:02 -0800564 FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
Bookatz1d0136d2017-12-01 11:13:32 -0800565 FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
Yangster-mac892f3d32018-05-02 14:16:48 -0700566 FRIEND_TEST(StatsdStatsTest, TestSystemServerCrash);
Chenjie Yu48ed1cc2018-10-31 17:36:38 -0700567 FRIEND_TEST(StatsdStatsTest, TestPullAtomStats);
Olivier Gaillarde3e969c2019-02-11 11:22:51 +0000568 FRIEND_TEST(StatsdStatsTest, TestAtomMetricsStats);
Yao Chenb3561512017-11-21 18:07:17 -0800569};
570
571} // namespace statsd
572} // namespace os
Stefan Lafonc6f2fa22018-01-04 22:03:29 -0800573} // namespace android