diff options
| author | 2018-02-28 01:29:27 +0000 | |
|---|---|---|
| committer | 2018-02-28 01:29:27 +0000 | |
| commit | 9c53ea3a75ffcbc71f3d28b045169e1c8c7e01db (patch) | |
| tree | 93c600eee481a9b3ec583664b3eeba0e5ee8b0c9 | |
| parent | bf6edacac900e4f889dde292474e0e3fecb8d689 (diff) | |
| parent | 539288806fe5ae3733ef7883eb8ec01cce293988 (diff) | |
Merge "Duration tracker optimization."
| -rw-r--r-- | cmds/statsd/src/FieldValue.h | 12 | ||||
| -rw-r--r-- | cmds/statsd/src/HashableDimensionKey.cpp | 5 | ||||
| -rw-r--r-- | cmds/statsd/src/HashableDimensionKey.h | 3 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/DurationMetricProducer.cpp | 286 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/DurationMetricProducer.h | 12 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricProducer.cpp | 39 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricProducer.h | 2 |
7 files changed, 270 insertions, 89 deletions
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h index 21f30e288c25..b0e2c43e8cdd 100644 --- a/cmds/statsd/src/FieldValue.h +++ b/cmds/statsd/src/FieldValue.h @@ -217,6 +217,14 @@ struct Matcher { const Field mMatcher; const int32_t mMask; + inline const Field& getMatcher() const { + return mMatcher; + } + + inline int32_t getMask() const { + return mMask; + } + bool hasAnyPositionMatcher(int* prefix) const { if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(2) == 0) { (*prefix) = mMatcher.getPrefix(2); @@ -224,6 +232,10 @@ struct Matcher { } return false; } + + inline bool operator!=(const Matcher& that) const { + return mMatcher != that.getMatcher() || mMask != that.getMask(); + }; }; /** diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp index 1502a00abee9..cc7063131f18 100644 --- a/cmds/statsd/src/HashableDimensionKey.cpp +++ b/cmds/statsd/src/HashableDimensionKey.cpp @@ -166,10 +166,11 @@ void filterGaugeValues(const std::vector<Matcher>& matcherFields, } } -void getDimensionForCondition(const LogEvent& event, Metric2Condition links, +void getDimensionForCondition(const std::vector<FieldValue>& eventValues, + const Metric2Condition& links, vector<HashableDimensionKey>* conditionDimension) { // Get the dimension first by using dimension from what. - filterValues(links.metricFields, event.getValues(), conditionDimension); + filterValues(links.metricFields, eventValues, conditionDimension); // Then replace the field with the dimension from condition. for (auto& dim : *conditionDimension) { diff --git a/cmds/statsd/src/HashableDimensionKey.h b/cmds/statsd/src/HashableDimensionKey.h index 5d016e9f2804..57bdf68091d0 100644 --- a/cmds/statsd/src/HashableDimensionKey.h +++ b/cmds/statsd/src/HashableDimensionKey.h @@ -144,7 +144,8 @@ bool filterValues(const std::vector<Matcher>& matcherFields, const std::vector<F void filterGaugeValues(const std::vector<Matcher>& matchers, const std::vector<FieldValue>& values, std::vector<FieldValue>* output); -void getDimensionForCondition(const LogEvent& event, Metric2Condition links, +void getDimensionForCondition(const std::vector<FieldValue>& eventValues, + const Metric2Condition& links, std::vector<HashableDimensionKey>* conditionDimension); } // namespace statsd diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp index 16cac99f1fb9..80329c3a8a42 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -101,6 +101,18 @@ DurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const Durat } mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0); + if (mDimensionsInWhat.size() == mInternalDimensions.size()) { + bool mUseWhatDimensionAsInternalDimension = true; + for (size_t i = 0; mUseWhatDimensionAsInternalDimension && + i < mDimensionsInWhat.size(); ++i) { + if (mDimensionsInWhat[i] != mInternalDimensions[i]) { + mUseWhatDimensionAsInternalDimension = false; + } + } + } else { + mUseWhatDimensionAsInternalDimension = false; + } + VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(), (long long)mBucketSizeNs, (long long)mStartTimeNs); } @@ -141,29 +153,56 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eve flushIfNeededLocked(eventTime); // Now for each of the on-going event, check if the condition has changed for them. - for (auto& pair : mCurrentSlicedDurationTrackerMap) { - pair.second->onSlicedConditionMayChange(eventTime); + for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { + for (auto& pair : whatIt.second) { + pair.second->onSlicedConditionMayChange(eventTime); + } } - - std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet; - mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition, - &conditionDimensionsKeySet); - - for (auto& pair : mCurrentSlicedDurationTrackerMap) { - conditionDimensionsKeySet.erase(pair.first.getDimensionKeyInCondition()); + if (mDimensionsInCondition.empty()) { + return; } - std::unordered_set<MetricDimensionKey> newKeys; - for (const auto& conditionDimensionsKey : conditionDimensionsKeySet) { - for (auto& pair : mCurrentSlicedDurationTrackerMap) { - auto newKey = - MetricDimensionKey(pair.first.getDimensionKeyInWhat(), conditionDimensionsKey); - if (newKeys.find(newKey) == newKeys.end()) { - mCurrentSlicedDurationTrackerMap[newKey] = pair.second->clone(eventTime); - mCurrentSlicedDurationTrackerMap[newKey]->setEventKey(newKey); - mCurrentSlicedDurationTrackerMap[newKey]->onSlicedConditionMayChange(eventTime); + + if (mMetric2ConditionLinks.empty()) { + std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet; + mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition, + &conditionDimensionsKeySet); + for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) { + for (const auto& pair : whatIt.second) { + conditionDimensionsKeySet.erase(pair.first); + } + } + for (const auto& conditionDimension : conditionDimensionsKeySet) { + for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { + if (!whatIt.second.empty()) { + unique_ptr<DurationTracker> newTracker = + whatIt.second.begin()->second->clone(eventTime); + newTracker->setEventKey(MetricDimensionKey(whatIt.first, conditionDimension)); + newTracker->onSlicedConditionMayChange(eventTime); + whatIt.second[conditionDimension] = std::move(newTracker); + } + } + } + } else { + for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { + ConditionKey conditionKey; + for (const auto& link : mMetric2ConditionLinks) { + getDimensionForCondition(whatIt.first.getValues(), link, + &conditionKey[link.conditionId]); + } + std::unordered_set<HashableDimensionKey> conditionDimensionsKeys; + mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition, + &conditionDimensionsKeys); + + for (const auto& conditionDimension : conditionDimensionsKeys) { + if (!whatIt.second.empty() && + whatIt.second.find(conditionDimension) == whatIt.second.end()) { + auto newTracker = whatIt.second.begin()->second->clone(eventTime); + newTracker->setEventKey(MetricDimensionKey(whatIt.first, conditionDimension)); + newTracker->onSlicedConditionMayChange(eventTime); + whatIt.second[conditionDimension] = std::move(newTracker); + } } - newKeys.insert(newKey); } } } @@ -175,8 +214,10 @@ void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet, flushIfNeededLocked(eventTime); // TODO: need to populate the condition change time from the event which triggers the condition // change, instead of using current time. - for (auto& pair : mCurrentSlicedDurationTrackerMap) { - pair.second->onConditionChanged(conditionMet, eventTime); + for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { + for (auto& pair : whatIt.second) { + pair.second->onConditionChanged(conditionMet, eventTime); + } } } @@ -241,13 +282,20 @@ void DurationMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) { return; } VLOG("flushing..........."); - for (auto it = mCurrentSlicedDurationTrackerMap.begin(); - it != mCurrentSlicedDurationTrackerMap.end();) { - if (it->second->flushIfNeeded(eventTimeNs, &mPastBuckets)) { - VLOG("erase bucket for key %s", it->first.c_str()); - it = mCurrentSlicedDurationTrackerMap.erase(it); + for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin(); + whatIt != mCurrentSlicedDurationTrackerMap.end();) { + for (auto it = whatIt->second.begin(); it != whatIt->second.end();) { + if (it->second->flushIfNeeded(eventTimeNs, &mPastBuckets)) { + VLOG("erase bucket for key %s %s", whatIt->first.c_str(), it->first.c_str()); + it = whatIt->second.erase(it); + } else { + ++it; + } + } + if (whatIt->second.empty()) { + whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt); } else { - ++it; + whatIt++; } } @@ -257,13 +305,20 @@ void DurationMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) { } void DurationMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs) { - for (auto it = mCurrentSlicedDurationTrackerMap.begin(); - it != mCurrentSlicedDurationTrackerMap.end();) { - if (it->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) { - VLOG("erase bucket for key %s", it->first.c_str()); - it = mCurrentSlicedDurationTrackerMap.erase(it); + for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin(); + whatIt != mCurrentSlicedDurationTrackerMap.end();) { + for (auto it = whatIt->second.begin(); it != whatIt->second.end();) { + if (it->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) { + VLOG("erase bucket for key %s %s", whatIt->first.c_str(), it->first.c_str()); + it = whatIt->second.erase(it); + } else { + ++it; + } + } + if (whatIt->second.empty()) { + whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt); } else { - ++it; + whatIt++; } } } @@ -276,18 +331,16 @@ void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const { fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId, (unsigned long)mCurrentSlicedDurationTrackerMap.size()); if (verbose) { - for (const auto& slice : mCurrentSlicedDurationTrackerMap) { - fprintf(out, "\t%s\n", slice.first.c_str()); - slice.second->dumpStates(out, verbose); + for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) { + for (const auto& slice : whatIt.second) { + fprintf(out, "\t%s\t%s\n", whatIt.first.c_str(), slice.first.c_str()); + slice.second->dumpStates(out, verbose); + } } } } bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) { - // the key is not new, we are good. - if (mCurrentSlicedDurationTrackerMap.find(newKey) != mCurrentSlicedDurationTrackerMap.end()) { - return false; - } // 1. Report the tuple count if the tuple count > soft limit if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) { size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1; @@ -302,49 +355,162 @@ bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey return false; } +void DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey, + const ConditionKey& conditionKeys, + bool condition, const LogEvent& event) { + const auto& whatKey = eventKey.getDimensionKeyInWhat(); + const auto& condKey = eventKey.getDimensionKeyInCondition(); + + auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey); + if (whatIt == mCurrentSlicedDurationTrackerMap.end()) { + if (hitGuardRailLocked(eventKey)) { + return; + } + mCurrentSlicedDurationTrackerMap[whatKey][condKey] = createDurationTracker(eventKey); + } else { + if (whatIt->second.find(condKey) == whatIt->second.end()) { + if (hitGuardRailLocked(eventKey)) { + return; + } + mCurrentSlicedDurationTrackerMap[whatKey][condKey] = createDurationTracker(eventKey); + } + } + + auto it = mCurrentSlicedDurationTrackerMap.find(whatKey)->second.find(condKey); + if (mUseWhatDimensionAsInternalDimension) { + it->second->noteStart(whatKey, condition, + event.GetElapsedTimestampNs(), conditionKeys); + return; + } + + std::vector<HashableDimensionKey> values; + filterValues(mInternalDimensions, event.getValues(), &values); + if (values.empty()) { + it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, + event.GetElapsedTimestampNs(), conditionKeys); + } else { + for (const auto& value : values) { + it->second->noteStart(value, condition, event.GetElapsedTimestampNs(), conditionKeys); + } + } + +} + void DurationMetricProducer::onMatchedLogEventInternalLocked( const size_t matcherIndex, const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys, bool condition, const LogEvent& event) { + ALOGW("Not used in duration tracker."); +} + +void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, + const LogEvent& event) { + uint64_t eventTimeNs = event.GetElapsedTimestampNs(); + if (eventTimeNs < mStartTimeNs) { + return; + } + flushIfNeededLocked(event.GetElapsedTimestampNs()); + // Handles Stopall events. if (matcherIndex == mStopAllIndex) { - for (auto& pair : mCurrentSlicedDurationTrackerMap) { - pair.second->noteStopAll(event.GetElapsedTimestampNs()); + for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { + for (auto& pair : whatIt.second) { + pair.second->noteStopAll(event.GetElapsedTimestampNs()); + } } return; } - if (mCurrentSlicedDurationTrackerMap.find(eventKey) == mCurrentSlicedDurationTrackerMap.end()) { - if (hitGuardRailLocked(eventKey)) { + vector<HashableDimensionKey> dimensionInWhatValues; + if (!mDimensionsInWhat.empty()) { + filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhatValues); + } else { + dimensionInWhatValues.push_back(DEFAULT_DIMENSION_KEY); + } + + // Handles Stop events. + if (matcherIndex == mStopIndex) { + if (mUseWhatDimensionAsInternalDimension) { + for (const HashableDimensionKey& whatKey : dimensionInWhatValues) { + auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey); + if (whatIt != mCurrentSlicedDurationTrackerMap.end()) { + for (const auto& condIt : whatIt->second) { + condIt.second->noteStop(whatKey, event.GetElapsedTimestampNs(), false); + } + } + } return; } - mCurrentSlicedDurationTrackerMap[eventKey] = createDurationTracker(eventKey); + + std::vector<HashableDimensionKey> internalDimensionKeys; + filterValues(mInternalDimensions, event.getValues(), &internalDimensionKeys); + if (internalDimensionKeys.empty()) { + internalDimensionKeys.push_back(DEFAULT_DIMENSION_KEY); + } + for (const HashableDimensionKey& whatDimension : dimensionInWhatValues) { + auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatDimension); + if (whatIt != mCurrentSlicedDurationTrackerMap.end()) { + for (const auto& condIt : whatIt->second) { + for (const auto& internalDimensionKey : internalDimensionKeys) { + condIt.second->noteStop( + internalDimensionKey, event.GetElapsedTimestampNs(), false); + } + } + } + } + return; } - auto it = mCurrentSlicedDurationTrackerMap.find(eventKey); + bool condition; + ConditionKey conditionKey; + std::unordered_set<HashableDimensionKey> dimensionKeysInCondition; + if (mConditionSliced) { + for (const auto& link : mMetric2ConditionLinks) { + getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]); + } - std::vector<HashableDimensionKey> values; - filterValues(mInternalDimensions, event.getValues(), &values); - if (values.empty()) { - if (matcherIndex == mStartIndex) { - it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, - event.GetElapsedTimestampNs(), conditionKeys); - } else if (matcherIndex == mStopIndex) { - it->second->noteStop(DEFAULT_DIMENSION_KEY, event.GetElapsedTimestampNs(), false); + auto conditionState = + mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition, + &dimensionKeysInCondition); + condition = (conditionState == ConditionState::kTrue); + if (mDimensionsInCondition.empty() && condition) { + dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY); } } else { - for (const auto& value : values) { - if (matcherIndex == mStartIndex) { - it->second->noteStart(value, condition, event.GetElapsedTimestampNs(), conditionKeys); - } else if (matcherIndex == mStopIndex) { - it->second->noteStop(value, event.GetElapsedTimestampNs(), false); - } + condition = mCondition; + if (condition) { + dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY); } } + for (const auto& whatDimension : dimensionInWhatValues) { + auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatDimension); + // If the what dimension is already there, we should update all the trackers even + // the condition is false. + if (whatIt != mCurrentSlicedDurationTrackerMap.end()) { + for (const auto& condIt : whatIt->second) { + const bool cond = dimensionKeysInCondition.find(condIt.first) != + dimensionKeysInCondition.end(); + handleStartEvent(MetricDimensionKey(whatDimension, condIt.first), + conditionKey, cond, event); + } + } else { + // If it is a new what dimension key, we need to handle the start events for all current + // condition dimensions. + for (const auto& conditionDimension : dimensionKeysInCondition) { + handleStartEvent(MetricDimensionKey(whatDimension, conditionDimension), + conditionKey, condition, event); + } + } + if (dimensionKeysInCondition.empty()) { + handleStartEvent(MetricDimensionKey(whatDimension, DEFAULT_DIMENSION_KEY), + conditionKey, condition, event); + } + } } + size_t DurationMetricProducer::byteSizeLocked() const { size_t totalSize = 0; for (const auto& pair : mPastBuckets) { diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h index f41c278c5915..73d074f1a2ce 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.h +++ b/cmds/statsd/src/metrics/DurationMetricProducer.h @@ -50,12 +50,16 @@ public: const sp<AlarmMonitor>& anomalyAlarmMonitor) override; protected: + void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) override; void onMatchedLogEventInternalLocked( const size_t matcherIndex, const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys, bool condition, const LogEvent& event) override; private: + void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys, + bool condition, const LogEvent& event); + void onDumpReportLocked(const uint64_t dumpTimeNs, android::util::ProtoOutputStream* protoOutput) override; @@ -92,12 +96,16 @@ private: // The dimension from the atom predicate. e.g., uid, wakelock name. vector<Matcher> mInternalDimensions; + // This boolean is true iff When mInternalDimensions == mDimensionsInWhat + bool mUseWhatDimensionAsInternalDimension; + // Save the past buckets and we can clear when the StatsLogReport is dumped. // TODO: Add a lock to mPastBuckets. std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets; - // The current bucket. - std::unordered_map<MetricDimensionKey, std::unique_ptr<DurationTracker>> + // The duration trackers in the current bucket. + std::unordered_map<HashableDimensionKey, + std::unordered_map<HashableDimensionKey, std::unique_ptr<DurationTracker>>> mCurrentSlicedDurationTrackerMap; // Helper function to create a duration tracker given the metric aggregation type. diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp index f3307dc1d1e3..18694a1cadcd 100644 --- a/cmds/statsd/src/metrics/MetricProducer.cpp +++ b/cmds/statsd/src/metrics/MetricProducer.cpp @@ -37,7 +37,7 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo std::unordered_set<HashableDimensionKey> dimensionKeysInCondition; if (mConditionSliced) { for (const auto& link : mMetric2ConditionLinks) { - getDimensionForCondition(event, link, &conditionKey[link.conditionId]); + getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]); } auto conditionState = @@ -48,37 +48,30 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo condition = mCondition; } + if (mDimensionsInCondition.empty() && condition) { + dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY); + } + vector<HashableDimensionKey> dimensionInWhatValues; - if (mDimensionsInWhat.size() > 0) { + if (!mDimensionsInWhat.empty()) { filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhatValues); + } else { + dimensionInWhatValues.push_back(DEFAULT_DIMENSION_KEY); } - if (dimensionInWhatValues.empty() && dimensionKeysInCondition.empty()) { - onMatchedLogEventInternalLocked( - matcherIndex, DEFAULT_METRIC_DIMENSION_KEY, conditionKey, condition, event); - } else if (dimensionKeysInCondition.empty()) { - for (const HashableDimensionKey& whatValue : dimensionInWhatValues) { - onMatchedLogEventInternalLocked(matcherIndex, - MetricDimensionKey(whatValue, DEFAULT_DIMENSION_KEY), - conditionKey, condition, event); - } - } else if (dimensionInWhatValues.empty()) { + for (const auto& whatDimension : dimensionInWhatValues) { for (const auto& conditionDimensionKey : dimensionKeysInCondition) { onMatchedLogEventInternalLocked( - matcherIndex, - MetricDimensionKey(DEFAULT_DIMENSION_KEY, conditionDimensionKey), - conditionKey, condition, event); + matcherIndex, MetricDimensionKey(whatDimension, conditionDimensionKey), + conditionKey, condition, event); } - } else { - for (const auto& whatValue : dimensionInWhatValues) { - for (const auto& conditionDimensionKey : dimensionKeysInCondition) { - onMatchedLogEventInternalLocked( - matcherIndex, MetricDimensionKey(whatValue, conditionDimensionKey), - conditionKey, condition, event); - } + if (dimensionKeysInCondition.empty()) { + onMatchedLogEventInternalLocked( + matcherIndex, MetricDimensionKey(whatDimension, DEFAULT_DIMENSION_KEY), + conditionKey, condition, event); } } -} + } } // namespace statsd } // namespace os diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 83e1740c1fad..2bf624160475 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -233,7 +233,7 @@ protected: const LogEvent& event) = 0; // Consume the parsed stats log entry that already matched the "what" of the metric. - void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event); + virtual void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event); mutable std::mutex mMutex; }; |