1 /*
2  * Copyright (C) 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 
17 #pragma once
18 
19 #include "anomaly/AlarmMonitor.h"
20 #include "anomaly/AlarmTracker.h"
21 #include "anomaly/AnomalyTracker.h"
22 #include "condition/ConditionTracker.h"
23 #include "config/ConfigKey.h"
24 #include "external/StatsPullerManager.h"
25 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
26 #include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"
27 #include "logd/LogEvent.h"
28 #include "matchers/LogMatchingTracker.h"
29 #include "metrics/MetricProducer.h"
30 #include "packages/UidMap.h"
31 
32 #include <unordered_map>
33 
34 namespace android {
35 namespace os {
36 namespace statsd {
37 
38 // A MetricsManager is responsible for managing metrics from one single config source.
39 class MetricsManager : public virtual android::RefBase, public virtual PullUidProvider {
40 public:
41     MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const int64_t timeBaseNs,
42                    const int64_t currentTimeNs, const sp<UidMap>& uidMap,
43                    const sp<StatsPullerManager>& pullerManager,
44                    const sp<AlarmMonitor>& anomalyAlarmMonitor,
45                    const sp<AlarmMonitor>& periodicAlarmMonitor);
46 
47     virtual ~MetricsManager();
48 
49     // Return whether the configuration is valid.
50     bool isConfigValid() const;
51 
52     bool checkLogCredentials(const LogEvent& event);
53 
54     bool eventSanityCheck(const LogEvent& event);
55 
56     void onLogEvent(const LogEvent& event);
57 
58     void onAnomalyAlarmFired(
59         const int64_t& timestampNs,
60         unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
61 
62     void onPeriodicAlarmFired(
63         const int64_t& timestampNs,
64         unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
65 
66     void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
67                           const int64_t version);
68 
69     void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid);
70 
71     void onUidMapReceived(const int64_t& eventTimeNs);
72 
73     void onStatsdInitCompleted(const int64_t& elapsedTimeNs);
74 
75     void init();
76 
77     vector<int32_t> getPullAtomUids(int32_t atomId) override;
78 
shouldWriteToDisk()79     bool shouldWriteToDisk() const {
80         return mNoReportMetricIds.size() != mAllMetricProducers.size();
81     }
82 
shouldPersistLocalHistory()83     bool shouldPersistLocalHistory() const {
84         return mShouldPersistHistory;
85     }
86 
87     void dumpStates(FILE* out, bool verbose);
88 
isInTtl(const int64_t timestampNs)89     inline bool isInTtl(const int64_t timestampNs) const {
90         return mTtlNs <= 0 || timestampNs < mTtlEndNs;
91     };
92 
hashStringInReport()93     inline bool hashStringInReport() const {
94         return mHashStringsInReport;
95     };
96 
versionStringsInReport()97     inline bool versionStringsInReport() const {
98         return mVersionStringsInReport;
99     };
100 
installerInReport()101     inline bool installerInReport() const {
102         return mInstallerInReport;
103     };
104 
refreshTtl(const int64_t currentTimestampNs)105     void refreshTtl(const int64_t currentTimestampNs) {
106         if (mTtlNs > 0) {
107             mTtlEndNs = currentTimestampNs + mTtlNs;
108         }
109     };
110 
111     // Returns the elapsed realtime when this metric manager last reported metrics. If this config
112     // has not yet dumped any reports, this is the time the metricsmanager was initialized.
getLastReportTimeNs()113     inline int64_t getLastReportTimeNs() const {
114         return mLastReportTimeNs;
115     };
116 
getLastReportWallClockNs()117     inline int64_t getLastReportWallClockNs() const {
118         return mLastReportWallClockNs;
119     };
120 
getNumMetrics()121     inline size_t getNumMetrics() const {
122         return mAllMetricProducers.size();
123     }
124 
125     virtual void dropData(const int64_t dropTimeNs);
126 
127     virtual void onDumpReport(const int64_t dumpTimeNs,
128                               const bool include_current_partial_bucket,
129                               const bool erase_data,
130                               const DumpLatency dumpLatency,
131                               std::set<string> *str_set,
132                               android::util::ProtoOutputStream* protoOutput);
133 
134     // Computes the total byte size of all metrics managed by a single config source.
135     // Does not change the state.
136     virtual size_t byteSize();
137 
138     // Returns whether or not this config is active.
139     // The config is active if any metric in the config is active.
isActive()140     inline bool isActive() const {
141         return mIsActive;
142     }
143 
144     void loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs);
145 
146     void writeActiveConfigToProtoOutputStream(
147             int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
148 
149     // Returns true if at least one piece of metadata is written.
150     bool writeMetadataToProto(int64_t currentWallClockTimeNs,
151                               int64_t systemElapsedTimeNs,
152                               metadata::StatsMetadata* statsMetadata);
153 
154     void loadMetadata(const metadata::StatsMetadata& metadata,
155                       int64_t currentWallClockTimeNs,
156                       int64_t systemElapsedTimeNs);
157 private:
158     // For test only.
getTtlEndNs()159     inline int64_t getTtlEndNs() const { return mTtlEndNs; }
160 
161     const ConfigKey mConfigKey;
162 
163     sp<UidMap> mUidMap;
164 
165     bool mConfigValid = false;
166 
167     bool mHashStringsInReport = false;
168     bool mVersionStringsInReport = false;
169     bool mInstallerInReport = false;
170 
171     const int64_t mTtlNs;
172     int64_t mTtlEndNs;
173 
174     int64_t mLastReportTimeNs;
175     int64_t mLastReportWallClockNs;
176 
177     sp<StatsPullerManager> mPullerManager;
178 
179     // The uid log sources from StatsdConfig.
180     std::vector<int32_t> mAllowedUid;
181 
182     // The pkg log sources from StatsdConfig.
183     std::vector<std::string> mAllowedPkg;
184 
185     // The combined uid sources (after translating pkg name to uid).
186     // Logs from uids that are not in the list will be ignored to avoid spamming.
187     std::set<int32_t> mAllowedLogSources;
188 
189     // To guard access to mAllowedLogSources
190     mutable std::mutex mAllowedLogSourcesMutex;
191 
192     const std::set<int32_t> mWhitelistedAtomIds;
193 
194     // We can pull any atom from these uids.
195     std::set<int32_t> mDefaultPullUids;
196 
197     // Uids that specific atoms can pull from.
198     // This is a map<atom id, set<uids>>
199     std::map<int32_t, std::set<int32_t>> mPullAtomUids;
200 
201     // Packages that specific atoms can be pulled from.
202     std::map<int32_t, std::set<std::string>> mPullAtomPackages;
203 
204     // All uids to pull for this atom. NOTE: Does not include the default uids for memory.
205     std::map<int32_t, std::set<int32_t>> mCombinedPullAtomUids;
206 
207     // Contains the annotations passed in with StatsdConfig.
208     std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
209 
210     const bool mShouldPersistHistory;
211 
212 
213     // All event tags that are interesting to my metrics.
214     std::set<int> mTagIds;
215 
216     // We only store the sp of LogMatchingTracker, MetricProducer, and ConditionTracker in
217     // MetricsManager. There are relationships between them, and the relationships are denoted by
218     // index instead of pointers. The reasons for this are: (1) the relationship between them are
219     // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B
220     // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get
221     // the related results from a cache using the index.
222 
223     // Hold all the atom matchers from the config.
224     std::vector<sp<LogMatchingTracker>> mAllAtomMatchers;
225 
226     // Hold all the conditions from the config.
227     std::vector<sp<ConditionTracker>> mAllConditionTrackers;
228 
229     // Hold all metrics from the config.
230     std::vector<sp<MetricProducer>> mAllMetricProducers;
231 
232     // Hold all alert trackers.
233     std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers;
234 
235     // Hold all periodic alarm trackers.
236     std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
237 
238     // To make the log processing more efficient, we want to do as much filtering as possible
239     // before we go into individual trackers and conditions to match.
240 
241     // 1st filter: check if the event tag id is in mTagIds.
242     // 2nd filter: if it is, we parse the event because there is at least one member is interested.
243     //             then pass to all LogMatchingTrackers (itself also filter events by ids).
244     // 3nd filter: for LogMatchingTrackers that matched this event, we pass this event to the
245     //             ConditionTrackers and MetricProducers that use this matcher.
246     // 4th filter: for ConditionTrackers that changed value due to this event, we pass
247     //             new conditions to  metrics that use this condition.
248 
249     // The following map is initialized from the statsd_config.
250 
251     // Maps from the index of the LogMatchingTracker to index of MetricProducer.
252     std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;
253 
254     // Maps from LogMatchingTracker to ConditionTracker
255     std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;
256 
257     // Maps from ConditionTracker to MetricProducer
258     std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
259 
260     // Maps from life span triggering event to MetricProducers.
261     std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap;
262 
263     // Maps deactivation triggering event to MetricProducers.
264     std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap;
265 
266     // Maps AlertIds to the index of the corresponding AnomalyTracker stored in mAllAnomalyTrackers.
267     // The map is used in LoadMetadata to more efficiently lookup AnomalyTrackers from an AlertId.
268     std::unordered_map<int64_t, int> mAlertTrackerMap;
269 
270     std::vector<int> mMetricIndexesWithActivation;
271 
272     void initLogSourceWhiteList();
273 
274     void initPullAtomSources();
275 
276     // The metrics that don't need to be uploaded or even reported.
277     std::set<int64_t> mNoReportMetricIds;
278 
279    // The config is active if any metric in the config is active.
280     bool mIsActive;
281 
282     // The config is always active if any metric in the config does not have an activation signal.
283     bool mIsAlwaysActive;
284 
285     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions);
286     FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
287     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
288     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
289     FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
290     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
291     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
292     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsWithActivation);
293     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition);
294     FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
295 
296     FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
297     FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
298     FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
299     FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
300     FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_load_refractory_from_disk);
301     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
302     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
303     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
304 
305     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
306     FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
307     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
308     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
309     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
310     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
311     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
312 
313     FRIEND_TEST(MetricsManagerTest, TestLogSources);
314 
315     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
316     FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
317     FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
318     FRIEND_TEST(StatsLogProcessorTest,
319             TestActivationOnBootMultipleActivationsDifferentActivationTypes);
320     FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
321 
322     FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges);
323     FRIEND_TEST(CountMetricE2eTest, TestSlicedState);
324     FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
325     FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
326     FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
327 
328     FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
329     FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
330     FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
331     FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
332     FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
333     FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
334     FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState);
335     FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState);
336     FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped);
337     FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSuperset);
338     FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
339 
340     FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
341     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
342     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
343     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
344     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
345     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
346     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
347 };
348 
349 }  // namespace statsd
350 }  // namespace os
351 }  // namespace android
352