blob: 14f4132053103dd66ff89d19851e50a7770cf811 [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"
19#include "frameworks/base/cmds/statsd/src/stats_log.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 Chenb3561512017-11-21 18:07:17 -080024#include <mutex>
25#include <string>
26#include <vector>
27
28namespace android {
29namespace os {
30namespace statsd {
31
32// Keeps track of stats of statsd.
33// Single instance shared across the process. All methods are thread safe.
34class StatsdStats {
35public:
36 static StatsdStats& getInstance();
37 ~StatsdStats(){};
38
39 // TODO: set different limit if the device is low ram.
40 const static int kDimensionKeySizeSoftLimit = 300;
41 const static int kDimensionKeySizeHardLimit = 500;
42
43 const static int kMaxConfigCount = 10;
44 const static int kMaxConditionCountPerConfig = 200;
45 const static int kMaxMetricCountPerConfig = 300;
46 const static int kMaxMatcherCountPerConfig = 500;
47
Yao Chen0fac5b12017-11-28 16:07:02 -080048 const static int kMaxTimestampCount = 20;
49
Yao Chend10f7b12017-12-18 12:53:50 -080050 const static int kMaxLogSourceCount = 50;
51
David Chend9269e22017-12-05 13:43:51 -080052 // Max memory allowed for storing metrics per configuration. When this limit is approached,
53 // statsd will send a broadcast so that the client can fetch the data and clear this memory.
54 static const size_t kMaxMetricsBytesPerConfig = 128 * 1024;
55
David Chenc136f452017-11-27 11:52:26 -080056 // Cap the UID map's memory usage to this. This should be fairly high since the UID information
57 // is critical for understanding the metrics.
58 const static size_t kMaxBytesUsedUidMap = 50 * 1024;
59
David Chend9269e22017-12-05 13:43:51 -080060 /* Minimum period between two broadcasts in nanoseconds. */
61 static const unsigned long long kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
62
63 /* Min period between two checks of byte size per config key in nanoseconds. */
64 static const unsigned long long kMinByteSizeCheckPeriodNs = 10 * NS_PER_SEC;
65
Chenjie Yub038b702017-12-18 15:15:34 -080066 // Default minimum interval between pulls for an atom. Pullers can return cached values if
67 // another pull request happens within this interval.
68 static std::map<int, long> kPullerCooldownMap;
69
70 // Default cooldown time for a puller
71 static const long kDefaultPullerCooldown = 1;
72
Yao Chenb3561512017-11-21 18:07:17 -080073 /**
74 * Report a new config has been received and report the static stats about the config.
75 *
76 * The static stats include: the count of metrics, conditions, matchers, and alerts.
77 * If the config is not valid, this config stats will be put into icebox immediately.
78 */
79 void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
80 int matchersCount, int alertCount, bool isValid);
81 /**
82 * Report a config has been removed.
83 */
84 void noteConfigRemoved(const ConfigKey& key);
85
86 /**
87 * Report a broadcast has been sent to a config owner to collect the data.
88 */
89 void noteBroadcastSent(const ConfigKey& key);
90
91 /**
92 * Report a config's metrics data has been dropped.
93 */
Yao Chen69f1baf2017-11-27 17:25:36 -080094 void noteDataDropped(const ConfigKey& key);
95
96 /**
97 * Report metrics data report has been sent.
98 *
99 * The report may be requested via StatsManager API, or through adb cmd.
100 */
101 void noteMetricsReportSent(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -0800102
103 /**
104 * Report the size of output tuple of a condition.
105 *
106 * Note: only report when the condition has an output dimension, and the tuple
107 * count > kDimensionKeySizeSoftLimit.
108 *
109 * [key]: The config key that this condition belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800110 * [id]: The id of the condition.
Yao Chenb3561512017-11-21 18:07:17 -0800111 * [size]: The output tuple size.
112 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800113 void noteConditionDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800114
115 /**
116 * Report the size of output tuple of a metric.
117 *
118 * Note: only report when the metric has an output dimension, and the tuple
119 * count > kDimensionKeySizeSoftLimit.
120 *
121 * [key]: The config key that this metric belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800122 * [id]: The id of the metric.
Yao Chenb3561512017-11-21 18:07:17 -0800123 * [size]: The output tuple size.
124 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800125 void noteMetricDimensionSize(const ConfigKey& key, const int64_t& id, int size);
Yao Chenb3561512017-11-21 18:07:17 -0800126
127 /**
128 * Report a matcher has been matched.
129 *
130 * [key]: The config key that this matcher belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800131 * [id]: The id of the matcher.
Yao Chenb3561512017-11-21 18:07:17 -0800132 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800133 void noteMatcherMatched(const ConfigKey& key, const int64_t& id);
Yao Chenb3561512017-11-21 18:07:17 -0800134
135 /**
Bookatz8f2f3d82017-12-07 13:53:21 -0800136 * Report that an anomaly detection alert has been declared.
137 *
138 * [key]: The config key that this alert belongs to.
Yangster-mac94e197c2018-01-02 16:03:03 -0800139 * [id]: The id of the alert.
Bookatz8f2f3d82017-12-07 13:53:21 -0800140 */
Yangster-mac94e197c2018-01-02 16:03:03 -0800141 void noteAnomalyDeclared(const ConfigKey& key, const int64_t& id);
Bookatz8f2f3d82017-12-07 13:53:21 -0800142
143 /**
Yao Chenb3561512017-11-21 18:07:17 -0800144 * Report an atom event has been logged.
145 */
146 void noteAtomLogged(int atomId, int32_t timeSec);
147
148 /**
Bookatz1d0136d2017-12-01 11:13:32 -0800149 * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
150 */
151 void noteRegisteredAnomalyAlarmChanged();
152
153 /**
David Chenc136f452017-11-27 11:52:26 -0800154 * Records the number of snapshot and delta entries that are being dropped from the uid map.
155 */
156 void noteUidMapDropped(int snapshots, int deltas);
157
158 /**
159 * Updates the number of snapshots currently stored in the uid map.
160 */
161 void setUidMapSnapshots(int snapshots);
162 void setUidMapChanges(int changes);
163 void setCurrentUidMapMemory(int bytes);
164
Chenjie Yub038b702017-12-18 15:15:34 -0800165 // Update minimum interval between pulls for an pulled atom
166 void updateMinPullIntervalSec(int pullAtomId, long intervalSec);
167
168 // Notify pull request for an atom
169 void notePull(int pullAtomId);
170
171 // Notify pull request for an atom served from cached data
172 void notePullFromCache(int pullAtomId);
173
David Chenc136f452017-11-27 11:52:26 -0800174 /**
Yao Chenb3561512017-11-21 18:07:17 -0800175 * Reset the historical stats. Including all stats in icebox, and the tracked stats about
176 * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
177 * to collect stats after reset() has been called.
178 */
179 void reset();
180
181 /**
182 * Output the stats in protobuf binary format to [buffer].
183 *
184 * [reset]: whether to clear the historical stats after the call.
185 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800186 void dumpStats(std::vector<uint8_t>* buffer, bool reset);
Yao Chenb3561512017-11-21 18:07:17 -0800187
Chenjie Yub038b702017-12-18 15:15:34 -0800188 typedef struct {
189 long totalPull;
190 long totalPullFromCache;
191 long minPullIntervalSec;
192 } PulledAtomStats;
193
Yao Chenb3561512017-11-21 18:07:17 -0800194private:
195 StatsdStats();
196
197 mutable std::mutex mLock;
198
Yao Chen69f1baf2017-11-27 17:25:36 -0800199 int32_t mStartTimeSec;
Yao Chenb3561512017-11-21 18:07:17 -0800200
David Chenc136f452017-11-27 11:52:26 -0800201 // Track the number of dropped entries used by the uid map.
202 StatsdStatsReport_UidMapStats mUidMapStats;
203
Yao Chenb3561512017-11-21 18:07:17 -0800204 // The stats about the configs that are still in use.
205 std::map<const ConfigKey, StatsdStatsReport_ConfigStats> mConfigStats;
206
207 // Stores the stats for the configs that are no longer in use.
208 std::vector<const StatsdStatsReport_ConfigStats> mIceBox;
209
210 // Stores the number of output tuple of condition trackers when it's bigger than
211 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
212 // it means some data has been dropped.
Yangster-mac94e197c2018-01-02 16:03:03 -0800213 std::map<const ConfigKey, std::map<const int64_t, int>> mConditionStats;
Yao Chenb3561512017-11-21 18:07:17 -0800214
215 // Stores the number of output tuple of metric producers when it's bigger than
216 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
217 // it means some data has been dropped.
Yangster-mac94e197c2018-01-02 16:03:03 -0800218 std::map<const ConfigKey, std::map<const int64_t, int>> mMetricsStats;
Yao Chenb3561512017-11-21 18:07:17 -0800219
220 // Stores the number of times a pushed atom is logged.
221 // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
222 // out of that range will be dropped (it's either pulled atoms or test atoms).
223 // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
224 std::vector<int> mPushedAtomStats;
225
Chenjie Yub038b702017-12-18 15:15:34 -0800226 std::map<int, PulledAtomStats> mPulledAtomStats;
227
Bookatz1d0136d2017-12-01 11:13:32 -0800228 // Stores the number of times statsd modified the anomaly alarm registered with
229 // StatsCompanionService.
230 int mAnomalyAlarmRegisteredStats = 0;
231
Bookatz8f2f3d82017-12-07 13:53:21 -0800232 // Stores the number of times an anomaly detection alert has been declared
233 // (per config, per alert name).
Yangster-mac94e197c2018-01-02 16:03:03 -0800234 std::map<const ConfigKey, std::map<const int64_t, int>> mAlertStats;
Bookatz8f2f3d82017-12-07 13:53:21 -0800235
Yao Chenb3561512017-11-21 18:07:17 -0800236 // Stores how many times a matcher have been matched.
Yangster-mac94e197c2018-01-02 16:03:03 -0800237 std::map<const ConfigKey, std::map<const int64_t, int>> mMatcherStats;
Yao Chenb3561512017-11-21 18:07:17 -0800238
239 void noteConfigRemovedInternalLocked(const ConfigKey& key);
240
241 void resetInternalLocked();
242
Bookatz8f2f3d82017-12-07 13:53:21 -0800243 void addSubStatsToConfigLocked(const ConfigKey& key,
244 StatsdStatsReport_ConfigStats& configStats);
Yao Chen69f1baf2017-11-27 17:25:36 -0800245
Yao Chen0fac5b12017-11-28 16:07:02 -0800246 void noteDataDropped(const ConfigKey& key, int32_t timeSec);
247
248 void noteMetricsReportSent(const ConfigKey& key, int32_t timeSec);
249
250 void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
251
Yao Chen69f1baf2017-11-27 17:25:36 -0800252 FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
253 FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
254 FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
255 FRIEND_TEST(StatsdStatsTest, TestSubStats);
256 FRIEND_TEST(StatsdStatsTest, TestAtomLog);
Yao Chen0fac5b12017-11-28 16:07:02 -0800257 FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
Bookatz1d0136d2017-12-01 11:13:32 -0800258 FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
Yao Chenb3561512017-11-21 18:07:17 -0800259};
260
261} // namespace statsd
262} // namespace os
263} // namespace android