blob: 8df30d3de28441577efd879b2a7fdf2ea8c1cabb [file] [log] [blame]
Chenjie Yub3dda412017-10-24 13:41:59 -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#pragma once
18
Chenjie Yu6736c892017-11-09 10:50:09 -080019#include <gtest/gtest_prod.h>
Chenjie Yub3dda412017-10-24 13:41:59 -070020#include <utils/threads.h>
21#include <list>
Bookatzde1b55622017-12-14 18:38:27 -080022#include "../anomaly/AnomalyTracker.h"
Chenjie Yub3dda412017-10-24 13:41:59 -070023#include "../condition/ConditionTracker.h"
24#include "../external/PullDataReceiver.h"
25#include "../external/StatsPullerManager.h"
Chenjie Yub3dda412017-10-24 13:41:59 -070026#include "MetricProducer.h"
Chenjie Yub3dda412017-10-24 13:41:59 -070027#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
28
29namespace android {
30namespace os {
31namespace statsd {
32
yro2b0f8862017-11-06 14:27:31 -080033struct ValueBucket {
34 int64_t mBucketStartNs;
35 int64_t mBucketEndNs;
36 int64_t mValue;
37};
38
Chenjie Yub3dda412017-10-24 13:41:59 -070039class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
40public:
Yao Chenb3561512017-11-21 18:07:17 -080041 ValueMetricProducer(const ConfigKey& key, const ValueMetric& valueMetric,
42 const int conditionIndex, const sp<ConditionWizard>& wizard,
Yangster-mac15f6bbc2018-04-08 11:52:26 -070043 const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs);
Chenjie Yub3dda412017-10-24 13:41:59 -070044
45 virtual ~ValueMetricProducer();
46
Chenjie Yub3dda412017-10-24 13:41:59 -070047 void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data) override;
yro2b0f8862017-11-06 14:27:31 -080048
David Chen27785a82018-01-19 17:06:45 -080049 // ValueMetric needs special logic if it's a pulled atom.
Yangster-macb142cc82018-03-30 15:22:08 -070050 void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
David Chen27785a82018-01-19 17:06:45 -080051 const int64_t version) override {
52 std::lock_guard<std::mutex> lock(mMutex);
53
54 if (mPullTagId != -1) {
55 vector<shared_ptr<LogEvent>> allData;
Chenjie Yu1a0a9412018-03-28 10:07:22 -070056 mStatsPullerManager->Pull(mPullTagId, eventTimeNs, &allData);
David Chen27785a82018-01-19 17:06:45 -080057 if (allData.size() == 0) {
58 // This shouldn't happen since this valuemetric is not useful now.
59 }
60
61 // Pretend the pulled data occurs right before the app upgrade event.
62 mCondition = false;
63 for (const auto& data : allData) {
Yangster-mac330af582018-02-08 15:24:38 -080064 data->setElapsedTimestampNs(eventTimeNs - 1);
David Chen27785a82018-01-19 17:06:45 -080065 onMatchedLogEventLocked(0, *data);
66 }
67
68 flushCurrentBucketLocked(eventTimeNs);
69 mCurrentBucketStartTimeNs = eventTimeNs;
70
71 mCondition = true;
72 for (const auto& data : allData) {
Yangster-mac330af582018-02-08 15:24:38 -080073 data->setElapsedTimestampNs(eventTimeNs);
David Chen27785a82018-01-19 17:06:45 -080074 onMatchedLogEventLocked(0, *data);
75 }
76 } else { // For pushed value metric, we simply flush and reset the current bucket start.
77 flushCurrentBucketLocked(eventTimeNs);
78 mCurrentBucketStartTimeNs = eventTimeNs;
79 }
80 };
81
Chenjie Yub3dda412017-10-24 13:41:59 -070082protected:
Yangsterf2bee6f2017-11-29 12:01:05 -080083 void onMatchedLogEventInternalLocked(
Yangster-mac93694462018-01-22 20:49:31 -080084 const size_t matcherIndex, const MetricDimensionKey& eventKey,
Yangster-mac20877162017-12-22 17:19:39 -080085 const ConditionKey& conditionKey, bool condition,
Chenjie Yua7259ab2017-12-10 08:31:05 -080086 const LogEvent& event) override;
yro2b0f8862017-11-06 14:27:31 -080087
Chenjie Yub3dda412017-10-24 13:41:59 -070088private:
Yangster-macb142cc82018-03-30 15:22:08 -070089 void onDumpReportLocked(const int64_t dumpTimeNs,
Yangster-mace68f3a52018-04-04 00:01:43 -070090 const bool include_current_partial_bucket,
Yao Chen288c6002017-12-12 13:43:18 -080091 android::util::ProtoOutputStream* protoOutput) override;
Yangsterf2bee6f2017-11-29 12:01:05 -080092
93 // Internal interface to handle condition change.
Yangster-macb142cc82018-03-30 15:22:08 -070094 void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
Yangsterf2bee6f2017-11-29 12:01:05 -080095
96 // Internal interface to handle sliced condition change.
Yangster-macb142cc82018-03-30 15:22:08 -070097 void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
Yangsterf2bee6f2017-11-29 12:01:05 -080098
99 // Internal function to calculate the current used bytes.
100 size_t byteSizeLocked() const override;
101
Yangster-maca78d0082018-03-12 12:02:56 -0700102 void dumpStatesLocked(FILE* out, bool verbose) const override;
Yao Chen884c8c12018-01-26 10:36:25 -0800103
Yangsterf2bee6f2017-11-29 12:01:05 -0800104 // Util function to flush the old packet.
Yangster-macb142cc82018-03-30 15:22:08 -0700105 void flushIfNeededLocked(const int64_t& eventTime) override;
David Chen27785a82018-01-19 17:06:45 -0800106
Yangster-macb142cc82018-03-30 15:22:08 -0700107 void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
Yangsterf2bee6f2017-11-29 12:01:05 -0800108
Yangster-macb142cc82018-03-30 15:22:08 -0700109 void dropDataLocked(const int64_t dropTimeNs) override;
Yao Chen06dba5d2018-01-26 13:38:16 -0800110
Yangster-maca7fb12d2018-01-03 17:17:20 -0800111 const FieldMatcher mValueField;
Chenjie Yub3dda412017-10-24 13:41:59 -0700112
Chenjie Yu6736c892017-11-09 10:50:09 -0800113 std::shared_ptr<StatsPullerManager> mStatsPullerManager;
114
115 // for testing
Yao Chenb3561512017-11-21 18:07:17 -0800116 ValueMetricProducer(const ConfigKey& key, const ValueMetric& valueMetric,
117 const int conditionIndex, const sp<ConditionWizard>& wizard,
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700118 const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs,
Chenjie Yu6736c892017-11-09 10:50:09 -0800119 std::shared_ptr<StatsPullerManager> statsPullerManager);
Chenjie Yub3dda412017-10-24 13:41:59 -0700120
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700121 // tagId for pulled data. -1 if this is not pulled
122 const int mPullTagId;
Chenjie Yub3dda412017-10-24 13:41:59 -0700123
Yao Chen8a8d16c2018-02-08 14:50:40 -0800124 int mField;
125
Chenjie Yub3dda412017-10-24 13:41:59 -0700126 // internal state of a bucket.
127 typedef struct {
Chenjie Yua7259ab2017-12-10 08:31:05 -0800128 // Pulled data always come in pair of <start, end>. This holds the value
129 // for start. The diff (end - start) is added to sum.
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700130 int64_t start;
Chenjie Yua7259ab2017-12-10 08:31:05 -0800131 // Whether the start data point is updated
132 bool startUpdated;
133 // If end data point comes before the start, record this pair as tainted
134 // and the value is not added to the running sum.
135 int tainted;
136 // Running sum of known pairs in this bucket
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700137 int64_t sum;
Chenjie Yuae63b0a2018-04-10 14:59:31 -0700138 // If this dimension has any non-tainted value. If not, don't report the
139 // dimension.
140 bool hasValue;
Chenjie Yub3dda412017-10-24 13:41:59 -0700141 } Interval;
142
Yangster-mac93694462018-01-22 20:49:31 -0800143 std::unordered_map<MetricDimensionKey, Interval> mCurrentSlicedBucket;
Chenjie Yub3dda412017-10-24 13:41:59 -0700144
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700145 std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket;
David Chen27785a82018-01-19 17:06:45 -0800146
Chenjie Yub3dda412017-10-24 13:41:59 -0700147 // Save the past buckets and we can clear when the StatsLogReport is dumped.
yro2b0f8862017-11-06 14:27:31 -0800148 // TODO: Add a lock to mPastBuckets.
Yangster-mac93694462018-01-22 20:49:31 -0800149 std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>> mPastBuckets;
Chenjie Yub3dda412017-10-24 13:41:59 -0700150
David Chen81245fd2018-04-12 14:33:37 -0700151 // Pairs of (elapsed start, elapsed end) denoting buckets that were skipped.
152 std::list<std::pair<int64_t, int64_t>> mSkippedBuckets;
153
154 const int64_t mMinBucketSizeNs;
155
Yangsterf2bee6f2017-11-29 12:01:05 -0800156 // Util function to check whether the specified dimension hits the guardrail.
Yangster-mac93694462018-01-22 20:49:31 -0800157 bool hitGuardRailLocked(const MetricDimensionKey& newKey);
Yao Chenb3561512017-11-21 18:07:17 -0800158
Yangster-mace2cd6d52017-11-09 20:38:30 -0800159 static const size_t kBucketSize = sizeof(ValueBucket{});
Chenjie Yu6736c892017-11-09 10:50:09 -0800160
Chenjie Yuc5875052018-03-09 10:13:11 -0800161 const size_t mDimensionSoftLimit;
162
163 const size_t mDimensionHardLimit;
164
Chenjie Yu6736c892017-11-09 10:50:09 -0800165 FRIEND_TEST(ValueMetricProducerTest, TestNonDimensionalEvents);
166 FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
David Chen27785a82018-01-19 17:06:45 -0800167 FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade);
168 FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade);
Chenjie Yu6736c892017-11-09 10:50:09 -0800169 FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
Bookatzde1b55622017-12-14 18:38:27 -0800170 FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
Chenjie Yu6d370f42018-03-25 14:57:30 -0700171 FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
172 FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition);
173 FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2);
174 FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition3);
Chenjie Yub3dda412017-10-24 13:41:59 -0700175};
176
177} // namespace statsd
178} // namespace os
179} // namespace android