DurationMetricProducer.cpp revision 884c8c130fde0d02ada1316f7c27f0f55e7e48b9
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 173c0b95ceb520c6b23871da90c23f89c55b76b560Yao Chen#define DEBUG false 185154a379303ab90a2b2914676a4441917a329b5dYao Chen 19729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include "Log.h" 205154a379303ab90a2b2914676a4441917a329b5dYao Chen#include "DurationMetricProducer.h" 21b356151e63140085cb96fa16804ee18b3862a4fcYao Chen#include "guardrail/StatsdStats.h" 22729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include "stats_util.h" 232087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#include "stats_log_util.h" 24729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 25729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include <limits.h> 26729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include <stdlib.h> 27729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 28b0378b093d9b937fe9a731a601d670d50f263078yrousing android::util::FIELD_COUNT_REPEATED; 292b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_BOOL; 302b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_FLOAT; 312b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT32; 322b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT64; 332b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_MESSAGE; 34d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-macusing android::util::FIELD_TYPE_STRING; 352b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::ProtoOutputStream; 36729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::string; 37729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::unordered_map; 38729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::vector; 39729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 40729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace android { 41729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace os { 42729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace statsd { 43729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 442b0f88678b2877a8e9f83cea60f097322b078367yro// for StatsLogReport 4594e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-macconst int FIELD_ID_ID = 1; 462b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_START_REPORT_NANOS = 2; 472b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_END_REPORT_NANOS = 3; 482b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION_METRICS = 6; 492b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricDataWrapper 502b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DATA = 1; 512b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricData 52468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-macconst int FIELD_ID_DIMENSION_IN_WHAT = 1; 53468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-macconst int FIELD_ID_DIMENSION_IN_CONDITION = 2; 54468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-macconst int FIELD_ID_BUCKET_INFO = 3; 552b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationBucketInfo 562b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_START_BUCKET_NANOS = 1; 572b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_END_BUCKET_NANOS = 2; 582b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION = 3; 592b0f88678b2877a8e9f83cea60f097322b078367yro 60b356151e63140085cb96fa16804ee18b3862a4fcYao ChenDurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const DurationMetric& metric, 61729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const int conditionIndex, const size_t startIndex, 62729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const size_t stopIndex, const size_t stopAllIndex, 630ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen const bool nesting, 645154a379303ab90a2b2914676a4441917a329b5dYao Chen const sp<ConditionWizard>& wizard, 652087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac const FieldMatcher& internalDimensions, 6693fe3a34a02c673eaee4a2d18565ba8df20685cbYao Chen const uint64_t startTimeNs) 6794e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard), 68f09569f848ca0b81a21a74e9f4dd8bd9a886151aYao Chen mAggregationType(metric.aggregation_type()), 69729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mStartIndex(startIndex), 70729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mStopIndex(stopIndex), 715154a379303ab90a2b2914676a4441917a329b5dYao Chen mStopAllIndex(stopAllIndex), 720ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen mNested(nesting), 732087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac mInternalDimensions(internalDimensions) { 74729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract 75729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // them in the base class, because the proto generated CountMetric, and DurationMetric are 76729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // not related. Maybe we should add a template in the future?? 77b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac if (metric.has_bucket()) { 78b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac mBucketSizeNs = TimeUnitToBucketSizeInMillis(metric.bucket()) * 1000000; 79729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } else { 80729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mBucketSizeNs = LLONG_MAX; 81729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 82729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 83729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // TODO: use UidMap if uid->pkg_name is required 84468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-mac mDimensions = metric.dimensions_in_what(); 85729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 86729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen if (metric.links().size() > 0) { 87729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(), 88729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen metric.links().end()); 89729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mConditionSliced = true; 90729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 91729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 9294e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(), 93729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen (long long)mBucketSizeNs, (long long)mStartTimeNs); 94729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 95729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 96729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao ChenDurationMetricProducer::~DurationMetricProducer() { 97729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen VLOG("~DurationMetric() called"); 98729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 99729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 100857aaa520804d846a050e1eeb85d82977c983666Bookatzsp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(const Alert &alert) { 101857aaa520804d846a050e1eeb85d82977c983666Bookatz std::lock_guard<std::mutex> lock(mMutex); 102a7fb12d2d285a3a62f5e8956d1bacfa0e15e9d0fYangster-mac if (alert.trigger_if_sum_gt() > alert.num_buckets() * mBucketSizeNs) { 103a7fb12d2d285a3a62f5e8956d1bacfa0e15e9d0fYangster-mac ALOGW("invalid alert: threshold (%f) > possible recordable value (%d x %lld)", 104a7fb12d2d285a3a62f5e8956d1bacfa0e15e9d0fYangster-mac alert.trigger_if_sum_gt(), alert.num_buckets(), 105450099db169d386077584d93486908c3bae1244eBookatz (long long)mBucketSizeNs); 106450099db169d386077584d93486908c3bae1244eBookatz return nullptr; 107450099db169d386077584d93486908c3bae1244eBookatz } 108857aaa520804d846a050e1eeb85d82977c983666Bookatz sp<DurationAnomalyTracker> anomalyTracker = new DurationAnomalyTracker(alert, mConfigKey); 109857aaa520804d846a050e1eeb85d82977c983666Bookatz if (anomalyTracker != nullptr) { 110857aaa520804d846a050e1eeb85d82977c983666Bookatz mAnomalyTrackers.push_back(anomalyTracker); 111857aaa520804d846a050e1eeb85d82977c983666Bookatz } 112857aaa520804d846a050e1eeb85d82977c983666Bookatz return anomalyTracker; 113450099db169d386077584d93486908c3bae1244eBookatz} 114450099db169d386077584d93486908c3bae1244eBookatz 1155154a379303ab90a2b2914676a4441917a329b5dYao Chenunique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker( 116f60e0bad5908c51c954ca8dc763c8efd394c56dcYao Chen const HashableDimensionKey& eventKey) const { 117f09569f848ca0b81a21a74e9f4dd8bd9a886151aYao Chen switch (mAggregationType) { 118cfed20bce8a66bde6ad0d74a44fc0a2764b2886dStefan Lafon case DurationMetric_AggregationType_SUM: 119b356151e63140085cb96fa16804ee18b3862a4fcYao Chen return make_unique<OringDurationTracker>( 12094e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested, 121d59a6589faeb8a1b7b3c23e5ac95671bda736cddYao Chen mCurrentBucketStartTimeNs, mBucketSizeNs, mConditionSliced, mAnomalyTrackers); 122cfed20bce8a66bde6ad0d74a44fc0a2764b2886dStefan Lafon case DurationMetric_AggregationType_MAX_SPARSE: 123b356151e63140085cb96fa16804ee18b3862a4fcYao Chen return make_unique<MaxDurationTracker>( 12494e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex, mNested, 125d59a6589faeb8a1b7b3c23e5ac95671bda736cddYao Chen mCurrentBucketStartTimeNs, mBucketSizeNs, mConditionSliced, mAnomalyTrackers); 1265154a379303ab90a2b2914676a4441917a329b5dYao Chen } 1275154a379303ab90a2b2914676a4441917a329b5dYao Chen} 1285154a379303ab90a2b2914676a4441917a329b5dYao Chen 129f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstervoid DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) { 13094e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId); 131f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster flushIfNeededLocked(eventTime); 132729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen // Now for each of the on-going event, check if the condition has changed for them. 133729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (auto& pair : mCurrentSlicedDuration) { 1345154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->onSlicedConditionMayChange(eventTime); 135729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 136729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 137729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 138f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstervoid DurationMetricProducer::onConditionChangedLocked(const bool conditionMet, 139f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster const uint64_t eventTime) { 14094e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac VLOG("Metric %lld onConditionChanged", (long long)mMetricId); 141729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen mCondition = conditionMet; 142f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster flushIfNeededLocked(eventTime); 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. 145729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (auto& pair : mCurrentSlicedDuration) { 1465154a379303ab90a2b2914676a4441917a329b5dYao Chen pair.second->onConditionChanged(conditionMet, eventTime); 147729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 148729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 149729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 1502087716f2bdca90c7c3034d556ac12911bd8018eYangster-macvoid DurationMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) { 1512087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac flushIfNeededLocked(dumpTimeNs); 15294e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac report->set_metric_id(mMetricId); 1532087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac report->set_start_report_nanos(mStartTimeNs); 1542087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac 1552087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac auto duration_metrics = report->mutable_duration_metrics(); 1562087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac for (const auto& pair : mPastBuckets) { 1572087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac DurationMetricData* metricData = duration_metrics->add_data(); 158468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-mac *metricData->mutable_dimensions_in_what() = pair.first.getDimensionsValue(); 1592087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac for (const auto& bucket : pair.second) { 1602087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac auto bucketInfo = metricData->add_bucket_info(); 1612087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac bucketInfo->set_start_bucket_nanos(bucket.mBucketStartNs); 1622087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac bucketInfo->set_end_bucket_nanos(bucket.mBucketEndNs); 1632087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac bucketInfo->set_duration_nanos(bucket.mDuration); 1642087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } 1652087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } 1662087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac} 1672087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac 168288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chenvoid DurationMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, 169288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen ProtoOutputStream* protoOutput) { 170288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen flushIfNeededLocked(dumpTimeNs); 171635b4b37210bd61b73aebf19298e38b8fb382e85Yangster-mac if (mPastBuckets.empty()) { 172635b4b37210bd61b73aebf19298e38b8fb382e85Yangster-mac return; 173635b4b37210bd61b73aebf19298e38b8fb382e85Yangster-mac } 174288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen 17594e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId); 176288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_REPORT_NANOS, (long long)mStartTimeNs); 177288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen long long protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS); 1786a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen 17994e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac VLOG("metric %lld dump report now...", (long long)mMetricId); 1806a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen 181729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen for (const auto& pair : mPastBuckets) { 182729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen const HashableDimensionKey& hashableKey = pair.first; 1832b0f88678b2877a8e9f83cea60f097322b078367yro VLOG(" dimension key %s", hashableKey.c_str()); 1841ff4f4325882d812ded4f75ee6c2b6d352a85c9eYao Chen 185b0378b093d9b937fe9a731a601d670d50f263078yro long long wrapperToken = 186288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA); 1872b0f88678b2877a8e9f83cea60f097322b078367yro 1882087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac // First fill dimension. 1892087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac long long dimensionToken = protoOutput->start( 190468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-mac FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT); 1912087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac writeDimensionsValueProtoToStream(hashableKey.getDimensionsValue(), protoOutput); 1922087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac protoOutput->end(dimensionToken); 1932b0f88678b2877a8e9f83cea60f097322b078367yro 1942b0f88678b2877a8e9f83cea60f097322b078367yro // Then fill bucket_info (DurationBucketInfo). 1952b0f88678b2877a8e9f83cea60f097322b078367yro for (const auto& bucket : pair.second) { 196288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen long long bucketInfoToken = protoOutput->start( 197288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO); 198288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_NANOS, 199288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen (long long)bucket.mBucketStartNs); 200288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_NANOS, 201288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen (long long)bucket.mBucketEndNs); 202288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DURATION, (long long)bucket.mDuration); 203288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->end(bucketInfoToken); 2042b0f88678b2877a8e9f83cea60f097322b078367yro VLOG("\t bucket [%lld - %lld] duration: %lld", (long long)bucket.mBucketStartNs, 2052b0f88678b2877a8e9f83cea60f097322b078367yro (long long)bucket.mBucketEndNs, (long long)bucket.mDuration); 2062b0f88678b2877a8e9f83cea60f097322b078367yro } 2072b0f88678b2877a8e9f83cea60f097322b078367yro 208288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->end(wrapperToken); 209729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 2102b0f88678b2877a8e9f83cea60f097322b078367yro 211288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->end(protoToken); 212288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_REPORT_NANOS, (long long)dumpTimeNs); 213f60e0bad5908c51c954ca8dc763c8efd394c56dcYao Chen mPastBuckets.clear(); 214288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen mStartTimeNs = mCurrentBucketStartTimeNs; 2152b0f88678b2877a8e9f83cea60f097322b078367yro} 216729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 217f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstervoid DurationMetricProducer::flushIfNeededLocked(const uint64_t& eventTime) { 2185154a379303ab90a2b2914676a4441917a329b5dYao Chen if (mCurrentBucketStartTimeNs + mBucketSizeNs > eventTime) { 219729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen return; 220729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 2215154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("flushing..........."); 222d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen for (auto it = mCurrentSlicedDuration.begin(); it != mCurrentSlicedDuration.end();) { 223f60e0bad5908c51c954ca8dc763c8efd394c56dcYao Chen if (it->second->flushIfNeeded(eventTime, &mPastBuckets)) { 2245154a379303ab90a2b2914676a4441917a329b5dYao Chen VLOG("erase bucket for key %s", it->first.c_str()); 225d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen it = mCurrentSlicedDuration.erase(it); 226d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen } else { 227d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen ++it; 228729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 229729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 230729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2315154a379303ab90a2b2914676a4441917a329b5dYao Chen int numBucketsForward = (eventTime - mCurrentBucketStartTimeNs) / mBucketSizeNs; 2325154a379303ab90a2b2914676a4441917a329b5dYao Chen mCurrentBucketStartTimeNs += numBucketsForward * mBucketSizeNs; 233e2cd6d509b17894b95d14523ae3e7c4c7a9a74e3Yangster-mac mCurrentBucketNum += numBucketsForward; 234729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 235729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 236884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chenvoid DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const { 237884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen if (mCurrentSlicedDuration.size() == 0) { 238884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen return; 239884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen } 240884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen 241884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId, 242884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen (unsigned long)mCurrentSlicedDuration.size()); 243884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen if (verbose) { 244884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen for (const auto& slice : mCurrentSlicedDuration) { 245884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen fprintf(out, "\t%s\n", slice.first.c_str()); 246884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen slice.second->dumpStates(out, verbose); 247884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen } 248884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen } 249884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen} 250884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen 251f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangsterbool DurationMetricProducer::hitGuardRailLocked(const HashableDimensionKey& newKey) { 252b356151e63140085cb96fa16804ee18b3862a4fcYao Chen // the key is not new, we are good. 253b356151e63140085cb96fa16804ee18b3862a4fcYao Chen if (mCurrentSlicedDuration.find(newKey) != mCurrentSlicedDuration.end()) { 254b356151e63140085cb96fa16804ee18b3862a4fcYao Chen return false; 255b356151e63140085cb96fa16804ee18b3862a4fcYao Chen } 256b356151e63140085cb96fa16804ee18b3862a4fcYao Chen // 1. Report the tuple count if the tuple count > soft limit 257b356151e63140085cb96fa16804ee18b3862a4fcYao Chen if (mCurrentSlicedDuration.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) { 258b356151e63140085cb96fa16804ee18b3862a4fcYao Chen size_t newTupleCount = mCurrentSlicedDuration.size() + 1; 25994e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount); 260b356151e63140085cb96fa16804ee18b3862a4fcYao Chen // 2. Don't add more tuples, we are above the allowed threshold. Drop the data. 261b356151e63140085cb96fa16804ee18b3862a4fcYao Chen if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) { 26294e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac ALOGE("DurationMetric %lld dropping data for dimension key %s", 26394e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac (long long)mMetricId, newKey.c_str()); 264b356151e63140085cb96fa16804ee18b3862a4fcYao Chen return true; 265b356151e63140085cb96fa16804ee18b3862a4fcYao Chen } 266b356151e63140085cb96fa16804ee18b3862a4fcYao Chen } 267b356151e63140085cb96fa16804ee18b3862a4fcYao Chen return false; 268b356151e63140085cb96fa16804ee18b3862a4fcYao Chen} 269b356151e63140085cb96fa16804ee18b3862a4fcYao Chen 270f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstervoid DurationMetricProducer::onMatchedLogEventInternalLocked( 2715154a379303ab90a2b2914676a4441917a329b5dYao Chen const size_t matcherIndex, const HashableDimensionKey& eventKey, 2722087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac const ConditionKey& conditionKeys, bool condition, 273a7259abde4e89fd91404b14b4845113cd313d1ecChenjie Yu const LogEvent& event) { 274f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster flushIfNeededLocked(event.GetTimestampNs()); 275729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2766a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen if (matcherIndex == mStopAllIndex) { 2776a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen for (auto& pair : mCurrentSlicedDuration) { 2786a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen pair.second->noteStopAll(event.GetTimestampNs()); 2795154a379303ab90a2b2914676a4441917a329b5dYao Chen } 2806a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen return; 2816a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen } 282729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 283729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2846a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen if (mCurrentSlicedDuration.find(eventKey) == mCurrentSlicedDuration.end()) { 285f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster if (hitGuardRailLocked(eventKey)) { 2866a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen return; 287b356151e63140085cb96fa16804ee18b3862a4fcYao Chen } 288f60e0bad5908c51c954ca8dc763c8efd394c56dcYao Chen mCurrentSlicedDuration[eventKey] = createDurationTracker(eventKey); 2896a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen } 290729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 2916a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen auto it = mCurrentSlicedDuration.find(eventKey); 2926a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen 2932087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac std::vector<DimensionsValue> values = getDimensionKeys(event, mInternalDimensions); 2942087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac if (values.empty()) { 2952087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac if (matcherIndex == mStartIndex) { 2962087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, 2972087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac event.GetTimestampNs(), conditionKeys); 2982087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } else if (matcherIndex == mStopIndex) { 2992087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac it->second->noteStop(DEFAULT_DIMENSION_KEY, event.GetTimestampNs(), false); 3002087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } 3012087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } else { 3022087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac for (const DimensionsValue& value : values) { 3032087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac if (matcherIndex == mStartIndex) { 3042087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac it->second->noteStart(HashableDimensionKey(value), condition, 3052087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac event.GetTimestampNs(), conditionKeys); 3062087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } else if (matcherIndex == mStopIndex) { 3072087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac it->second->noteStop(HashableDimensionKey(value), event.GetTimestampNs(), false); 3082087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } 3092087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac } 310729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen } 3112087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac 312729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} 313729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen 314f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstersize_t DurationMetricProducer::byteSizeLocked() const { 3157c334a129e93e405a72e8299a1cd928af079d14fYangster size_t totalSize = 0; 3167c334a129e93e405a72e8299a1cd928af079d14fYangster for (const auto& pair : mPastBuckets) { 3177c334a129e93e405a72e8299a1cd928af079d14fYangster totalSize += pair.second.size() * kBucketSize; 3187c334a129e93e405a72e8299a1cd928af079d14fYangster } 3197c334a129e93e405a72e8299a1cd928af079d14fYangster return totalSize; 32069007c82625dd8b19bd68d1031191e2ff83b5f49yro} 32169007c82625dd8b19bd68d1031191e2ff83b5f49yro 322729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace statsd 323729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace os 324729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen} // namespace android 325