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