blob: 65ba4f7b12f7e32994dc29d26259a43c5f55562e [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;
45 std::list<int32_t> data_drop_time_sec;
Yangster-mace68f3a52018-04-04 00:01:43 -070046 std::list<std::pair<int32_t, int64_t>> dump_report_stats;
Yao Chen20e9e622018-02-28 11:18:51 -080047
48 // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount.
49 std::map<const int64_t, int> matcher_stats;
50
51 // Stores the number of output tuple of condition trackers when it's bigger than
52 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
53 // it means some data has been dropped. The map size is capped by kMaxConfigCount.
54 std::map<const int64_t, int> condition_stats;
55
56 // Stores the number of output tuple of metric producers when it's bigger than
57 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
58 // it means some data has been dropped. The map size is capped by kMaxConfigCount.
59 std::map<const int64_t, int> metric_stats;
60
Yangster-mac306ccc22018-03-24 15:03:40 -070061 // Stores the max number of output tuple of dimensions in condition across dimensions in what
62 // when it's bigger than kDimensionKeySizeSoftLimit. When you see the number is
63 // kDimensionKeySizeHardLimit +1, it means some data has been dropped. The map size is capped by
64 // kMaxConfigCount.
65 std::map<const int64_t, int> metric_dimension_in_condition_stats;
66
Yao Chen20e9e622018-02-28 11:18:51 -080067 // Stores the number of times an anomaly detection alert has been declared.
68 // The map size is capped by kMaxConfigCount.
69 std::map<const int64_t, int> alert_stats;
David Chenfaa1af52018-03-30 15:14:04 -070070
71 // Stores the config ID for each sub-config used.
72 std::list<std::pair<const int64_t, const int32_t>> annotations;
Yao Chen20e9e622018-02-28 11:18:51 -080073};
74
75struct UidMapStats {
Yao Chen20e9e622018-02-28 11:18:51 -080076 int32_t changes;
77 int32_t bytes_used;
Yao Chen20e9e622018-02-28 11:18:51 -080078 int32_t dropped_changes;
David Chenbd125272018-04-04 19:02:50 -070079 int32_t deleted_apps = 0;
Yao Chen20e9e622018-02-28 11:18:51 -080080};
81
Yao Chenb3561512017-11-21 18:07:17 -080082// Keeps track of stats of statsd.
Yao Chen20e9e622018-02-28 11:18:51 -080083// Single instance shared across the process. All public methods are thread safe.
Yao Chenb3561512017-11-21 18:07:17 -080084class StatsdStats {
85public:
86 static StatsdStats& getInstance();
87 ~StatsdStats(){};
88
89 // TODO: set different limit if the device is low ram.
Yao Chen52b478b2018-03-27 10:59:45 -070090 const static int kDimensionKeySizeSoftLimit = 500;
91 const static int kDimensionKeySizeHardLimit = 800;
Yao Chenb3561512017-11-21 18:07:17 -080092
Chenjie Yuc5875052018-03-09 10:13:11 -080093 // Per atom dimension key size limit
94 static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
95
Yao Chen52b478b2018-03-27 10:59:45 -070096 const static int kMaxConfigCountPerUid = 10;
Bookatz1476ef22018-02-13 12:26:01 -080097 const static int kMaxAlertCountPerConfig = 100;
Yao Chen52b478b2018-03-27 10:59:45 -070098 const static int kMaxConditionCountPerConfig = 300;
99 const static int kMaxMetricCountPerConfig = 1000;
100 const static int kMaxMatcherCountPerConfig = 800;
Yao Chenb3561512017-11-21 18:07:17 -0800101
Yao Chenf6723df2018-01-08 15:11:58 -0800102 // The max number of old config stats we keep.
103 const static int kMaxIceBoxSize = 20;
104
Yao Chen163d2602018-04-10 10:39:53 -0700105 const static int kMaxLoggerErrors = 20;
Yangster-macb8382a12018-04-04 10:39:12 -0700106
Yao Chen0fac5b12017-11-28 16:07:02 -0800107 const static int kMaxTimestampCount = 20;
108
Yao Chend10f7b12017-12-18 12:53:50 -0800109 const static int kMaxLogSourceCount = 50;
110
David Chen4c6d97a2018-03-22 16:31:40 -0700111 // Max memory allowed for storing metrics per configuration. If this limit is exceeded, statsd
112 // drops the metrics data in memory.
113 static const size_t kMaxMetricsBytesPerConfig = 256 * 1024;
114
115 // Soft memory limit per configuration. Once this limit is exceeded, we begin notifying the
116 // data subscriber that it's time to call getData.
Yangster-macdb185c92018-04-19 10:54:30 -0700117 static const size_t kBytesPerConfigTriggerGetData = 192 * 1024;
David Chend9269e22017-12-05 13:43:51 -0800118
David Chenc136f452017-11-27 11:52:26 -0800119 // Cap the UID map's memory usage to this. This should be fairly high since the UID information
120 // is critical for understanding the metrics.
121 const static size_t kMaxBytesUsedUidMap = 50 * 1024;
122
David Chenbd125272018-04-04 19:02:50 -0700123 // The number of deleted apps that are stored in the uid map.
124 const static int kMaxDeletedAppsInUidMap = 100;
125
David Chend9269e22017-12-05 13:43:51 -0800126 /* Minimum period between two broadcasts in nanoseconds. */
Yangster-macb142cc82018-03-30 15:22:08 -0700127 static const int64_t kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
David Chend9269e22017-12-05 13:43:51 -0800128
129 /* Min period between two checks of byte size per config key in nanoseconds. */
Yangster-macb142cc82018-03-30 15:22:08 -0700130 static const int64_t kMinByteSizeCheckPeriodNs = 10 * NS_PER_SEC;
David Chend9269e22017-12-05 13:43:51 -0800131
yro98a28502018-01-18 17:00:14 -0800132 // Maximum age (30 days) that files on disk can exist in seconds.
133 static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
134
135 // Maximum number of files (1000) that can be in stats directory on disk.
136 static const int kMaxFileNumber = 1000;
137
138 // Maximum size of all files that can be written to stats directory on disk.
139 static const int kMaxFileSize = 50 * 1024 * 1024;
140
Chenjie Yufa22d652018-02-05 14:37:48 -0800141 // How long to try to clear puller cache from last time
142 static const long kPullerCacheClearIntervalSec = 1;
143
Yao Chenb3561512017-11-21 18:07:17 -0800144 /**
145 * Report a new config has been received and report the static stats about the config.
146 *
147 * The static stats include: the count of metrics, conditions, matchers, and alerts.
148 * If the config is not valid, this config stats will be put into icebox immediately.
149 */
150 void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
David Chenfaa1af52018-03-30 15:14:04 -0700151 int matchersCount, int alertCount,
152 const std::list<std::pair<const int64_t, const int32_t>>& annotations,
153 bool isValid);
Yao Chenb3561512017-11-21 18:07:17 -0800154 /**
155 * Report a config has been removed.
156 */
157 void noteConfigRemoved(const ConfigKey& key);
Yangster-macb142cc82018-03-30 15:22:08 -0700158 /**
159 * Report a config has been reset when ttl expires.
160 */
161 void noteConfigReset(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -0800162
163 /**
164 * Report a broadcast has been sent to a config owner to collect the data.
165 */
166 void noteBroadcastSent(const ConfigKey& key);
167
168 /**
169 * Report a config's metrics data has been dropped.
170 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800171 void noteDataDropped(const ConfigKey& key);
172
173 /**
174 * Report metrics data report has been sent.
175 *
176 * The report may be requested via StatsManager API, or through adb cmd.
177 */
Yangster-mace68f3a52018-04-04 00:01:43 -0700178 void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes);
Yao Chenb3561512017-11-21 18:07:17 -0800179
180 /**
181 * Report the size of output tuple of a condition.
182 *
183 * Note: only report when the condition has an output dimension, and the tuple
184 * count > kDimensionKeySizeSoftLimit.
185 *
186 * [key]: The config key that this condition belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800187 * [id]: The id of the condition.
Yao Chenb3561512017-11-21 18:07:17 -0800188 * [size]: The output tuple size.
189 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800190 void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800191
192 /**
193 * Report the size of output tuple of a metric.
194 *
195 * Note: only report when the metric has an output dimension, and the tuple
196 * count > kDimensionKeySizeSoftLimit.
197 *
198 * [key]: The config key that this metric belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800199 * [id]: The id of the metric.
Yao Chenb3561512017-11-21 18:07:17 -0800200 * [size]: The output tuple size.
201 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800202 void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800203
Yangster-mac306ccc22018-03-24 15:03:40 -0700204
205 /**
206 * Report the max size of output tuple of dimension in condition across dimensions in what.
207 *
208 * Note: only report when the metric has an output dimension in condition, and the max tuple
209 * count > kDimensionKeySizeSoftLimit.
210 *
211 * [key]: The config key that this metric belongs to.
212 * [id]: The id of the metric.
213 * [size]: The output tuple size.
214 */
215 void noteMetricDimensionInConditionSize(const ConfigKey& key, const int64_t& id, int size);
216
Yao Chenb3561512017-11-21 18:07:17 -0800217 /**
218 * Report a matcher has been matched.
219 *
220 * [key]: The config key that this matcher belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800221 * [id]: The id of the matcher.
Yao Chenb3561512017-11-21 18:07:17 -0800222 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800223 void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
Yao Chenb3561512017-11-21 18:07:17 -0800224
225 /**
Bookatz8f2f3d82017-12-07 13:53:21 -0800226 * Report that an anomaly detection alert has been declared.
227 *
228 * [key]: The config key that this alert belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800229 * [id]: The id of the alert.
Bookatz8f2f3d82017-12-07 13:53:21 -0800230 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800231 void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
Bookatz8f2f3d82017-12-07 13:53:21 -0800232
233 /**
Yao Chenb3561512017-11-21 18:07:17 -0800234 * Report an atom event has been logged.
235 */
236 void noteAtomLogged(int atomId, int32_t timeSec);
237
238 /**
Bookatz1d0136d2017-12-01 11:13:32 -0800239 * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
240 */
241 void noteRegisteredAnomalyAlarmChanged();
242
243 /**
Yangster-mac932ecec2018-02-01 10:23:52 -0800244 * Report that statsd modified the periodic alarm registered with StatsCompanionService.
245 */
246 void noteRegisteredPeriodicAlarmChanged();
247
248 /**
David Chenbd125272018-04-04 19:02:50 -0700249 * Records the number of delta entries that are being dropped from the uid map.
David Chenc136f452017-11-27 11:52:26 -0800250 */
David Chenbd125272018-04-04 19:02:50 -0700251 void noteUidMapDropped(int deltas);
David Chenc136f452017-11-27 11:52:26 -0800252
253 /**
David Chenbd125272018-04-04 19:02:50 -0700254 * Records that an app was deleted (from statsd's map).
David Chenc136f452017-11-27 11:52:26 -0800255 */
David Chenbd125272018-04-04 19:02:50 -0700256 void noteUidMapAppDeletionDropped();
257
258 /**
259 * Updates the number of changes currently stored in the uid map.
260 */
David Chenc136f452017-11-27 11:52:26 -0800261 void setUidMapChanges(int changes);
262 void setCurrentUidMapMemory(int bytes);
263
Chenjie Yub038b702017-12-18 15:15:34 -0800264 // Update minimum interval between pulls for an pulled atom
265 void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
266
267 // Notify pull request for an atom
268 void notePull(int pullAtomId);
269
270 // Notify pull request for an atom served from cached data
271 void notePullFromCache(int pullAtomId);
272
David Chenc136f452017-11-27 11:52:26 -0800273 /**
Yao Chen884c8c12018-01-26 10:36:25 -0800274 * Records statsd met an error while reading from logd.
275 */
276 void noteLoggerError(int error);
277
278 /**
Yangster-macb8382a12018-04-04 10:39:12 -0700279 * Records statsd skipped an event.
280 */
Yao Chen163d2602018-04-10 10:39:53 -0700281 void noteLogLost(int64_t timestamp);
Yangster-macb8382a12018-04-04 10:39:12 -0700282
283 /**
Yao Chenb3561512017-11-21 18:07:17 -0800284 * Reset the historical stats. Including all stats in icebox, and the tracked stats about
285 * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
286 * to collect stats after reset() has been called.
287 */
288 void reset();
289
290 /**
291 * Output the stats in protobuf binary format to [buffer].
292 *
293 * [reset]: whether to clear the historical stats after the call.
294 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800295 void dumpStats(std::vector<uint8_t>* buffer, bool reset);
Yao Chenb3561512017-11-21 18:07:17 -0800296
Yao Chenf5acabe2018-01-17 14:10:34 -0800297 /**
298 * Output statsd stats in human readable format to [out] file.
299 */
300 void dumpStats(FILE* out) const;
301
Chenjie Yub038b702017-12-18 15:15:34 -0800302 typedef struct {
303 long totalPull;
304 long totalPullFromCache;
305 long minPullIntervalSec;
306 } PulledAtomStats;
307
Yao Chenb3561512017-11-21 18:07:17 -0800308private:
309 StatsdStats();
310
311 mutable std::mutex mLock;
312
Yao Chen69f1baf2017-11-27 17:25:36 -0800313 int32_t mStartTimeSec;
Yao Chenb3561512017-11-21 18:07:17 -0800314
David Chenc136f452017-11-27 11:52:26 -0800315 // Track the number of dropped entries used by the uid map.
Yao Chen20e9e622018-02-28 11:18:51 -0800316 UidMapStats mUidMapStats;
David Chenc136f452017-11-27 11:52:26 -0800317
Yao Chenb3561512017-11-21 18:07:17 -0800318 // The stats about the configs that are still in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800319 // The map size is capped by kMaxConfigCount.
Yao Chen20e9e622018-02-28 11:18:51 -0800320 std::map<const ConfigKey, std::shared_ptr<ConfigStats>> mConfigStats;
Yao Chenb3561512017-11-21 18:07:17 -0800321
322 // Stores the stats for the configs that are no longer in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800323 // The size of the vector is capped by kMaxIceBoxSize.
Yao Chen20e9e622018-02-28 11:18:51 -0800324 std::list<const std::shared_ptr<ConfigStats>> mIceBox;
Yao Chenb3561512017-11-21 18:07:17 -0800325
326 // Stores the number of times a pushed atom is logged.
327 // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
328 // out of that range will be dropped (it's either pulled atoms or test atoms).
329 // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
330 std::vector<int> mPushedAtomStats;
331
Yao Chenf6723df2018-01-08 15:11:58 -0800332 // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
Chenjie Yub038b702017-12-18 15:15:34 -0800333 std::map<int, PulledAtomStats> mPulledAtomStats;
334
Yao Chen884c8c12018-01-26 10:36:25 -0800335 // Logd errors. Size capped by kMaxLoggerErrors.
336 std::list<const std::pair<int, int>> mLoggerErrors;
337
Yao Chen163d2602018-04-10 10:39:53 -0700338 // Timestamps when we detect log loss after logd reconnect.
339 std::list<int64_t> mLogLossTimestampNs;
Yangster-macb8382a12018-04-04 10:39:12 -0700340
Bookatz1d0136d2017-12-01 11:13:32 -0800341 // Stores the number of times statsd modified the anomaly alarm registered with
342 // StatsCompanionService.
343 int mAnomalyAlarmRegisteredStats = 0;
344
Yangster-mac932ecec2018-02-01 10:23:52 -0800345 // Stores the number of times statsd registers the periodic alarm changes
346 int mPeriodicAlarmRegisteredStats = 0;
347
Yangster-macb142cc82018-03-30 15:22:08 -0700348 void noteConfigResetInternalLocked(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -0800349
350 void noteConfigRemovedInternalLocked(const ConfigKey& key);
351
352 void resetInternalLocked();
353
Yao Chen0fac5b12017-11-28 16:07:02 -0800354 void noteDataDropped(const ConfigKey& key, int32_t timeSec);
355
Yangster-mace68f3a52018-04-04 00:01:43 -0700356 void noteMetricsReportSent(const ConfigKey& key, const size_t num_bytes, int32_t timeSec);
Yao Chen0fac5b12017-11-28 16:07:02 -0800357
358 void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
359
Yao Chen20e9e622018-02-28 11:18:51 -0800360 void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
Yao Chenf6723df2018-01-08 15:11:58 -0800361
Yao Chen69f1baf2017-11-27 17:25:36 -0800362 FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
363 FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
364 FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
365 FRIEND_TEST(StatsdStatsTest, TestSubStats);
366 FRIEND_TEST(StatsdStatsTest, TestAtomLog);
Yao Chen0fac5b12017-11-28 16:07:02 -0800367 FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
Bookatz1d0136d2017-12-01 11:13:32 -0800368 FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
Yao Chenb3561512017-11-21 18:07:17 -0800369};
370
371} // namespace statsd
372} // namespace os
Stefan Lafonc6f2fa22018-01-04 22:03:29 -0800373} // namespace android