blob: cb868e1fd8c6cd66efb14975262c6ccd106a4f88 [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"
20
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 Chenb3561512017-11-21 18:07:17 -080023#include <mutex>
24#include <string>
25#include <vector>
26
27namespace android {
28namespace os {
29namespace statsd {
30
31// Keeps track of stats of statsd.
32// Single instance shared across the process. All methods are thread safe.
33class StatsdStats {
34public:
35 static StatsdStats& getInstance();
36 ~StatsdStats(){};
37
38 // TODO: set different limit if the device is low ram.
39 const static int kDimensionKeySizeSoftLimit = 300;
40 const static int kDimensionKeySizeHardLimit = 500;
41
42 const static int kMaxConfigCount = 10;
43 const static int kMaxConditionCountPerConfig = 200;
44 const static int kMaxMetricCountPerConfig = 300;
45 const static int kMaxMatcherCountPerConfig = 500;
46
Yao Chen0fac5b12017-11-28 16:07:02 -080047 const static int kMaxTimestampCount = 20;
48
Yao Chend10f7b12017-12-18 12:53:50 -080049 const static int kMaxLogSourceCount = 50;
50
David Chend9269e22017-12-05 13:43:51 -080051 // Max memory allowed for storing metrics per configuration. When this limit is approached,
52 // statsd will send a broadcast so that the client can fetch the data and clear this memory.
53 static const size_t kMaxMetricsBytesPerConfig = 128 * 1024;
54
David Chenc136f452017-11-27 11:52:26 -080055 // Cap the UID map's memory usage to this. This should be fairly high since the UID information
56 // is critical for understanding the metrics.
57 const static size_t kMaxBytesUsedUidMap = 50 * 1024;
58
David Chend9269e22017-12-05 13:43:51 -080059 /* Minimum period between two broadcasts in nanoseconds. */
60 static const unsigned long long kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
61
62 /* Min period between two checks of byte size per config key in nanoseconds. */
63 static const unsigned long long kMinByteSizeCheckPeriodNs = 10 * NS_PER_SEC;
64
Yao Chenb3561512017-11-21 18:07:17 -080065 /**
66 * Report a new config has been received and report the static stats about the config.
67 *
68 * The static stats include: the count of metrics, conditions, matchers, and alerts.
69 * If the config is not valid, this config stats will be put into icebox immediately.
70 */
71 void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
72 int matchersCount, int alertCount, bool isValid);
73 /**
74 * Report a config has been removed.
75 */
76 void noteConfigRemoved(const ConfigKey& key);
77
78 /**
79 * Report a broadcast has been sent to a config owner to collect the data.
80 */
81 void noteBroadcastSent(const ConfigKey& key);
82
83 /**
84 * Report a config's metrics data has been dropped.
85 */
Yao Chen69f1baf2017-11-27 17:25:36 -080086 void noteDataDropped(const ConfigKey& key);
87
88 /**
89 * Report metrics data report has been sent.
90 *
91 * The report may be requested via StatsManager API, or through adb cmd.
92 */
93 void noteMetricsReportSent(const ConfigKey& key);
Yao Chenb3561512017-11-21 18:07:17 -080094
95 /**
96 * Report the size of output tuple of a condition.
97 *
98 * Note: only report when the condition has an output dimension, and the tuple
99 * count > kDimensionKeySizeSoftLimit.
100 *
101 * [key]: The config key that this condition belongs to.
102 * [name]: The name of the condition.
103 * [size]: The output tuple size.
104 */
105 void noteConditionDimensionSize(const ConfigKey& key, const std::string& name, int size);
106
107 /**
108 * Report the size of output tuple of a metric.
109 *
110 * Note: only report when the metric has an output dimension, and the tuple
111 * count > kDimensionKeySizeSoftLimit.
112 *
113 * [key]: The config key that this metric belongs to.
114 * [name]: The name of the metric.
115 * [size]: The output tuple size.
116 */
117 void noteMetricDimensionSize(const ConfigKey& key, const std::string& name, int size);
118
119 /**
120 * Report a matcher has been matched.
121 *
122 * [key]: The config key that this matcher belongs to.
123 * [name]: The name of the matcher.
124 */
125 void noteMatcherMatched(const ConfigKey& key, const std::string& name);
126
127 /**
Bookatz8f2f3d82017-12-07 13:53:21 -0800128 * Report that an anomaly detection alert has been declared.
129 *
130 * [key]: The config key that this alert belongs to.
131 * [name]: The name of the alert.
132 */
133 void noteAnomalyDeclared(const ConfigKey& key, const std::string& name);
134
135 /**
Yao Chenb3561512017-11-21 18:07:17 -0800136 * Report an atom event has been logged.
137 */
138 void noteAtomLogged(int atomId, int32_t timeSec);
139
140 /**
Bookatz1d0136d2017-12-01 11:13:32 -0800141 * Report that statsd modified the anomaly alarm registered with StatsCompanionService.
142 */
143 void noteRegisteredAnomalyAlarmChanged();
144
145 /**
David Chenc136f452017-11-27 11:52:26 -0800146 * Records the number of snapshot and delta entries that are being dropped from the uid map.
147 */
148 void noteUidMapDropped(int snapshots, int deltas);
149
150 /**
151 * Updates the number of snapshots currently stored in the uid map.
152 */
153 void setUidMapSnapshots(int snapshots);
154 void setUidMapChanges(int changes);
155 void setCurrentUidMapMemory(int bytes);
156
157 /**
Yao Chenb3561512017-11-21 18:07:17 -0800158 * Reset the historical stats. Including all stats in icebox, and the tracked stats about
159 * metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
160 * to collect stats after reset() has been called.
161 */
162 void reset();
163
164 /**
165 * Output the stats in protobuf binary format to [buffer].
166 *
167 * [reset]: whether to clear the historical stats after the call.
168 */
Yao Chen69f1baf2017-11-27 17:25:36 -0800169 void dumpStats(std::vector<uint8_t>* buffer, bool reset);
Yao Chenb3561512017-11-21 18:07:17 -0800170
171private:
172 StatsdStats();
173
174 mutable std::mutex mLock;
175
Yao Chen69f1baf2017-11-27 17:25:36 -0800176 int32_t mStartTimeSec;
Yao Chenb3561512017-11-21 18:07:17 -0800177
David Chenc136f452017-11-27 11:52:26 -0800178 // Track the number of dropped entries used by the uid map.
179 StatsdStatsReport_UidMapStats mUidMapStats;
180
Yao Chenb3561512017-11-21 18:07:17 -0800181 // The stats about the configs that are still in use.
182 std::map<const ConfigKey, StatsdStatsReport_ConfigStats> mConfigStats;
183
184 // Stores the stats for the configs that are no longer in use.
185 std::vector<const StatsdStatsReport_ConfigStats> mIceBox;
186
187 // Stores the number of output tuple of condition trackers when it's bigger than
188 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
189 // it means some data has been dropped.
190 std::map<const ConfigKey, std::map<const std::string, int>> mConditionStats;
191
192 // Stores the number of output tuple of metric producers when it's bigger than
193 // kDimensionKeySizeSoftLimit. When you see the number is kDimensionKeySizeHardLimit +1,
194 // it means some data has been dropped.
195 std::map<const ConfigKey, std::map<const std::string, int>> mMetricsStats;
196
197 // Stores the number of times a pushed atom is logged.
198 // The size of the vector is the largest pushed atom id in atoms.proto + 1. Atoms
199 // out of that range will be dropped (it's either pulled atoms or test atoms).
200 // This is a vector, not a map because it will be accessed A LOT -- for each stats log.
201 std::vector<int> mPushedAtomStats;
202
Bookatz1d0136d2017-12-01 11:13:32 -0800203 // Stores the number of times statsd modified the anomaly alarm registered with
204 // StatsCompanionService.
205 int mAnomalyAlarmRegisteredStats = 0;
206
Bookatz8f2f3d82017-12-07 13:53:21 -0800207 // Stores the number of times an anomaly detection alert has been declared
208 // (per config, per alert name).
209 std::map<const ConfigKey, std::map<const std::string, int>> mAlertStats;
210
Yao Chenb3561512017-11-21 18:07:17 -0800211 // Stores how many times a matcher have been matched.
212 std::map<const ConfigKey, std::map<const std::string, int>> mMatcherStats;
213
214 void noteConfigRemovedInternalLocked(const ConfigKey& key);
215
216 void resetInternalLocked();
217
Bookatz8f2f3d82017-12-07 13:53:21 -0800218 void addSubStatsToConfigLocked(const ConfigKey& key,
219 StatsdStatsReport_ConfigStats& configStats);
Yao Chen69f1baf2017-11-27 17:25:36 -0800220
Yao Chen0fac5b12017-11-28 16:07:02 -0800221 void noteDataDropped(const ConfigKey& key, int32_t timeSec);
222
223 void noteMetricsReportSent(const ConfigKey& key, int32_t timeSec);
224
225 void noteBroadcastSent(const ConfigKey& key, int32_t timeSec);
226
Yao Chen69f1baf2017-11-27 17:25:36 -0800227 FRIEND_TEST(StatsdStatsTest, TestValidConfigAdd);
228 FRIEND_TEST(StatsdStatsTest, TestInvalidConfigAdd);
229 FRIEND_TEST(StatsdStatsTest, TestConfigRemove);
230 FRIEND_TEST(StatsdStatsTest, TestSubStats);
231 FRIEND_TEST(StatsdStatsTest, TestAtomLog);
Yao Chen0fac5b12017-11-28 16:07:02 -0800232 FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold);
Bookatz1d0136d2017-12-01 11:13:32 -0800233 FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor);
Yao Chenb3561512017-11-21 18:07:17 -0800234};
235
236} // namespace statsd
237} // namespace os
238} // namespace android