DurationMetricProducer.cpp revision cfed20bce8a66bde6ad0d74a44fc0a2764b2886d
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 26b0378b093d9b937fe9a731a601d670d50f263078yrousing android::util::FIELD_COUNT_REPEATED; 272b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_BOOL; 282b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_FLOAT; 292b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT32; 302b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT64; 312b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_MESSAGE; 32d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-macusing android::util::FIELD_TYPE_STRING; 332b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::ProtoOutputStream; 34729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::string; 35729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::unordered_map; 36729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::vector; 37729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 38729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace android { 39729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace os { 40729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace statsd { 41729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 422b0f88678b2877a8e9f83cea60f097322b078367yro// for StatsLogReport 43d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-macconst int FIELD_ID_NAME = 1; 442b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_START_REPORT_NANOS = 2; 452b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_END_REPORT_NANOS = 3; 462b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION_METRICS = 6; 472b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricDataWrapper 482b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DATA = 1; 492b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricData 502b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DIMENSION = 1; 512b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_BUCKET_INFO = 2; 522b0f88678b2877a8e9f83cea60f097322b078367yro// for KeyValuePair 532b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_KEY = 1; 542b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_STR = 2; 552b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_INT = 3; 562b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_BOOL = 4; 572b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_VALUE_FLOAT = 5; 582b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationBucketInfo 592b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_START_BUCKET_NANOS = 1; 602b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_END_BUCKET_NANOS = 2; 612b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION = 3; 622b0f88678b2877a8e9f83cea60f097322b078367yro 63729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao ChenDurationMetricProducer::DurationMetricProducer(const DurationMetric& metric, 64729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const int conditionIndex, const size_t startIndex, 65729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const size_t stopIndex, const size_t stopAllIndex, 660ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen const bool nesting, 675154a379303ab90a2b2914676a4441917a329b5dYao Chen const sp<ConditionWizard>& wizard, 6893fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen const vector<KeyMatcher>& internalDimension, 6993fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen const uint64_t startTimeNs) 7093fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen : MetricProducer(startTimeNs, conditionIndex, wizard), 71729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mMetric(metric), 72729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mStartIndex(startIndex), 73729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mStopIndex(stopIndex), 745154a379303ab90a2b2914676a4441917a329b5dYao Chen mStopAllIndex(stopAllIndex), 750ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen mNested(nesting), 765154a379303ab90a2b2914676a4441917a329b5dYao Chen mInternalDimension(internalDimension) { 77729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract 78729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // them in the base class, because the proto generated CountMetric, and DurationMetric are 79729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // not related. Maybe we should add a template in the future?? 80729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) { 81729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mBucketSizeNs = metric.bucket().bucket_size_millis() * 1000000; 82729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } else { 83729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mBucketSizeNs = LLONG_MAX; 84729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 85729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 86729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: use UidMap if uid->pkg_name is required 87729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mDimension.insert(mDimension.begin(), metric.dimension().begin(), metric.dimension().end()); 88729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 89729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen if (metric.links().size() > 0) { 90729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(), 91729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen metric.links().end()); 92729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mConditionSliced = true; 93729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 94729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 952b0f88678b2877a8e9f83cea60f097322b078367yro startNewProtoOutputStream(mStartTimeNs); 962b0f88678b2877a8e9f83cea60f097322b078367yro 97d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-mac VLOG("metric %s created. bucket size %lld start_time: %lld", metric.name().c_str(), 98729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen (long long)mBucketSizeNs, (long long)mStartTimeNs); 99729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 100729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 101729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao ChenDurationMetricProducer::~DurationMetricProducer() { 102729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen VLOG("~DurationMetric() called"); 103729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 104729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 1052b0f88678b2877a8e9f83cea60f097322b078367yrovoid DurationMetricProducer::startNewProtoOutputStream(long long startTime) { 1062b0f88678b2877a8e9f83cea60f097322b078367yro mProto = std::make_unique<ProtoOutputStream>(); 107d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-mac mProto->write(FIELD_TYPE_STRING | FIELD_ID_NAME, mMetric.name()); 1082b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, startTime); 1092b0f88678b2877a8e9f83cea60f097322b078367yro mProtoToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS); 1102b0f88678b2877a8e9f83cea60f097322b078367yro} 1112b0f88678b2877a8e9f83cea60f097322b078367yro 1125154a379303ab90a2b2914676a4441917a329b5dYao Chenunique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker( 1132b0f88678b2877a8e9f83cea60f097322b078367yro vector<DurationBucket>& bucket) { 114cfed20bce8a66bde6ad0d74a44fc0a2764b2886dStefan Lafon switch (mMetric.aggregation_type()) { 115cfed20bce8a66bde6ad0d74a44fc0a2764b2886dStefan Lafon case DurationMetric_AggregationType_SUM: 1160ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen return make_unique<OringDurationTracker>(mWizard, mConditionTrackerIndex, mNested, 1175154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentBucketStartTimeNs, mBucketSizeNs, 1185154a379303ab90a2b2914676a4441917a329b5dYao Chen bucket); 119cfed20bce8a66bde6ad0d74a44fc0a2764b2886dStefan Lafon case DurationMetric_AggregationType_MAX_SPARSE: 1200ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen return make_unique<MaxDurationTracker>(mWizard, mConditionTrackerIndex, mNested, 1215154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentBucketStartTimeNs, mBucketSizeNs, 1225154a379303ab90a2b2914676a4441917a329b5dYao Chen bucket); 1235154a379303ab90a2b2914676a4441917a329b5dYao Chen } 1245154a379303ab90a2b2914676a4441917a329b5dYao Chen} 1255154a379303ab90a2b2914676a4441917a329b5dYao Chen 126729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenvoid DurationMetricProducer::finish() { 127729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: write the StatsLogReport to dropbox using 128729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // DropboxWriter. 129729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 130729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 1315154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) { 132d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-mac VLOG("Metric %s onSlicedConditionMayChange", mMetric.name().c_str()); 133729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // Now for each of the on-going event, check if the condition has changed for them. 1345154a379303ab90a2b2914676a4441917a329b5dYao Chen flushIfNeeded(eventTime); 135729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (auto& pair : mCurrentSlicedDuration) { 1365154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->onSlicedConditionMayChange(eventTime); 137729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 138729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 139729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 1405154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::onConditionChanged(const bool conditionMet, const uint64_t eventTime) { 141d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-mac VLOG("Metric %s onConditionChanged", mMetric.name().c_str()); 142729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mCondition = conditionMet; 143729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: need to populate the condition change time from the event which triggers the condition 144729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // change, instead of using current time. 1455154a379303ab90a2b2914676a4441917a329b5dYao Chen 1465154a379303ab90a2b2914676a4441917a329b5dYao Chen flushIfNeeded(eventTime); 147729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (auto& pair : mCurrentSlicedDuration) { 1485154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->onConditionChanged(conditionMet, eventTime); 149729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 150729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 151729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 152729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenstatic void addDurationBucketsToReport(StatsLogReport_DurationMetricDataWrapper& wrapper, 153729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const vector<KeyValuePair>& key, 154729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const vector<DurationBucketInfo>& buckets) { 155729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen DurationMetricData* data = wrapper.add_data(); 156729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (const auto& kv : key) { 157729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen data->add_dimension()->CopyFrom(kv); 158729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 159729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (const auto& bucket : buckets) { 160729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen data->add_bucket_info()->CopyFrom(bucket); 1615154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("\t bucket [%lld - %lld] duration(ns): %lld", bucket.start_bucket_nanos(), 162729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen bucket.end_bucket_nanos(), bucket.duration_nanos()); 163729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 164729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 165729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 16617adac9cf3e03ad95372eb8657b26909d0414ac0yrostd::unique_ptr<std::vector<uint8_t>> DurationMetricProducer::onDumpReport() { 1672b0f88678b2877a8e9f83cea60f097322b078367yro long long endTime = time(nullptr) * NS_PER_SEC; 1682b0f88678b2877a8e9f83cea60f097322b078367yro 169729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // Dump current bucket if it's stale. 170729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // If current bucket is still on-going, don't force dump current bucket. 171729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // In finish(), We can force dump current bucket. 1722b0f88678b2877a8e9f83cea60f097322b078367yro flushIfNeeded(endTime); 173d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-mac VLOG("metric %s dump report now...", mMetric.name().c_str()); 174729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 175729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (const auto& pair : mPastBuckets) { 176729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const HashableDimensionKey& hashableKey = pair.first; 1772b0f88678b2877a8e9f83cea60f097322b078367yro VLOG(" dimension key %s", hashableKey.c_str()); 178729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen auto it = mDimensionKeyMap.find(hashableKey); 179729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen if (it == mDimensionKeyMap.end()) { 180729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen ALOGW("Dimension key %s not found?!?! skip...", hashableKey.c_str()); 181729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen continue; 182729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 183b0378b093d9b937fe9a731a601d670d50f263078yro long long wrapperToken = 184b0378b093d9b937fe9a731a601d670d50f263078yro mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA); 1852b0f88678b2877a8e9f83cea60f097322b078367yro 1862b0f88678b2877a8e9f83cea60f097322b078367yro // First fill dimension (KeyValuePairs). 1872b0f88678b2877a8e9f83cea60f097322b078367yro for (const auto& kv : it->second) { 188b0378b093d9b937fe9a731a601d670d50f263078yro long long dimensionToken = 189b0378b093d9b937fe9a731a601d670d50f263078yro mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DIMENSION); 1902b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT32 | FIELD_ID_KEY, kv.key()); 1912b0f88678b2877a8e9f83cea60f097322b078367yro if (kv.has_value_str()) { 1922b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT32 | FIELD_ID_VALUE_STR, kv.value_str()); 1932b0f88678b2877a8e9f83cea60f097322b078367yro } else if (kv.has_value_int()) { 1942b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_INT, kv.value_int()); 1952b0f88678b2877a8e9f83cea60f097322b078367yro } else if (kv.has_value_bool()) { 1962b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_BOOL | FIELD_ID_VALUE_BOOL, kv.value_bool()); 1972b0f88678b2877a8e9f83cea60f097322b078367yro } else if (kv.has_value_float()) { 1982b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_FLOAT | FIELD_ID_VALUE_FLOAT, kv.value_float()); 1992b0f88678b2877a8e9f83cea60f097322b078367yro } 2002b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(dimensionToken); 2012b0f88678b2877a8e9f83cea60f097322b078367yro } 2022b0f88678b2877a8e9f83cea60f097322b078367yro 2032b0f88678b2877a8e9f83cea60f097322b078367yro // Then fill bucket_info (DurationBucketInfo). 2042b0f88678b2877a8e9f83cea60f097322b078367yro for (const auto& bucket : pair.second) { 205b0378b093d9b937fe9a731a601d670d50f263078yro long long bucketInfoToken = 206b0378b093d9b937fe9a731a601d670d50f263078yro mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO); 2072b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_NANOS, 2082b0f88678b2877a8e9f83cea60f097322b078367yro (long long)bucket.mBucketStartNs); 2092b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_NANOS, 2102b0f88678b2877a8e9f83cea60f097322b078367yro (long long)bucket.mBucketEndNs); 2112b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_DURATION, (long long)bucket.mDuration); 2122b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(bucketInfoToken); 2132b0f88678b2877a8e9f83cea60f097322b078367yro VLOG("\t bucket [%lld - %lld] duration: %lld", (long long)bucket.mBucketStartNs, 2142b0f88678b2877a8e9f83cea60f097322b078367yro (long long)bucket.mBucketEndNs, (long long)bucket.mDuration); 2152b0f88678b2877a8e9f83cea60f097322b078367yro } 2162b0f88678b2877a8e9f83cea60f097322b078367yro 2172b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(wrapperToken); 218729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 2192b0f88678b2877a8e9f83cea60f097322b078367yro 2202b0f88678b2877a8e9f83cea60f097322b078367yro mProto->end(mProtoToken); 2212b0f88678b2877a8e9f83cea60f097322b078367yro mProto->write(FIELD_TYPE_INT64 | FIELD_ID_END_REPORT_NANOS, 2222b0f88678b2877a8e9f83cea60f097322b078367yro (long long)mCurrentBucketStartTimeNs); 2232b0f88678b2877a8e9f83cea60f097322b078367yro 22417adac9cf3e03ad95372eb8657b26909d0414ac0yro std::unique_ptr<std::vector<uint8_t>> buffer = serializeProto(); 2252b0f88678b2877a8e9f83cea60f097322b078367yro 2262b0f88678b2877a8e9f83cea60f097322b078367yro startNewProtoOutputStream(endTime); 2272b0f88678b2877a8e9f83cea60f097322b078367yro mPastBuckets.clear(); 2282b0f88678b2877a8e9f83cea60f097322b078367yro 22917adac9cf3e03ad95372eb8657b26909d0414ac0yro return buffer; 2302b0f88678b2877a8e9f83cea60f097322b078367yro} 231729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2325154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::flushIfNeeded(uint64_t eventTime) { 2335154a379303ab90a2b2914676a4441917a329b5dYao Chen if (mCurrentBucketStartTimeNs + mBucketSizeNs > eventTime) { 234729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen return; 235729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 236729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2375154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("flushing..........."); 238d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen for (auto it = mCurrentSlicedDuration.begin(); it != mCurrentSlicedDuration.end();) { 2395154a379303ab90a2b2914676a4441917a329b5dYao Chen if (it->second->flushIfNeeded(eventTime)) { 2405154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("erase bucket for key %s", it->first.c_str()); 241d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen it = mCurrentSlicedDuration.erase(it); 242d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen } else { 243d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen ++it; 244729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 245729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 246729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2475154a379303ab90a2b2914676a4441917a329b5dYao Chen int numBucketsForward = (eventTime - mCurrentBucketStartTimeNs) / mBucketSizeNs; 2485154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentBucketStartTimeNs += numBucketsForward * mBucketSizeNs; 249729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 250729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2515154a379303ab90a2b2914676a4441917a329b5dYao Chenvoid DurationMetricProducer::onMatchedLogEventInternal( 2525154a379303ab90a2b2914676a4441917a329b5dYao Chen const size_t matcherIndex, const HashableDimensionKey& eventKey, 2535154a379303ab90a2b2914676a4441917a329b5dYao Chen const map<string, HashableDimensionKey>& conditionKeys, bool condition, 254b3dda41a5a48ddfa44dc8fa939ab495926a0195dChenjie Yu const LogEvent& event, bool scheduledPull) { 2555154a379303ab90a2b2914676a4441917a329b5dYao Chen flushIfNeeded(event.GetTimestampNs()); 256729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2575154a379303ab90a2b2914676a4441917a329b5dYao Chen if (matcherIndex == mStopAllIndex) { 2585154a379303ab90a2b2914676a4441917a329b5dYao Chen for (auto& pair : mCurrentSlicedDuration) { 2595154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->noteStopAll(event.GetTimestampNs()); 2605154a379303ab90a2b2914676a4441917a329b5dYao Chen } 261729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen return; 262729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 263729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2645154a379303ab90a2b2914676a4441917a329b5dYao Chen HashableDimensionKey atomKey = getHashableKey(getDimensionKey(event, mInternalDimension)); 265729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2665154a379303ab90a2b2914676a4441917a329b5dYao Chen if (mCurrentSlicedDuration.find(eventKey) == mCurrentSlicedDuration.end()) { 2675154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentSlicedDuration[eventKey] = createDurationTracker(mPastBuckets[eventKey]); 2685154a379303ab90a2b2914676a4441917a329b5dYao Chen } 269729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2705154a379303ab90a2b2914676a4441917a329b5dYao Chen auto it = mCurrentSlicedDuration.find(eventKey); 271729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2725154a379303ab90a2b2914676a4441917a329b5dYao Chen if (matcherIndex == mStartIndex) { 2735154a379303ab90a2b2914676a4441917a329b5dYao Chen it->second->noteStart(atomKey, condition, event.GetTimestampNs(), conditionKeys); 2745154a379303ab90a2b2914676a4441917a329b5dYao Chen } else if (matcherIndex == mStopIndex) { 2750ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen it->second->noteStop(atomKey, event.GetTimestampNs(), false); 276729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 277729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 278729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 27969007c82625dd8b19bd68d1031191e2ff83b5f49yrosize_t DurationMetricProducer::byteSize() { 2802b0f88678b2877a8e9f83cea60f097322b078367yro size_t totalSize = 0; 2812b0f88678b2877a8e9f83cea60f097322b078367yro for (const auto& pair : mPastBuckets) { 2822b0f88678b2877a8e9f83cea60f097322b078367yro totalSize += pair.second.size() * kBucketSize; 2832b0f88678b2877a8e9f83cea60f097322b078367yro } 2842b0f88678b2877a8e9f83cea60f097322b078367yro return totalSize; 28569007c82625dd8b19bd68d1031191e2ff83b5f49yro} 28669007c82625dd8b19bd68d1031191e2ff83b5f49yro 287729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace statsd 288729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace os 289729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace android 290