blob: 8c16e4e9c2eb64fbf9400ca8b89a2becc7d9be4f [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
33// Keeps track of stats of statsd.
34// Single instance shared across the process. All methods are thread safe.
35class StatsdStats {
36public:
37 static StatsdStats& getInstance();
38 ~StatsdStats(){};
39
40 // TODO: set different limit if the device is low ram.
41 const static int kDimensionKeySizeSoftLimit = 300;
42 const static int kDimensionKeySizeHardLimit = 500;
43
44 const static int kMaxConfigCount = 10;
Bookatz1476ef22018-02-13 12:26:01 -080045 const static int kMaxAlertCountPerConfig = 100;
Yao Chenb3561512017-11-21 18:07:17 -080046 const static int kMaxConditionCountPerConfig = 200;
47 const static int kMaxMetricCountPerConfig = 300;
48 const static int kMaxMatcherCountPerConfig = 500;
49
Yao Chenf6723df2018-01-08 15:11:58 -080050 // The max number of old config stats we keep.
51 const static int kMaxIceBoxSize = 20;
52
Yao Chen884c8c12018-01-26 10:36:25 -080053 const static int kMaxLoggerErrors = 10;
54
Yao Chen0fac5b12017-11-28 16:07:02 -080055 const static int kMaxTimestampCount = 20;
56
Yao Chend10f7b12017-12-18 12:53:50 -080057 const static int kMaxLogSourceCount = 50;
58
David Chend9269e22017-12-05 13:43:51 -080059 // Max memory allowed for storing metrics per configuration. When this limit is approached,
60 // statsd will send a broadcast so that the client can fetch the data and clear this memory.
61 static const size_t kMaxMetricsBytesPerConfig = 128 * 1024;
62
David Chenc136f452017-11-27 11:52:26 -080063 // Cap the UID map's memory usage to this. This should be fairly high since the UID information
64 // is critical for understanding the metrics.
65 const static size_t kMaxBytesUsedUidMap = 50 * 1024;
66
David Chend9269e22017-12-05 13:43:51 -080067 /* Minimum period between two broadcasts in nanoseconds. */
68 static const unsigned long long kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
69
70 /* Min period between two checks of byte size per config key in nanoseconds. */
71 static const unsigned long long kMinByteSizeCheckPeriodNs = 10 * NS_PER_SEC;
72
Chenjie Yub038b702017-12-18 15:15:34 -080073 // Default minimum interval between pulls for an atom. Pullers can return cached values if
74 // another pull request happens within this interval.
75 static std::map<int, long> kPullerCooldownMap;
76
77 // Default cooldown time for a puller
78 static const long kDefaultPullerCooldown = 1;
79
yro98a28502018-01-18 17:00:14 -080080 // Maximum age (30 days) that files on disk can exist in seconds.
81 static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
82
83 // Maximum number of files (1000) that can be in stats directory on disk.
84 static const int kMaxFileNumber = 1000;
85
86 // Maximum size of all files that can be written to stats directory on disk.
87 static const int kMaxFileSize = 50 * 1024 * 1024;
88
Chenjie Yufa22d652018-02-05 14:37:48 -080089 // How long to try to clear puller cache from last time
90 static const long kPullerCacheClearIntervalSec = 1;
91
Yao Chenb3561512017-11-21 18:07:17 -080092 /**
93 * Report a new config has been received and report the static stats about the config.
94 *
95 * The static stats include: the count of metrics, conditions, matchers, and alerts.
96 * If the config is not valid, this config stats will be put into icebox immediately.
97 */
98 void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
99 int matchersCount, int alertCount, bool isValid);
100 /**
101 * Report a config has been removed.
102 */
103 void noteConfigRemoved(const ConfigKey& key);
104
105 /**
106 * Report a broadcast has been sent to a config owner to collect the data.
107 */
108 void noteBroadcastSent(const ConfigKey& key);
109
110 /**
111 * Report a config's metrics data has been dropped.
112 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800113 void noteDataDropped(const ConfigKey& key);
114
115 /**
116 * Report metrics data report has been sent.
117 *
118 * The report may be requested via StatsManager API, or through adb cmd.
119 */
120 void noteMetricsReportSent(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -0800121
122 /**
123 * Report the size of output tuple of a condition.
124 *
125 * Note: only report when the condition has an output dimension, and the tuple
126 * count > kDimensionKeySizeSoftLimit.
127 *
128 * [key]: The config key that this condition belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800129 * [id]: The id of the condition.
Yao Chenb3561512017-11-21 18:07:17 -0800130 * [size]: The output tuple size.
131 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800132 void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800133
134 /**
135 * Report the size of output tuple of a metric.
136 *
137 * Note: only report when the metric has an output dimension, and the tuple
138 * count > kDimensionKeySizeSoftLimit.
139 *
140 * [key]: The config key that this metric belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800141 * [id]: The id of the metric.
Yao Chenb3561512017-11-21 18:07:17 -0800142 * [size]: The output tuple size.
143 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800144 void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800145
146 /**
147 * Report a matcher has been matched.
148 *
149 * [key]: The config key that this matcher belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800150 * [id]: The id of the matcher.
Yao Chenb3561512017-11-21 18:07:17 -0800151 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800152 void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
Yao Chenb3561512017-11-21 18:07:17 -0800153
154 /**
Bookatz8f2f3d82017-12-07 13:53:21 -0800155 * Report that an anomaly detection alert has been declared.
156 *
157 * [key]: The config key that this alert belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800158 * [id]: The id of the alert.
Bookatz8f2f3d82017-12-07 13:53:21 -0800159 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800160 void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
Bookatz8f2f3d82017-12-07 13:53:21 -0800161
162 /**
Yao Chenb3561512017-11-21 18:07:17 -0800163 * Report an atom event has been logged.
164 */
165 void noteAtomLogged(int atomId, int32_t timeSec);
166
167 /**
Bookatz1d0136d2017-12-01 11:13:32 -0800168 * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
169 */
170 void noteRegisteredAnomalyAlarmChanged();
171
172 /**
David Chenc136f452017-11-27 11:52:26 -0800173 * Records the number of snapshot and delta entries that are being dropped from the uid map.
174 */
175 void noteUidMapDropped(int snapshots, int deltas);
176
177 /**
178 * Updates the number of snapshots currently stored in the uid map.
179 */
180 void setUidMapSnapshots(int snapshots);
181 void setUidMapChanges(int changes);
182 void setCurrentUidMapMemory(int bytes);
183
Chenjie Yub038b702017-12-18 15:15:34 -0800184 // Update minimum interval between pulls for an pulled atom
185 void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
186
187 // Notify pull request for an atom
188 void notePull(int pullAtomId);
189
190 // Notify pull request for an atom served from cached data
191 void notePullFromCache(int pullAtomId);
192
David Chenc136f452017-11-27 11:52:26 -0800193 /**
Yao Chen884c8c12018-01-26 10:36:25 -0800194 * Records statsd met an error while reading from logd.
195 */
196 void noteLoggerError(int error);
197
198 /**
Yao Chenb3561512017-11-21 18:07:17 -0800199 * Reset the historical stats. Including all stats in icebox, and the tracked stats about
200 * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
201 * to collect stats after reset() has been called.
202 */
203 void reset();
204
205 /**
206 * Output the stats in protobuf binary format to [buffer].
207 *
208 * [reset]: whether to clear the historical stats after the call.
209 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800210 void dumpStats(std::vector<uint8_t>* buffer, bool reset);
Yao Chenb3561512017-11-21 18:07:17 -0800211
Yao Chenf5acabe2018-01-17 14:10:34 -0800212 /**
213 * Output statsd stats in human readable format to [out] file.
214 */
215 void dumpStats(FILE* out) const;
216
Chenjie Yub038b702017-12-18 15:15:34 -0800217 typedef struct {
218 long totalPull;
219 long totalPullFromCache;
220 long minPullIntervalSec;
221 } PulledAtomStats;
222
Yao Chenb3561512017-11-21 18:07:17 -0800223private:
224 StatsdStats();
225
226 mutable std::mutex mLock;
227
Yao Chen69f1baf2017-11-27 17:25:36 -0800228 int32_t mStartTimeSec;
Yao Chenb3561512017-11-21 18:07:17 -0800229
David Chenc136f452017-11-27 11:52:26 -0800230 // Track the number of dropped entries used by the uid map.
231 StatsdStatsReport_UidMapStats mUidMapStats;
232
Yao Chenb3561512017-11-21 18:07:17 -0800233 // The stats about the configs that are still in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800234 // The map size is capped by kMaxConfigCount.
Yao Chenb3561512017-11-21 18:07:17 -0800235 std::map<const ConfigKey, StatsdStatsReport_ConfigStats> mConfigStats;
236
237 // Stores the stats for the configs that are no longer in use.
Yao Chenf6723df2018-01-08 15:11:58 -0800238 // The size of the vector is capped by kMaxIceBoxSize.
239 std::list<const StatsdStatsReport_ConfigStats> mIceBox;
Yao Chenb3561512017-11-21 18:07:17 -0800240
241 // Stores the number of output tuple of condition trackers when it's bigger than
242 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
Yao Chenf6723df2018-01-08 15:11:58 -0800243 // it means some data has been dropped. The map size is capped by kMaxConfigCount.
Yangster-mac94e197c2018-01-02 16:03:03 -0800244 std::map<const ConfigKey, std::map<const int64_t, int>> mConditionStats;
Yao Chenb3561512017-11-21 18:07:17 -0800245
246 // Stores the number of output tuple of metric producers when it's bigger than
247 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
Yao Chenf6723df2018-01-08 15:11:58 -0800248 // it means some data has been dropped. The map size is capped by kMaxConfigCount.
Yangster-mac94e197c2018-01-02 16:03:03 -0800249 std::map<const ConfigKey, std::map<const int64_t, int>> mMetricsStats;
Yao Chenb3561512017-11-21 18:07:17 -0800250
251 // Stores the number of times a pushed atom is logged.
252 // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
253 // out of that range will be dropped (it's either pulled atoms or test atoms).
254 // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
255 std::vector<int> mPushedAtomStats;
256
Yao Chenf6723df2018-01-08 15:11:58 -0800257 // Maps PullAtomId to its stats. The size is capped by the puller atom counts.
Chenjie Yub038b702017-12-18 15:15:34 -0800258 std::map<int, PulledAtomStats> mPulledAtomStats;
259
Yao Chen884c8c12018-01-26 10:36:25 -0800260 // Logd errors. Size capped by kMaxLoggerErrors.
261 std::list<const std::pair<int, int>> mLoggerErrors;
262
Bookatz1d0136d2017-12-01 11:13:32 -0800263 // Stores the number of times statsd modified the anomaly alarm registered with
264 // StatsCompanionService.
265 int mAnomalyAlarmRegisteredStats = 0;
266
Bookatz8f2f3d82017-12-07 13:53:21 -0800267 // Stores the number of times an anomaly detection alert has been declared
Yao Chenf6723df2018-01-08 15:11:58 -0800268 // (per config, per alert name). The map size is capped by kMaxConfigCount.
Yangster-mac94e197c2018-01-02 16:03:03 -0800269 std::map<const ConfigKey, std::map<const int64_t, int>> mAlertStats;
Bookatz8f2f3d82017-12-07 13:53:21 -0800270
Yao Chenf6723df2018-01-08 15:11:58 -0800271 // Stores how many times a matcher have been matched. The map size is capped by kMaxConfigCount.
Yangster-mac94e197c2018-01-02 16:03:03 -0800272 std::map<const ConfigKey, std::map<const int64_t, int>> mMatcherStats;
Yao Chenb3561512017-11-21 18:07:17 -0800273
274 void noteConfigRemovedInternalLocked(const ConfigKey& key);
275
276 void resetInternalLocked();
277
Bookatz8f2f3d82017-12-07 13:53:21 -0800278 void addSubStatsToConfigLocked(const ConfigKey& key,
279 StatsdStatsReport_ConfigStats& configStats);
Yao Chen69f1baf2017-11-27 17:25:36 -0800280
Yao Chen0fac5b12017-11-28 16:07:02 -0800281 void noteDataDropped(const ConfigKey& key, int32_t timeSec);
282
283 void noteMetricsReportSent(const ConfigKey& key, int32_t timeSec);
284
285 void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
286
Yao Chenf6723df2018-01-08 15:11:58 -0800287 void addToIceBoxLocked(const StatsdStatsReport_ConfigStats& stats);
288
Yao Chen69f1baf2017-11-27 17:25:36 -0800289 FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
290 FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
291 FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
292 FRIEND_TEST(StatsdStatsTest, TestSubStats);
293 FRIEND_TEST(StatsdStatsTest, TestAtomLog);
Yao Chen0fac5b12017-11-28 16:07:02 -0800294 FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
Bookatz1d0136d2017-12-01 11:13:32 -0800295 FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
Yao Chenb3561512017-11-21 18:07:17 -0800296};
297
298} // namespace statsd
299} // namespace os
Stefan Lafonc6f2fa22018-01-04 22:03:29 -0800300} // namespace android