blob: c3f401324454c89c5afae6b54359cde0edf8058d [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"
Yao Chen9c1debe2018-02-19 14:39:19 -080019#include "frameworks/base/cmds/statsd/src/stats_log_common.pb.h"
Chenjie Yub038b702017-12-18 15:15:34 -080020#include "statslog.h"
Yao Chenb3561512017-11-21 18:07:17 -080021
Yao Chen69f1baf2017-11-27 17:25:36 -080022#include <gtest/gtest_prod.h>
David Chend9269e22017-12-05 13:43:51 -080023#include <log/log_time.h>
Yao Chenf6723df2018-01-08 15:11:58 -080024#include <list>
Yao Chenb3561512017-11-21 18:07:17 -080025#include <mutex>
26#include <string>
27#include <vector>
28
29namespace android {
30namespace os {
31namespace statsd {
32
Yao Chen20e9e622018-02-28 11:18:51 -080033struct ConfigStats {
34 int32_t uid;
35 int64_t id;
36 int32_t creation_time_sec;
37 int32_t deletion_time_sec = 0;
38 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;
46 std::list<int32_t> dump_report_time_sec;
47
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
61 // Stores the number of times an anomaly detection alert has been declared.
62 // The map size is capped by kMaxConfigCount.
63 std::map<const int64_t, int> alert_stats;
64};
65
66struct UidMapStats {
67 int32_t snapshots;
68 int32_t changes;
69 int32_t bytes_used;
70 int32_t dropped_snapshots;
71 int32_t dropped_changes;
72};
73
Yao Chenb3561512017-11-21 18:07:17 -080074// Keeps track of stats of statsd.
Yao Chen20e9e622018-02-28 11:18:51 -080075// Single instance shared across the process. All public methods are thread safe.
Yao Chenb3561512017-11-21 18:07:17 -080076class StatsdStats {
77public:
78 static StatsdStats& getInstance();
79 ~StatsdStats(){};
80
81 // TODO: set different limit if the device is low ram.
82 const static int kDimensionKeySizeSoftLimit = 300;
83 const static int kDimensionKeySizeHardLimit = 500;
84
85 const static int kMaxConfigCount = 10;
Bookatz1476ef22018-02-13 12:26:01 -080086 const static int kMaxAlertCountPerConfig = 100;
Yao Chenb3561512017-11-21 18:07:17 -080087 const static int kMaxConditionCountPerConfig = 200;
88 const static int kMaxMetricCountPerConfig = 300;
89 const static int kMaxMatcherCountPerConfig = 500;
90
Yao Chenf6723df2018-01-08 15:11:58 -080091 // The max number of old config stats we keep.
92 const static int kMaxIceBoxSize = 20;
93
Yao Chen884c8c12018-01-26 10:36:25 -080094 const static int kMaxLoggerErrors = 10;
95
Yao Chen0fac5b12017-11-28 16:07:02 -080096 const static int kMaxTimestampCount = 20;
97
Yao Chend10f7b12017-12-18 12:53:50 -080098 const static int kMaxLogSourceCount = 50;
99
David Chend9269e22017-12-05 13:43:51 -0800100 // Max memory allowed for storing metrics per configuration. When this limit is approached,
101 // statsd will send a broadcast so that the client can fetch the data and clear this memory.
102 static const size_t kMaxMetricsBytesPerConfig = 128 * 1024;
103
David Chenc136f452017-11-27 11:52:26 -0800104 // Cap the UID map's memory usage to this. This should be fairly high since the UID information
105 // is critical for understanding the metrics.
106 const static size_t kMaxBytesUsedUidMap = 50 * 1024;
107
David Chend9269e22017-12-05 13:43:51 -0800108 /* Minimum period between two broadcasts in nanoseconds. */
109 static const unsigned long long kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
110
111 /* Min period between two checks of byte size per config key in nanoseconds. */
112 static const unsigned long long kMinByteSizeCheckPeriodNs = 10 * NS_PER_SEC;
113
Chenjie Yub038b702017-12-18 15:15:34 -0800114 // Default minimum interval between pulls for an atom. Pullers can return cached values if
115 // another pull request happens within this interval.
116 static std::map<int, long> kPullerCooldownMap;
117
118 // Default cooldown time for a puller
119 static const long kDefaultPullerCooldown = 1;
120
yro98a28502018-01-18 17:00:14 -0800121 // Maximum age (30 days) that files on disk can exist in seconds.
122 static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
123
124 // Maximum number of files (1000) that can be in stats directory on disk.
125 static const int kMaxFileNumber = 1000;
126
127 // Maximum size of all files that can be written to stats directory on disk.
128 static const int kMaxFileSize = 50 * 1024 * 1024;
129
Chenjie Yufa22d652018-02-05 14:37:48 -0800130 // How long to try to clear puller cache from last time
131 static const long kPullerCacheClearIntervalSec = 1;
132
Yao Chenb3561512017-11-21 18:07:17 -0800133 /**
134 * Report a new config has been received and report the static stats about the config.
135 *
136 * The static stats include: the count of metrics, conditions, matchers, and alerts.
137 * If the config is not valid, this config stats will be put into icebox immediately.
138 */
139 void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
140 int matchersCount, int alertCount, bool isValid);
141 /**
142 * Report a config has been removed.
143 */
144 void noteConfigRemoved(const ConfigKey& key);
145
146 /**
147 * Report a broadcast has been sent to a config owner to collect the data.
148 */
149 void noteBroadcastSent(const ConfigKey& key);
150
151 /**
152 * Report a config's metrics data has been dropped.
153 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800154 void noteDataDropped(const ConfigKey& key);
155
156 /**
157 * Report metrics data report has been sent.
158 *
159 * The report may be requested via StatsManager API, or through adb cmd.
160 */
161 void noteMetricsReportSent(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -0800162
163 /**
164 * Report the size of output tuple of a condition.
165 *
166 * Note: only report when the condition has an output dimension, and the tuple
167 * count > kDimensionKeySizeSoftLimit.
168 *
169 * [key]: The config key that this condition belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800170 * [id]: The id of the condition.
Yao Chenb3561512017-11-21 18:07:17 -0800171 * [size]: The output tuple size.
172 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800173 void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800174
175 /**
176 * Report the size of output tuple of a metric.
177 *
178 * Note: only report when the metric has an output dimension, and the tuple
179 * count > kDimensionKeySizeSoftLimit.
180 *
181 * [key]: The config key that this metric belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800182 * [id]: The id of the metric.
Yao Chenb3561512017-11-21 18:07:17 -0800183 * [size]: The output tuple size.
184 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800185 void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800186
187 /**
188 * Report a matcher has been matched.
189 *
190 * [key]: The config key that this matcher belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800191 * [id]: The id of the matcher.
Yao Chenb3561512017-11-21 18:07:17 -0800192 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800193 void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
Yao Chenb3561512017-11-21 18:07:17 -0800194
195 /**
Bookatz8f2f3d82017-12-07 13:53:21 -0800196 * Report that an anomaly detection alert has been declared.
197 *
198 * [key]: The config key that this alert belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800199 * [id]: The id of the alert.
Bookatz8f2f3d82017-12-07 13:53:21 -0800200 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800201 void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
Bookatz8f2f3d82017-12-07 13:53:21 -0800202
203 /**
Yao Chenb3561512017-11-21 18:07:17 -0800204 * Report an atom event has been logged.
205 */
206 void noteAtomLogged(int atomId, int32_t timeSec);
207
208 /**
Bookatz1d0136d2017-12-01 11:13:32 -0800209 * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
210 */
211 void noteRegisteredAnomalyAlarmChanged();
212
213 /**
Yangster-mac932ecec2018-02-01 10:23:52 -0800214 * Report that statsd modified the periodic alarm registered with StatsCompanionService.
215 */
216 void noteRegisteredPeriodicAlarmChanged();
217
218 /**
David Chenc136f452017-11-27 11:52:26 -0800219 * Records the number of snapshot and delta entries that are being dropped from the uid map.
220 */
221 void noteUidMapDropped(int snapshots, int deltas);
222
223 /**
224 * Updates the number of snapshots currently stored in the uid map.
225 */
226 void setUidMapSnapshots(int snapshots);
227 void setUidMapChanges(int changes);
228 void setCurrentUidMapMemory(int bytes);
229
Chenjie Yub038b702017-12-18 15:15:34 -0800230 // Update minimum interval between pulls for an pulled atom
231 void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
232
233 // Notify pull request for an atom
234 void notePull(int pullAtomId);
235
236 // Notify pull request for an atom served from cached data
237 void notePullFromCache(int pullAtomId);
238
David Chenc136f452017-11-27 11:52:26 -0800239 /**
Yao Chen884c8c12018-01-26 10:36:25 -0800240 * Records statsd met an error while reading from logd.
241 */
242 void noteLoggerError(int error);
243
244 /**
Yao Chenb3561512017-11-21 18:07:17 -0800245 * Reset the historical stats. Including all stats in icebox, and the tracked stats about
246 * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
247 * to collect stats after reset() has been called.
248 */
249 void reset();
250
251 /**
252 * Output the stats in protobuf binary format to [buffer].
253 *
254 * [reset]: whether to clear the historical stats after the call.
255 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800256 void dumpStats(std::vector<uint8_t>* buffer, bool reset);
Yao Chenb3561512017-11-21 18:07:17 -0800257
Yao Chenf5acabe2018-01-17 14:10:34 -0800258 /**
259 * Output statsd stats in human readable format to [out] file.
260 */
261 void dumpStats(FILE* out) const;
262
Chenjie Yub038b702017-12-18 15:15:34 -0800263 typedef struct {
264 long totalPull;
265 long totalPullFromCache;
266 long minPullIntervalSec;
267 } PulledAtomStats;
268
Yao Chenb3561512017-11-21 18:07:17 -0800269private:
270 StatsdStats();
271
272 mutable std::mutex mLock;
273
Yao Chen69f1baf2017-11-27 17:25:36 -0800274 int32_t mStartTimeSec;
Yao Chenb3561512017-11-21 18:07:17 -0800275
David Chenc136f452017-11-27 11:52:26 -0800276 // Track the number of dropped entries used by the uid map.
Yao Chen20e9e622018-02-28 11:18:51 -0800277 UidMapStats mUidMapStats;
David Chenc136f452017-11-27 11:52:26 -0800278
Yao Chenb3561512017-11-21 18:07:17 -0800279 // The stats about the configs that are still in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800280 // The map size is capped by kMaxConfigCount.
Yao Chen20e9e622018-02-28 11:18:51 -0800281 std::map<const ConfigKey, std::shared_ptr<ConfigStats>> mConfigStats;
Yao Chenb3561512017-11-21 18:07:17 -0800282
283 // Stores the stats for the configs that are no longer in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800284 // The size of the vector is capped by kMaxIceBoxSize.
Yao Chen20e9e622018-02-28 11:18:51 -0800285 std::list<const std::shared_ptr<ConfigStats>> mIceBox;
Yao Chenb3561512017-11-21 18:07:17 -0800286
287 // Stores the number of times a pushed atom is logged.
288 // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
289 // out of that range will be dropped (it's either pulled atoms or test atoms).
290 // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
291 std::vector<int> mPushedAtomStats;
292
Yao Chenf6723df2018-01-08 15:11:58 -0800293 // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
Chenjie Yub038b702017-12-18 15:15:34 -0800294 std::map<int, PulledAtomStats> mPulledAtomStats;
295
Yao Chen884c8c12018-01-26 10:36:25 -0800296 // Logd errors. Size capped by kMaxLoggerErrors.
297 std::list<const std::pair<int, int>> mLoggerErrors;
298
Bookatz1d0136d2017-12-01 11:13:32 -0800299 // Stores the number of times statsd modified the anomaly alarm registered with
300 // StatsCompanionService.
301 int mAnomalyAlarmRegisteredStats = 0;
302
Yangster-mac932ecec2018-02-01 10:23:52 -0800303 // Stores the number of times statsd registers the periodic alarm changes
304 int mPeriodicAlarmRegisteredStats = 0;
305
Yao Chenb3561512017-11-21 18:07:17 -0800306
307 void noteConfigRemovedInternalLocked(const ConfigKey& key);
308
309 void resetInternalLocked();
310
Yao Chen0fac5b12017-11-28 16:07:02 -0800311 void noteDataDropped(const ConfigKey& key, int32_t timeSec);
312
313 void noteMetricsReportSent(const ConfigKey& key, int32_t timeSec);
314
315 void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
316
Yao Chen20e9e622018-02-28 11:18:51 -0800317 void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
Yao Chenf6723df2018-01-08 15:11:58 -0800318
Yao Chen69f1baf2017-11-27 17:25:36 -0800319 FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
320 FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
321 FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
322 FRIEND_TEST(StatsdStatsTest, TestSubStats);
323 FRIEND_TEST(StatsdStatsTest, TestAtomLog);
Yao Chen0fac5b12017-11-28 16:07:02 -0800324 FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
Bookatz1d0136d2017-12-01 11:13:32 -0800325 FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
Yao Chenb3561512017-11-21 18:07:17 -0800326};
327
328} // namespace statsd
329} // namespace os
Stefan Lafonc6f2fa22018-01-04 22:03:29 -0800330} // namespace android