blob: cbae1d343f034ccff72eb886a6ecb08355e74bba [file] [log] [blame]
Yao Chen5110bed2017-10-23 12:50:02 -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#define DEBUG true // STOPSHIP if true
18#include "Log.h"
19
20#include "EventMetricProducer.h"
21#include "stats_util.h"
22
Yao Chen5110bed2017-10-23 12:50:02 -070023#include <limits.h>
24#include <stdlib.h>
25
yro24809bd2017-10-31 23:06:53 -070026using namespace android::util;
Yao Chen5110bed2017-10-23 12:50:02 -070027using android::util::ProtoOutputStream;
28using std::map;
29using std::string;
30using std::unordered_map;
31using std::vector;
32
33namespace android {
34namespace os {
35namespace statsd {
36
37// for StatsLogReport
38const int FIELD_ID_METRIC_ID = 1;
39const int FIELD_ID_START_REPORT_NANOS = 2;
yro24809bd2017-10-31 23:06:53 -070040const int FIELD_ID_END_REPORT_NANOS = 3;
Yao Chen5110bed2017-10-23 12:50:02 -070041const int FIELD_ID_EVENT_METRICS = 4;
yro24809bd2017-10-31 23:06:53 -070042// for EventMetricDataWrapper
43const int FIELD_ID_DATA = 1;
Yao Chen5110bed2017-10-23 12:50:02 -070044// for EventMetricData
45const int FIELD_ID_TIMESTAMP_NANOS = 1;
46const int FIELD_ID_STATS_EVENTS = 2;
Yao Chen5110bed2017-10-23 12:50:02 -070047
48EventMetricProducer::EventMetricProducer(const EventMetric& metric, const int conditionIndex,
49 const sp<ConditionWizard>& wizard)
50 // TODO: Pass in the start time from MetricsManager, instead of calling time() here.
51 : MetricProducer((time(nullptr) * NANO_SECONDS_IN_A_SECOND), conditionIndex, wizard),
52 mMetric(metric) {
53 if (metric.links().size() > 0) {
54 mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(),
55 metric.links().end());
56 mConditionSliced = true;
57 }
58
59 startNewProtoOutputStream(mStartTimeNs);
60
61 VLOG("metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(),
62 (long long)mBucketSizeNs, (long long)mStartTimeNs);
63}
64
65EventMetricProducer::~EventMetricProducer() {
66 VLOG("~EventMetricProducer() called");
67}
68
69void EventMetricProducer::startNewProtoOutputStream(long long startTime) {
70 mProto = std::make_unique<ProtoOutputStream>();
71 // TODO: We need to auto-generate the field IDs for StatsLogReport, EventMetricData,
72 // and StatsEvent.
yro24809bd2017-10-31 23:06:53 -070073 mProto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, mMetric.metric_id());
74 mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime);
75 mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS);
Yao Chen5110bed2017-10-23 12:50:02 -070076}
77
78void EventMetricProducer::finish() {
79}
80
Yao Chen5154a372017-10-30 22:57:06 -070081void EventMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) {
Yao Chen5110bed2017-10-23 12:50:02 -070082}
83
84StatsLogReport EventMetricProducer::onDumpReport() {
85 long long endTime = time(nullptr) * NANO_SECONDS_IN_A_SECOND;
86 mProto->end(mProtoToken);
yro24809bd2017-10-31 23:06:53 -070087 mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_REPORT_NANOS, endTime);
Yao Chen5110bed2017-10-23 12:50:02 -070088
89 size_t bufferSize = mProto->size();
90 VLOG("metric %lld dump report now... proto size: %zu ", mMetric.metric_id(), bufferSize);
91 std::unique_ptr<uint8_t[]> buffer(new uint8_t[bufferSize]);
92 size_t pos = 0;
93 auto it = mProto->data();
94 while (it.readBuffer() != NULL) {
95 size_t toRead = it.currentToRead();
96 std::memcpy(&buffer[pos], it.readBuffer(), toRead);
97 pos += toRead;
98 it.rp()->move(toRead);
99 }
100
101 startNewProtoOutputStream(endTime);
102
103 // TODO: Once we migrate all MetricProducers to use ProtoOutputStream, we should return this:
104 // return std::move(buffer);
105 return StatsLogReport();
106}
107
Yao Chen5154a372017-10-30 22:57:06 -0700108void EventMetricProducer::onConditionChanged(const bool conditionMet, const uint64_t eventTime) {
Yao Chen5110bed2017-10-23 12:50:02 -0700109 VLOG("Metric %lld onConditionChanged", mMetric.metric_id());
110 mCondition = conditionMet;
111}
112
113void EventMetricProducer::onMatchedLogEventInternal(
114 const size_t matcherIndex, const HashableDimensionKey& eventKey,
115 const std::map<std::string, HashableDimensionKey>& conditionKey, bool condition,
Chenjie Yub3dda412017-10-24 13:41:59 -0700116 const LogEvent& event, bool scheduledPull) {
Yao Chen5110bed2017-10-23 12:50:02 -0700117
118 if (!condition) {
119 return;
120 }
121
yro24809bd2017-10-31 23:06:53 -0700122 long long wrapperToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_DATA);
123 mProto->write(FIELD_TYPE_INT64 | FIELD_ID_TIMESTAMP_NANOS, (long long)event.GetTimestampNs());
124 long long eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_STATS_EVENTS);
Yao Chen5110bed2017-10-23 12:50:02 -0700125 event.ToProto(*mProto);
126 mProto->end(eventToken);
127 mProto->end(wrapperToken);
128}
129
yro69007c82017-10-26 20:42:57 -0700130size_t EventMetricProducer::byteSize() {
131 return mProto->size();
132}
133
Yao Chen5110bed2017-10-23 12:50:02 -0700134} // namespace statsd
135} // namespace os
136} // namespace android