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 <android/util/ProtoOutputStream.h> 20 21 #include <unordered_map> 22 23 #include "../anomaly/DurationAnomalyTracker.h" 24 #include "../condition/ConditionTracker.h" 25 #include "../matchers/matcher_util.h" 26 #include "MetricProducer.h" 27 #include "duration_helper/DurationTracker.h" 28 #include "duration_helper/MaxDurationTracker.h" 29 #include "duration_helper/OringDurationTracker.h" 30 #include "src/statsd_config.pb.h" 31 #include "stats_util.h" 32 33 using namespace std; 34 35 namespace android { 36 namespace os { 37 namespace statsd { 38 39 class DurationMetricProducer : public MetricProducer { 40 public: 41 DurationMetricProducer( 42 const ConfigKey& key, const DurationMetric& durationMetric, int conditionIndex, 43 const vector<ConditionState>& initialConditionCache, int whatIndex, 44 const int startIndex, int stopIndex, int stopAllIndex, const bool nesting, 45 const sp<ConditionWizard>& wizard, const uint64_t protoHash, 46 const FieldMatcher& internalDimensions, int64_t timeBaseNs, const int64_t startTimeNs, 47 const wp<ConfigMetadataProvider> configMetadataProvider, 48 const unordered_map<int, shared_ptr<Activation>>& eventActivationMap = {}, 49 const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap = {}, 50 const vector<int>& slicedStateAtoms = {}, 51 const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {}); 52 53 virtual ~DurationMetricProducer(); 54 55 sp<AnomalyTracker> addAnomalyTracker(const Alert& alert, 56 const sp<AlarmMonitor>& anomalyAlarmMonitor, 57 const UpdateStatus& updateStatus, 58 const int64_t updateTimeNs) override; 59 60 void addAnomalyTracker(sp<AnomalyTracker>& anomalyTracker, int64_t updateTimeNs) override; 61 62 void onStateChanged(const int64_t eventTimeNs, const int32_t atomId, 63 const HashableDimensionKey& primaryKey, const FieldValue& oldState, 64 const FieldValue& newState) override; 65 getMetricType()66 MetricType getMetricType() const override { 67 return METRIC_TYPE_DURATION; 68 } 69 70 protected: 71 void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) override; 72 73 void onMatchedLogEventInternalLocked( 74 const size_t matcherIndex, const MetricDimensionKey& eventKey, 75 const ConditionKey& conditionKeys, bool condition, const LogEvent& event, 76 const std::map<int, HashableDimensionKey>& statePrimaryKeys) override; 77 78 private: 79 // Initializes true dimensions of the 'what' predicate. Only to be called during initialization. 80 void initTrueDimensions(const int whatIndex, int64_t startTimeNs); 81 82 void handleMatchedLogEventValuesLocked(const size_t matcherIndex, 83 const std::vector<FieldValue>& values, 84 const int64_t eventTimeNs); 85 void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys, 86 bool condition, int64_t eventTimeNs, 87 const vector<FieldValue>& eventValues); 88 89 void onDumpReportLocked(const int64_t dumpTimeNs, const bool include_current_partial_bucket, 90 const bool erase_data, const DumpLatency dumpLatency, 91 std::set<string>* str_set, std::set<int32_t>& usedUids, 92 android::util::ProtoOutputStream* protoOutput) override; 93 94 void clearPastBucketsLocked(const int64_t dumpTimeNs) override; 95 96 // Internal interface to handle condition change. 97 void onConditionChangedLocked(const bool conditionMet, int64_t eventTime) override; 98 99 // Internal interface to handle active state change. 100 void onActiveStateChangedLocked(const int64_t eventTimeNs, const bool isActive) override; 101 102 // Internal interface to handle sliced condition change. 103 void onSlicedConditionMayChangeLocked(bool overallCondition, int64_t eventTime) override; 104 105 void onSlicedConditionMayChangeInternalLocked(const int64_t eventTimeNs); 106 107 void onSlicedConditionMayChangeLocked_opt1(const int64_t eventTime); 108 109 // Internal function to calculate the current used bytes. 110 size_t byteSizeLocked() const override; 111 112 void dumpStatesLocked(int out, bool verbose) const override; 113 114 void dropDataLocked(const int64_t dropTimeNs) override; 115 116 // Util function to flush the old packet. 117 void flushIfNeededLocked(int64_t eventTime); 118 119 void flushCurrentBucketLocked(int64_t eventTimeNs, int64_t nextBucketStartTimeNs) override; 120 121 optional<InvalidConfigReason> onConfigUpdatedLocked( 122 const StatsdConfig& config, int configIndex, int metricIndex, 123 const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, 124 const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap, 125 const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap, 126 const sp<EventMatcherWizard>& matcherWizard, 127 const std::vector<sp<ConditionTracker>>& allConditionTrackers, 128 const std::unordered_map<int64_t, int>& conditionTrackerMap, 129 const sp<ConditionWizard>& wizard, 130 const std::unordered_map<int64_t, int>& metricToActivationMap, 131 std::unordered_map<int, std::vector<int>>& trackerToMetricMap, 132 std::unordered_map<int, std::vector<int>>& conditionToMetricMap, 133 std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, 134 std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, 135 std::vector<int>& metricsWithActivation) override; 136 137 void addAnomalyTrackerLocked(sp<AnomalyTracker>& anomalyTracker, 138 const UpdateStatus& updateStatus, int64_t updateTimeNs); 139 140 size_t computeBucketSizeLocked(const bool isFullBucket, const MetricDimensionKey& dimKey, 141 const bool isFirstBucket) const override; 142 143 DataCorruptionSeverity determineCorruptionSeverity(int32_t atomId, DataCorruptedReason reason, 144 LostAtomType atomType) const override; 145 146 const DurationMetric_AggregationType mAggregationType; 147 148 // Index of the SimpleAtomMatcher which defines the start. 149 int mStartIndex; 150 151 // Index of the SimpleAtomMatcher which defines the stop. 152 int mStopIndex; 153 154 // Index of the SimpleAtomMatcher which defines the stop all for all dimensions. 155 int mStopAllIndex; 156 157 // nest counting -- for the same key, stops must match the number of starts to make real stop 158 const bool mNested; 159 160 // The dimension from the atom predicate. e.g., uid, wakelock name. 161 vector<Matcher> mInternalDimensions; 162 163 bool mContainANYPositionInInternalDimensions; 164 165 // This boolean is true iff When mInternalDimensions == mDimensionsInWhat 166 bool mUseWhatDimensionAsInternalDimension; 167 168 // Caches the current unsliced part condition. 169 ConditionState mUnSlicedPartCondition; 170 171 // Save the past buckets and we can clear when the StatsLogReport is dumped. 172 std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets; 173 174 // The duration trackers in the current bucket. 175 std::unordered_map<HashableDimensionKey, std::unique_ptr<DurationTracker>> 176 mCurrentSlicedDurationTrackerMap; 177 178 const size_t mDimensionHardLimit; 179 180 // Helper function to create a duration tracker given the metric aggregation type. 181 std::unique_ptr<DurationTracker> createDurationTracker( 182 const MetricDimensionKey& eventKey) const; 183 184 // Util function to check whether the specified dimension hits the guardrail. 185 bool hitGuardRailLocked(const MetricDimensionKey& newKey) const; 186 187 static const size_t kBucketSize = sizeof(DurationBucket{}); 188 189 FRIEND_TEST(DurationMetricTrackerTest, TestNoCondition); 190 FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedCondition); 191 FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState); 192 FRIEND_TEST(DurationMetricTrackerTest, TestFirstBucket); 193 194 FRIEND_TEST(DurationMetricProducerTest, TestSumDurationAppUpgradeSplitDisabled); 195 FRIEND_TEST(DurationMetricProducerTest, TestClearCurrentSlicedTrackerMapWhenStop); 196 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestSumDuration); 197 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, 198 TestSumDurationWithSplitInFollowingBucket); 199 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDuration); 200 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket); 201 202 FRIEND_TEST(ConfigUpdateTest, TestUpdateDurationMetrics); 203 FRIEND_TEST(ConfigUpdateTest, TestUpdateAlerts); 204 205 FRIEND_TEST(MetricsManagerUtilDimLimitTest, TestDimLimit); 206 207 FRIEND_TEST(ConfigUpdateDimLimitTest, TestDimLimit); 208 }; 209 210 } // namespace statsd 211 } // namespace os 212 } // namespace android 213