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