DurationMetricProducer.cpp revision 2b0f88678b2877a8e9f83cea60f097322b078367
1729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen/* 2729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * Copyright (C) 2017 The Android Open Source Project 3729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * 4729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * you may not use this file except in compliance with the License. 6729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * You may obtain a copy of the License at 7729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * 8729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * http://www.apache.org/licenses/LICENSE-2.0 9729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * 10729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * Unless required by applicable law or agreed to in writing, software 11729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * distributed under the License is distributed on an "AS IS" BASIS, 12729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * See the License for the specific language governing permissions and 14729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * limitations under the License. 15729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen */ 16729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 17729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#define DEBUG true 185154a379303ab90a2b2914676a4441917a329b5dYao Chen 19729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include "Log.h" 205154a379303ab90a2b2914676a4441917a329b5dYao Chen#include "DurationMetricProducer.h" 21729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include "stats_util.h" 22729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 23729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include <limits.h> 24729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include <stdlib.h> 25729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 262b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_BOOL; 272b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_FLOAT; 282b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT32; 292b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT64; 302b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_MESSAGE; 312b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::ProtoOutputStream; 32729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::string; 33729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::unordered_map; 34729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::vector; 35729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 36729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace android { 37729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace os { 38729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace statsd { 39729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 402b0f88678b2877a8e9f83cea60f097322b078367yro// for StatsLogReport 412b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_METRIC_ID = 1; 422b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_START_REPORT_NANOS = 2; 432b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_END_REPORT_NANOS = 3; 442b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION_METRICS = 6; 452b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricDataWrapper 462b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DATA = 1; 472b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricData 482b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DIMENSION = 1; 492b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_BUCKET_INFO = 2; 502b0f88678b2877a8e9f83cea60f097322b078367yro// for KeyValuePair 512b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_KEY = 1; 522b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_STR = 2; 532b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_INT = 3; 542b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_BOOL = 4; 552b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_FLOAT = 5; 562b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationBucketInfo 572b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_START_BUCKET_NANOS = 1; 582b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_END_BUCKET_NANOS = 2; 592b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION = 3; 602b0f88678b2877a8e9f83cea60f097322b078367yro 61729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao ChenDurationMetricProducer::DurationMetricProducer(const DurationMetric& metric, 62729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const int conditionIndex, const size_t startIndex, 63729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const size_t stopIndex, const size_t stopAllIndex, 645154a379303ab90a2b2914676a4441917a329b5dYao Chen const sp<ConditionWizard>& wizard, 6593fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen const vector<KeyMatcher>& internalDimension, 6693fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen const uint64_t startTimeNs) 6793fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen : MetricProducer(startTimeNs, conditionIndex, wizard), 68729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mMetric(metric), 69729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mStartIndex(startIndex), 70729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mStopIndex(stopIndex), 715154a379303ab90a2b2914676a4441917a329b5dYao Chen mStopAllIndex(stopAllIndex), 725154a379303ab90a2b2914676a4441917a329b5dYao Chen mInternalDimension(internalDimension) { 73729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract 74729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // them in the base class, because the proto generated CountMetric, and DurationMetric are 75729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // not related. Maybe we should add a template in the future?? 76729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) { 77729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mBucketSizeNs = metric.bucket().bucket_size_millis() * 1000000; 78729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } else { 79729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mBucketSizeNs = LLONG_MAX; 80729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 81729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 82729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: use UidMap if uid->pkg_name is required 83729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mDimension.insert(mDimension.begin(), metric.dimension().begin(), metric.dimension().end()); 84729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 85729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen if (metric.links().size() > 0) { 86729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(), 87729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen metric.links().end()); 88729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mConditionSliced = true; 89729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 90729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 912b0f88678b2877a8e9f83cea60f097322b078367yro startNewProtoOutputStream(mStartTimeNs); 922b0f88678b2877a8e9f83cea60f097322b078367yro 93729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen VLOG("metric %lld created. bucket size %lld start_time: %lld", metric.metric_id(), 94729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen (long long)mBucketSizeNs, (long long)mStartTimeNs); 95729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 96729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 97729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao ChenDurationMetricProducer::~DurationMetricProducer() { 98729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen VLOG("~DurationMetric() called"); 99729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 100729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 1012b0f88678b2877a8e9f83cea60f097322b078367yrovoid DurationMetricProducer::startNewProtoOutputStream(long long startTime) { 1022b0f88678b2877a8e9f83cea60f097322b078367yro mProto = std::make_unique<ProtoOutputStream>(); 1032b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT32 | FIELD_ID_METRIC_ID, mMetric.metric_id()); 1042b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime); 1052b0f88678b2877a8e9f83cea60f097322b078367yro mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS); 1062b0f88678b2877a8e9f83cea60f097322b078367yro} 1072b0f88678b2877a8e9f83cea60f097322b078367yro 1085154a379303ab90a2b2914676a4441917a329b5dYao Chenunique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker( 1092b0f88678b2877a8e9f83cea60f097322b078367yro vector<DurationBucket>& bucket) { 1105154a379303ab90a2b2914676a4441917a329b5dYao Chen switch (mMetric.type()) { 1115154a379303ab90a2b2914676a4441917a329b5dYao Chen case DurationMetric_AggregationType_DURATION_SUM: 1125154a379303ab90a2b2914676a4441917a329b5dYao Chen return make_unique<OringDurationTracker>(mWizard, mConditionTrackerIndex, 1135154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentBucketStartTimeNs, mBucketSizeNs, 1145154a379303ab90a2b2914676a4441917a329b5dYao Chen bucket); 1155154a379303ab90a2b2914676a4441917a329b5dYao Chen case DurationMetric_AggregationType_DURATION_MAX_SPARSE: 1165154a379303ab90a2b2914676a4441917a329b5dYao Chen return make_unique<MaxDurationTracker>(mWizard, mConditionTrackerIndex, 1175154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentBucketStartTimeNs, mBucketSizeNs, 1185154a379303ab90a2b2914676a4441917a329b5dYao Chen bucket); 1195154a379303ab90a2b2914676a4441917a329b5dYao Chen } 1205154a379303ab90a2b2914676a4441917a329b5dYao Chen} 1215154a379303ab90a2b2914676a4441917a329b5dYao Chen 122729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenvoid DurationMetricProducer::finish() { 123729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: write the StatsLogReport to dropbox using 124729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // DropboxWriter. 125729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 126729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 1275154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) { 128729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen VLOG("Metric %lld onSlicedConditionMayChange", mMetric.metric_id()); 129729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // Now for each of the on-going event, check if the condition has changed for them. 1305154a379303ab90a2b2914676a4441917a329b5dYao Chen flushIfNeeded(eventTime); 131729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (auto& pair : mCurrentSlicedDuration) { 1325154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->onSlicedConditionMayChange(eventTime); 133729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 134729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 135729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 1365154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::onConditionChanged(const bool conditionMet, const uint64_t eventTime) { 137729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen VLOG("Metric %lld onConditionChanged", mMetric.metric_id()); 138729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mCondition = conditionMet; 139729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: need to populate the condition change time from the event which triggers the condition 140729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // change, instead of using current time. 1415154a379303ab90a2b2914676a4441917a329b5dYao Chen 1425154a379303ab90a2b2914676a4441917a329b5dYao Chen flushIfNeeded(eventTime); 143729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (auto& pair : mCurrentSlicedDuration) { 1445154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->onConditionChanged(conditionMet, eventTime); 145729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 146729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 147729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 148729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenstatic void addDurationBucketsToReport(StatsLogReport_DurationMetricDataWrapper& wrapper, 149729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const vector<KeyValuePair>& key, 150729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const vector<DurationBucketInfo>& buckets) { 151729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen DurationMetricData* data = wrapper.add_data(); 152729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (const auto& kv : key) { 153729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen data->add_dimension()->CopyFrom(kv); 154729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 155729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (const auto& bucket : buckets) { 156729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen data->add_bucket_info()->CopyFrom(bucket); 1575154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("\t bucket [%lld - %lld] duration(ns): %lld", bucket.start_bucket_nanos(), 158729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen bucket.end_bucket_nanos(), bucket.duration_nanos()); 159729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 160729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 161729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 162729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao ChenStatsLogReport DurationMetricProducer::onDumpReport() { 1632b0f88678b2877a8e9f83cea60f097322b078367yro long long endTime = time(nullptr) * NS_PER_SEC; 1642b0f88678b2877a8e9f83cea60f097322b078367yro 165729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // Dump current bucket if it's stale. 166729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // If current bucket is still on-going, don't force dump current bucket. 167729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // In finish(), We can force dump current bucket. 1682b0f88678b2877a8e9f83cea60f097322b078367yro flushIfNeeded(endTime); 1692b0f88678b2877a8e9f83cea60f097322b078367yro VLOG("metric %lld dump report now...", mMetric.metric_id()); 170729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 171729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (const auto& pair : mPastBuckets) { 172729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const HashableDimensionKey& hashableKey = pair.first; 1732b0f88678b2877a8e9f83cea60f097322b078367yro VLOG(" dimension key %s", hashableKey.c_str()); 174729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen auto it = mDimensionKeyMap.find(hashableKey); 175729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen if (it == mDimensionKeyMap.end()) { 176729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen ALOGW("Dimension key %s not found?!?! skip...", hashableKey.c_str()); 177729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen continue; 178729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 1792b0f88678b2877a8e9f83cea60f097322b078367yro long long wrapperToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_DATA); 1802b0f88678b2877a8e9f83cea60f097322b078367yro 1812b0f88678b2877a8e9f83cea60f097322b078367yro // First fill dimension (KeyValuePairs). 1822b0f88678b2877a8e9f83cea60f097322b078367yro for (const auto& kv : it->second) { 1832b0f88678b2877a8e9f83cea60f097322b078367yro long long dimensionToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION); 1842b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT32 | FIELD_ID_KEY, kv.key()); 1852b0f88678b2877a8e9f83cea60f097322b078367yro if (kv.has_value_str()) { 1862b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT32 | FIELD_ID_VALUE_STR, kv.value_str()); 1872b0f88678b2877a8e9f83cea60f097322b078367yro } else if (kv.has_value_int()) { 1882b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_INT, kv.value_int()); 1892b0f88678b2877a8e9f83cea60f097322b078367yro } else if (kv.has_value_bool()) { 1902b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_BOOL | FIELD_ID_VALUE_BOOL, kv.value_bool()); 1912b0f88678b2877a8e9f83cea60f097322b078367yro } else if (kv.has_value_float()) { 1922b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_FLOAT | FIELD_ID_VALUE_FLOAT, kv.value_float()); 1932b0f88678b2877a8e9f83cea60f097322b078367yro } 1942b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(dimensionToken); 1952b0f88678b2877a8e9f83cea60f097322b078367yro } 1962b0f88678b2877a8e9f83cea60f097322b078367yro 1972b0f88678b2877a8e9f83cea60f097322b078367yro // Then fill bucket_info (DurationBucketInfo). 1982b0f88678b2877a8e9f83cea60f097322b078367yro for (const auto& bucket : pair.second) { 1992b0f88678b2877a8e9f83cea60f097322b078367yro long long bucketInfoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_BUCKET_INFO); 2002b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_NANOS, 2012b0f88678b2877a8e9f83cea60f097322b078367yro (long long)bucket.mBucketStartNs); 2022b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_NANOS, 2032b0f88678b2877a8e9f83cea60f097322b078367yro (long long)bucket.mBucketEndNs); 2042b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_DURATION, (long long)bucket.mDuration); 2052b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(bucketInfoToken); 2062b0f88678b2877a8e9f83cea60f097322b078367yro VLOG("\t bucket [%lld - %lld] duration: %lld", (long long)bucket.mBucketStartNs, 2072b0f88678b2877a8e9f83cea60f097322b078367yro (long long)bucket.mBucketEndNs, (long long)bucket.mDuration); 2082b0f88678b2877a8e9f83cea60f097322b078367yro } 2092b0f88678b2877a8e9f83cea60f097322b078367yro 2102b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(wrapperToken); 211729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 2122b0f88678b2877a8e9f83cea60f097322b078367yro 2132b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(mProtoToken); 2142b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_REPORT_NANOS, 2152b0f88678b2877a8e9f83cea60f097322b078367yro (long long)mCurrentBucketStartTimeNs); 2162b0f88678b2877a8e9f83cea60f097322b078367yro 2172b0f88678b2877a8e9f83cea60f097322b078367yro std::unique_ptr<uint8_t[]> buffer = serializeProto(); 2182b0f88678b2877a8e9f83cea60f097322b078367yro 2192b0f88678b2877a8e9f83cea60f097322b078367yro startNewProtoOutputStream(endTime); 2202b0f88678b2877a8e9f83cea60f097322b078367yro mPastBuckets.clear(); 2212b0f88678b2877a8e9f83cea60f097322b078367yro 2222b0f88678b2877a8e9f83cea60f097322b078367yro // TODO: Once we migrate all MetricProducers to use ProtoOutputStream, we should return this: 2232b0f88678b2877a8e9f83cea60f097322b078367yro // return std::move(buffer); 2242b0f88678b2877a8e9f83cea60f097322b078367yro return StatsLogReport(); 2252b0f88678b2877a8e9f83cea60f097322b078367yro} 226729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2275154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::flushIfNeeded(uint64_t eventTime) { 2285154a379303ab90a2b2914676a4441917a329b5dYao Chen if (mCurrentBucketStartTimeNs + mBucketSizeNs > eventTime) { 229729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen return; 230729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 231729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2325154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("flushing..........."); 2335154a379303ab90a2b2914676a4441917a329b5dYao Chen for (auto it = mCurrentSlicedDuration.begin(); it != mCurrentSlicedDuration.end(); ++it) { 2345154a379303ab90a2b2914676a4441917a329b5dYao Chen if (it->second->flushIfNeeded(eventTime)) { 2355154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("erase bucket for key %s", it->first.c_str()); 2365154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentSlicedDuration.erase(it); 237729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 238729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 239729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2405154a379303ab90a2b2914676a4441917a329b5dYao Chen int numBucketsForward = (eventTime - mCurrentBucketStartTimeNs) / mBucketSizeNs; 2415154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentBucketStartTimeNs += numBucketsForward * mBucketSizeNs; 242729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 243729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2445154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::onMatchedLogEventInternal( 2455154a379303ab90a2b2914676a4441917a329b5dYao Chen const size_t matcherIndex, const HashableDimensionKey& eventKey, 2465154a379303ab90a2b2914676a4441917a329b5dYao Chen const map<string, HashableDimensionKey>& conditionKeys, bool condition, 247b3dda41a5a48ddfa44dc8fa939ab495926a0195dChenjie Yu const LogEvent& event, bool scheduledPull) { 2485154a379303ab90a2b2914676a4441917a329b5dYao Chen flushIfNeeded(event.GetTimestampNs()); 249729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2505154a379303ab90a2b2914676a4441917a329b5dYao Chen if (matcherIndex == mStopAllIndex) { 2515154a379303ab90a2b2914676a4441917a329b5dYao Chen for (auto& pair : mCurrentSlicedDuration) { 2525154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->noteStopAll(event.GetTimestampNs()); 2535154a379303ab90a2b2914676a4441917a329b5dYao Chen } 254729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen return; 255729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 256729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2575154a379303ab90a2b2914676a4441917a329b5dYao Chen HashableDimensionKey atomKey = getHashableKey(getDimensionKey(event, mInternalDimension)); 258729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2595154a379303ab90a2b2914676a4441917a329b5dYao Chen if (mCurrentSlicedDuration.find(eventKey) == mCurrentSlicedDuration.end()) { 2605154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentSlicedDuration[eventKey] = createDurationTracker(mPastBuckets[eventKey]); 2615154a379303ab90a2b2914676a4441917a329b5dYao Chen } 262729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2635154a379303ab90a2b2914676a4441917a329b5dYao Chen auto it = mCurrentSlicedDuration.find(eventKey); 264729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2655154a379303ab90a2b2914676a4441917a329b5dYao Chen if (matcherIndex == mStartIndex) { 2665154a379303ab90a2b2914676a4441917a329b5dYao Chen it->second->noteStart(atomKey, condition, event.GetTimestampNs(), conditionKeys); 2675154a379303ab90a2b2914676a4441917a329b5dYao Chen } else if (matcherIndex == mStopIndex) { 2685154a379303ab90a2b2914676a4441917a329b5dYao Chen it->second->noteStop(atomKey, event.GetTimestampNs()); 269729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 270729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 271729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 27269007c82625dd8b19bd68d1031191e2ff83b5f49yrosize_t DurationMetricProducer::byteSize() { 2732b0f88678b2877a8e9f83cea60f097322b078367yro size_t totalSize = 0; 2742b0f88678b2877a8e9f83cea60f097322b078367yro for (const auto& pair : mPastBuckets) { 2752b0f88678b2877a8e9f83cea60f097322b078367yro totalSize += pair.second.size() * kBucketSize; 2762b0f88678b2877a8e9f83cea60f097322b078367yro } 2772b0f88678b2877a8e9f83cea60f097322b078367yro return totalSize; 27869007c82625dd8b19bd68d1031191e2ff83b5f49yro} 27969007c82625dd8b19bd68d1031191e2ff83b5f49yro 280729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace statsd 281729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace os 282729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace android 283