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 "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
     25 #include "logd/LogEvent.h"
     26 #include "matchers/LogMatchingTracker.h"
     27 #include "metrics/MetricProducer.h"
     28 #include "packages/UidMap.h"
     29 
     30 #include <unordered_map>
     31 
     32 namespace android {
     33 namespace os {
     34 namespace statsd {
     35 
     36 // A MetricsManager is responsible for managing metrics from one single config source.
     37 class MetricsManager : public PackageInfoListener {
     38 public:
     39     MetricsManager(const ConfigKey& configKey, const StatsdConfig& config,
     40                    const int64_t timeBaseNs, const int64_t currentTimeNs,
     41                    const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
     42                    const sp<AlarmMonitor>& periodicAlarmMonitor);
     43 
     44     virtual ~MetricsManager();
     45 
     46     // Return whether the configuration is valid.
     47     bool isConfigValid() const;
     48 
     49     void onLogEvent(const LogEvent& event);
     50 
     51     void onAnomalyAlarmFired(
     52         const int64_t& timestampNs,
     53         unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
     54 
     55     void onPeriodicAlarmFired(
     56         const int64_t& timestampNs,
     57         unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
     58 
     59     void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
     60                           const int64_t version) override;
     61 
     62     void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) override;
     63 
     64     void onUidMapReceived(const int64_t& eventTimeNs) override;
     65 
     66     bool shouldAddUidMapListener() const {
     67         return !mAllowedPkg.empty();
     68     }
     69 
     70     bool shouldWriteToDisk() const {
     71         return mNoReportMetricIds.size() != mAllMetricProducers.size();
     72     }
     73 
     74     void dumpStates(FILE* out, bool verbose);
     75 
     76     inline bool isInTtl(const int64_t timestampNs) const {
     77         return mTtlNs <= 0 || timestampNs < mTtlEndNs;
     78     };
     79 
     80     inline bool hashStringInReport() const {
     81         return mHashStringsInReport;
     82     };
     83 
     84     void refreshTtl(const int64_t currentTimestampNs) {
     85         if (mTtlNs > 0) {
     86             mTtlEndNs = currentTimestampNs + mTtlNs;
     87         }
     88     };
     89 
     90     // Returns the elapsed realtime when this metric manager last reported metrics. If this config
     91     // has not yet dumped any reports, this is the time the metricsmanager was initialized.
     92     inline int64_t getLastReportTimeNs() const {
     93         return mLastReportTimeNs;
     94     };
     95 
     96     inline int64_t getLastReportWallClockNs() const {
     97         return mLastReportWallClockNs;
     98     };
     99 
    100     inline size_t getNumMetrics() const {
    101         return mAllMetricProducers.size();
    102     }
    103 
    104     virtual void dropData(const int64_t dropTimeNs);
    105 
    106     virtual void onDumpReport(const int64_t dumpTimeNs,
    107                               const bool include_current_partial_bucket,
    108                               std::set<string> *str_set,
    109                               android::util::ProtoOutputStream* protoOutput);
    110 
    111     // Computes the total byte size of all metrics managed by a single config source.
    112     // Does not change the state.
    113     virtual size_t byteSize();
    114 
    115 private:
    116     // For test only.
    117     inline int64_t getTtlEndNs() const { return mTtlEndNs; }
    118 
    119     const ConfigKey mConfigKey;
    120 
    121     sp<UidMap> mUidMap;
    122 
    123     bool mConfigValid = false;
    124 
    125     bool mHashStringsInReport = false;
    126 
    127     const int64_t mTtlNs;
    128     int64_t mTtlEndNs;
    129 
    130     int64_t mLastReportTimeNs;
    131     int64_t mLastReportWallClockNs;
    132 
    133     // The uid log sources from StatsdConfig.
    134     std::vector<int32_t> mAllowedUid;
    135 
    136     // The pkg log sources from StatsdConfig.
    137     std::vector<std::string> mAllowedPkg;
    138 
    139     // The combined uid sources (after translating pkg name to uid).
    140     // Logs from uids that are not in the list will be ignored to avoid spamming.
    141     std::set<int32_t> mAllowedLogSources;
    142 
    143     // Contains the annotations passed in with StatsdConfig.
    144     std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
    145 
    146     // To guard access to mAllowedLogSources
    147     mutable std::mutex mAllowedLogSourcesMutex;
    148 
    149     // All event tags that are interesting to my metrics.
    150     std::set<int> mTagIds;
    151 
    152     // We only store the sp of LogMatchingTracker, MetricProducer, and ConditionTracker in
    153     // MetricsManager. There are relationships between them, and the relationships are denoted by
    154     // index instead of pointers. The reasons for this are: (1) the relationship between them are
    155     // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B
    156     // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get
    157     // the related results from a cache using the index.
    158 
    159     // Hold all the atom matchers from the config.
    160     std::vector<sp<LogMatchingTracker>> mAllAtomMatchers;
    161 
    162     // Hold all the conditions from the config.
    163     std::vector<sp<ConditionTracker>> mAllConditionTrackers;
    164 
    165     // Hold all metrics from the config.
    166     std::vector<sp<MetricProducer>> mAllMetricProducers;
    167 
    168     // Hold all alert trackers.
    169     std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers;
    170 
    171     // Hold all periodic alarm trackers.
    172     std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers;
    173 
    174     // To make the log processing more efficient, we want to do as much filtering as possible
    175     // before we go into individual trackers and conditions to match.
    176 
    177     // 1st filter: check if the event tag id is in mTagIds.
    178     // 2nd filter: if it is, we parse the event because there is at least one member is interested.
    179     //             then pass to all LogMatchingTrackers (itself also filter events by ids).
    180     // 3nd filter: for LogMatchingTrackers that matched this event, we pass this event to the
    181     //             ConditionTrackers and MetricProducers that use this matcher.
    182     // 4th filter: for ConditionTrackers that changed value due to this event, we pass
    183     //             new conditions to  metrics that use this condition.
    184 
    185     // The following map is initialized from the statsd_config.
    186 
    187     // maps from the index of the LogMatchingTracker to index of MetricProducer.
    188     std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;
    189 
    190     // maps from LogMatchingTracker to ConditionTracker
    191     std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;
    192 
    193     // maps from ConditionTracker to MetricProducer
    194     std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
    195 
    196     void initLogSourceWhiteList();
    197 
    198     // The metrics that don't need to be uploaded or even reported.
    199     std::set<int64_t> mNoReportMetricIds;
    200 
    201     FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions);
    202     FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
    203     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
    204     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
    205     FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
    206     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
    207     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
    208     FRIEND_TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents);
    209     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
    210     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
    211     FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition);
    212     FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition);
    213     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition);
    214     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition);
    215 
    216     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition);
    217     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition);
    218     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition);
    219     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition);
    220     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition);
    221     FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition);
    222 
    223     FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
    224     FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
    225     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
    226     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
    227     FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
    228 
    229     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
    230     FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
    231 };
    232 
    233 }  // namespace statsd
    234 }  // namespace os
    235 }  // namespace android
    236