blob: 842581ed1a9f41b49caadd5949a861eddc2f4152 [file] [log] [blame]
Yao Chen5154a372017-10-30 22:57:06 -07001/*
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#ifndef DURATION_TRACKER_H
18#define DURATION_TRACKER_H
19
Bookatz857aaa52017-12-19 15:29:06 -080020#include "anomaly/DurationAnomalyTracker.h"
Yao Chen5154a372017-10-30 22:57:06 -070021#include "condition/ConditionWizard.h"
Yao Chenb3561512017-11-21 18:07:17 -080022#include "config/ConfigKey.h"
Yao Chen5154a372017-10-30 22:57:06 -070023#include "stats_util.h"
24
Yao Chen5154a372017-10-30 22:57:06 -070025namespace android {
26namespace os {
27namespace statsd {
28
29enum DurationState {
30 kStopped = 0, // The event is stopped.
31 kStarted = 1, // The event is on going.
32 kPaused = 2, // The event is started, but condition is false, clock is paused. When condition
33 // turns to true, kPaused will become kStarted.
34};
35
36// Hold duration information for one atom level duration in current on-going bucket.
37struct DurationInfo {
38 DurationState state;
Yao Chen0ea19902017-11-15 15:44:45 -080039
40 // the number of starts seen.
41 int32_t startCount;
42
Yao Chen5154a372017-10-30 22:57:06 -070043 // most recent start time.
44 int64_t lastStartTime;
45 // existing duration in current bucket.
46 int64_t lastDuration;
47 // TODO: Optimize the way we track sliced condition in duration metrics.
48 // cache the HashableDimensionKeys we need to query the condition for this duration event.
49 ConditionKey conditionKeys;
50
Yao Chen0ea19902017-11-15 15:44:45 -080051 DurationInfo() : state(kStopped), startCount(0), lastStartTime(0), lastDuration(0){};
Yao Chen5154a372017-10-30 22:57:06 -070052};
53
yro2b0f8862017-11-06 14:27:31 -080054struct DurationBucket {
Yangster-mace2cd6d52017-11-09 20:38:30 -080055 uint64_t mBucketStartNs;
56 uint64_t mBucketEndNs;
57 uint64_t mDuration;
58 uint64_t mBucketNum;
yro2b0f8862017-11-06 14:27:31 -080059};
60
Yao Chen5154a372017-10-30 22:57:06 -070061class DurationTracker {
62public:
Yangster-mac94e197c2018-01-02 16:03:03 -080063 DurationTracker(const ConfigKey& key, const int64_t& id, const HashableDimensionKey& eventKey,
Yao Chenb3561512017-11-21 18:07:17 -080064 sp<ConditionWizard> wizard, int conditionIndex, bool nesting,
65 uint64_t currentBucketStartNs, uint64_t bucketSizeNs,
Bookatz857aaa52017-12-19 15:29:06 -080066 const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
Yao Chenb3561512017-11-21 18:07:17 -080067 : mConfigKey(key),
Yangster-mac94e197c2018-01-02 16:03:03 -080068 mTrackerId(id),
Yao Chenb3561512017-11-21 18:07:17 -080069 mEventKey(eventKey),
Yangster-mace2cd6d52017-11-09 20:38:30 -080070 mWizard(wizard),
Yao Chen5154a372017-10-30 22:57:06 -070071 mConditionTrackerIndex(conditionIndex),
Yao Chen5154a372017-10-30 22:57:06 -070072 mBucketSizeNs(bucketSizeNs),
Yao Chen0ea19902017-11-15 15:44:45 -080073 mNested(nesting),
74 mCurrentBucketStartTimeNs(currentBucketStartNs),
Yangster-mace2cd6d52017-11-09 20:38:30 -080075 mDuration(0),
76 mCurrentBucketNum(0),
77 mAnomalyTrackers(anomalyTrackers){};
Yangster7c334a12017-11-22 14:24:24 -080078
Yao Chen5154a372017-10-30 22:57:06 -070079 virtual ~DurationTracker(){};
Yangster7c334a12017-11-22 14:24:24 -080080
Yao Chen5154a372017-10-30 22:57:06 -070081 virtual void noteStart(const HashableDimensionKey& key, bool condition,
82 const uint64_t eventTime, const ConditionKey& conditionKey) = 0;
Yao Chen0ea19902017-11-15 15:44:45 -080083 virtual void noteStop(const HashableDimensionKey& key, const uint64_t eventTime,
84 const bool stopAll) = 0;
Yao Chen5154a372017-10-30 22:57:06 -070085 virtual void noteStopAll(const uint64_t eventTime) = 0;
Yangster7c334a12017-11-22 14:24:24 -080086
Yao Chen5154a372017-10-30 22:57:06 -070087 virtual void onSlicedConditionMayChange(const uint64_t timestamp) = 0;
88 virtual void onConditionChanged(bool condition, const uint64_t timestamp) = 0;
Yangster7c334a12017-11-22 14:24:24 -080089
Yao Chen5154a372017-10-30 22:57:06 -070090 // Flush stale buckets if needed, and return true if the tracker has no on-going duration
91 // events, so that the owner can safely remove the tracker.
Yao Chenf60e0ba2017-11-29 15:06:41 -080092 virtual bool flushIfNeeded(
93 uint64_t timestampNs,
94 std::unordered_map<HashableDimensionKey, std::vector<DurationBucket>>* output) = 0;
Yao Chen5154a372017-10-30 22:57:06 -070095
Yangster-mace2cd6d52017-11-09 20:38:30 -080096 // Predict the anomaly timestamp given the current status.
Bookatz857aaa52017-12-19 15:29:06 -080097 virtual int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
Yangster-mace2cd6d52017-11-09 20:38:30 -080098 const uint64_t currentTimestamp) const = 0;
99
Yao Chen5154a372017-10-30 22:57:06 -0700100protected:
Yangster-mace2cd6d52017-11-09 20:38:30 -0800101 // Starts the anomaly alarm.
102 void startAnomalyAlarm(const uint64_t eventTime) {
103 for (auto& anomalyTracker : mAnomalyTrackers) {
104 if (anomalyTracker != nullptr) {
105 anomalyTracker->startAlarm(mEventKey,
106 predictAnomalyTimestampNs(*anomalyTracker, eventTime));
107 }
108 }
109 }
110
111 // Stops the anomaly alarm.
112 void stopAnomalyAlarm() {
113 for (auto& anomalyTracker : mAnomalyTrackers) {
114 if (anomalyTracker != nullptr) {
115 anomalyTracker->stopAlarm(mEventKey);
116 }
117 }
118 }
119
120 void addPastBucketToAnomalyTrackers(const int64_t& bucketValue, const int64_t& bucketNum) {
121 for (auto& anomalyTracker : mAnomalyTrackers) {
122 if (anomalyTracker != nullptr) {
123 anomalyTracker->addPastBucket(mEventKey, bucketValue, bucketNum);
124 }
125 }
126 }
127
128 void detectAndDeclareAnomaly(const uint64_t& timestamp, const int64_t& currBucketNum,
129 const int64_t& currentBucketValue) {
130 for (auto& anomalyTracker : mAnomalyTrackers) {
131 if (anomalyTracker != nullptr) {
132 anomalyTracker->detectAndDeclareAnomaly(timestamp, currBucketNum, mEventKey,
133 currentBucketValue);
134 }
135 }
136 }
137
138 void declareAnomalyIfAlarmExpired(const uint64_t& timestamp) {
139 for (auto& anomalyTracker : mAnomalyTrackers) {
140 if (anomalyTracker != nullptr) {
141 anomalyTracker->declareAnomalyIfAlarmExpired(mEventKey, timestamp);
142 }
143 }
144 }
Yao Chenb3561512017-11-21 18:07:17 -0800145 // A reference to the DurationMetricProducer's config key.
146 const ConfigKey& mConfigKey;
147
Yangster-mac94e197c2018-01-02 16:03:03 -0800148 const int64_t mTrackerId;
Yangster-mace2cd6d52017-11-09 20:38:30 -0800149
150 HashableDimensionKey mEventKey;
151
Yao Chen5154a372017-10-30 22:57:06 -0700152 sp<ConditionWizard> mWizard;
153
Yao Chen0ea19902017-11-15 15:44:45 -0800154 const int mConditionTrackerIndex;
155
156 const int64_t mBucketSizeNs;
157
158 const bool mNested;
Yao Chen5154a372017-10-30 22:57:06 -0700159
160 uint64_t mCurrentBucketStartTimeNs;
161
Yao Chen5154a372017-10-30 22:57:06 -0700162 int64_t mDuration; // current recorded duration result
Yangster-mace2cd6d52017-11-09 20:38:30 -0800163
164 uint64_t mCurrentBucketNum;
165
Bookatz857aaa52017-12-19 15:29:06 -0800166 std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers;
Yangster-mace2cd6d52017-11-09 20:38:30 -0800167
168 FRIEND_TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp);
169 FRIEND_TEST(OringDurationTrackerTest, TestAnomalyDetection);
Yao Chen5154a372017-10-30 22:57:06 -0700170};
171
172} // namespace statsd
173} // namespace os
174} // namespace android
175
yro2b0f8862017-11-06 14:27:31 -0800176#endif // DURATION_TRACKER_H