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