• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define DEBUG false  // STOPSHIP if true
18 #include "Log.h"
19 
20 #include "EventMetricProducer.h"
21 
22 #include <limits.h>
23 #include <stdlib.h>
24 
25 #include "metrics/parsing_utils/metrics_manager_util.h"
26 #include "stats_log_util.h"
27 #include "stats_util.h"
28 
29 using android::util::FIELD_COUNT_REPEATED;
30 using android::util::FIELD_TYPE_BOOL;
31 using android::util::FIELD_TYPE_FLOAT;
32 using android::util::FIELD_TYPE_INT32;
33 using android::util::FIELD_TYPE_INT64;
34 using android::util::FIELD_TYPE_STRING;
35 using android::util::FIELD_TYPE_MESSAGE;
36 using android::util::ProtoOutputStream;
37 using std::map;
38 using std::string;
39 using std::unordered_map;
40 using std::vector;
41 using std::shared_ptr;
42 
43 namespace android {
44 namespace os {
45 namespace statsd {
46 
47 // for StatsLogReport
48 const int FIELD_ID_ID = 1;
49 const int FIELD_ID_EVENT_METRICS = 4;
50 const int FIELD_ID_IS_ACTIVE = 14;
51 // for EventMetricDataWrapper
52 const int FIELD_ID_DATA = 1;
53 // for EventMetricData
54 const int FIELD_ID_ELAPSED_TIMESTAMP_NANOS = 1;
55 const int FIELD_ID_ATOMS = 2;
56 
57 EventMetricProducer::EventMetricProducer(
58         const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
59         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
60         const uint64_t protoHash, const int64_t startTimeNs,
61         const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
62         const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
63         const vector<int>& slicedStateAtoms,
64         const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
65     : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, initialConditionCache, wizard,
66                      protoHash, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
67                      stateGroupMap) {
68     if (metric.links().size() > 0) {
69         for (const auto& link : metric.links()) {
70             Metric2Condition mc;
71             mc.conditionId = link.condition();
72             translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
73             translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
74             mMetric2ConditionLinks.push_back(mc);
75         }
76         mConditionSliced = true;
77     }
78     mProto = std::make_unique<ProtoOutputStream>();
79     VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
80          (long long)mBucketSizeNs, (long long)mTimeBaseNs);
81 }
82 
83 EventMetricProducer::~EventMetricProducer() {
84     VLOG("~EventMetricProducer() called");
85 }
86 
87 bool EventMetricProducer::onConfigUpdatedLocked(
88         const StatsdConfig& config, const int configIndex, const int metricIndex,
89         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
90         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
91         const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
92         const sp<EventMatcherWizard>& matcherWizard,
93         const vector<sp<ConditionTracker>>& allConditionTrackers,
94         const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
95         const unordered_map<int64_t, int>& metricToActivationMap,
96         unordered_map<int, vector<int>>& trackerToMetricMap,
97         unordered_map<int, vector<int>>& conditionToMetricMap,
98         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
99         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
100         vector<int>& metricsWithActivation) {
101     if (!MetricProducer::onConfigUpdatedLocked(
102                 config, configIndex, metricIndex, allAtomMatchingTrackers,
103                 oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
104                 allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
105                 trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
106                 deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
107         return false;
108     }
109 
110     const EventMetric& metric = config.event_metric(configIndex);
111     int trackerIndex;
112     // Update appropriate indices, specifically mConditionIndex and MetricsManager maps.
113     if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false,
114                                               allAtomMatchingTrackers, newAtomMatchingTrackerMap,
115                                               trackerToMetricMap, trackerIndex)) {
116         return false;
117     }
118 
119     if (metric.has_condition() &&
120         !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
121                                     metric.links(), allConditionTrackers, mConditionTrackerIndex,
122                                     conditionToMetricMap)) {
123         return false;
124     }
125     return true;
126 }
127 
128 void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
129     mProto->clear();
130     StatsdStats::getInstance().noteBucketDropped(mMetricId);
131 }
132 
133 void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
134                                                            const int64_t eventTime) {
135 }
136 
137 std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& protoOutput) {
138     size_t bufferSize = protoOutput.size();
139 
140     std::unique_ptr<std::vector<uint8_t>> buffer(new std::vector<uint8_t>(bufferSize));
141 
142     size_t pos = 0;
143     sp<android::util::ProtoReader> reader = protoOutput.data();
144     while (reader->readBuffer() != NULL) {
145         size_t toRead = reader->currentToRead();
146         std::memcpy(&((*buffer)[pos]), reader->readBuffer(), toRead);
147         pos += toRead;
148         reader->move(toRead);
149     }
150 
151     return buffer;
152 }
153 
154 void EventMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
155     mProto->clear();
156 }
157 
158 void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
159                                              const bool include_current_partial_bucket,
160                                              const bool erase_data,
161                                              const DumpLatency dumpLatency,
162                                              std::set<string> *str_set,
163                                              ProtoOutputStream* protoOutput) {
164     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
165     protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_IS_ACTIVE, isActiveLocked());
166     if (mProto->size() <= 0) {
167         return;
168     }
169 
170     size_t bufferSize = mProto->size();
171     VLOG("metric %lld dump report now... proto size: %zu ",
172         (long long)mMetricId, bufferSize);
173     std::unique_ptr<std::vector<uint8_t>> buffer = serializeProtoLocked(*mProto);
174 
175     protoOutput->write(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS,
176                        reinterpret_cast<char*>(buffer.get()->data()), buffer.get()->size());
177 
178     if (erase_data) {
179         mProto->clear();
180     }
181 }
182 
183 void EventMetricProducer::onConditionChangedLocked(const bool conditionMet,
184                                                    const int64_t eventTime) {
185     VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
186     mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
187 }
188 
189 void EventMetricProducer::onMatchedLogEventInternalLocked(
190         const size_t matcherIndex, const MetricDimensionKey& eventKey,
191         const ConditionKey& conditionKey, bool condition, const LogEvent& event,
192         const map<int, HashableDimensionKey>& statePrimaryKeys) {
193     if (!condition) {
194         return;
195     }
196 
197     uint64_t wrapperToken =
198             mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
199     const int64_t elapsedTimeNs = truncateTimestampIfNecessary(event);
200     mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS, (long long) elapsedTimeNs);
201 
202     uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
203     event.ToProto(*mProto);
204     mProto->end(eventToken);
205     mProto->end(wrapperToken);
206 }
207 
208 size_t EventMetricProducer::byteSizeLocked() const {
209     return mProto->bytesWritten();
210 }
211 
212 }  // namespace statsd
213 }  // namespace os
214 }  // namespace android
215