1/ Duration anomaly tracker with alarm.
2/ Init anomaly from config based on the public language.
3/ Unit tests for anomaly detection in count/gauge producer.
4/ Revisit the duration tracker logic.
Test: unit test passed.
Change-Id: I2423c0e0f05b1e37626954de9e749303423963f2
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index eba2e06..b0a97b1 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -110,16 +110,16 @@
}
unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
- vector<DurationBucket>& bucket) {
+ const HashableDimensionKey& eventKey, vector<DurationBucket>& bucket) {
switch (mMetric.aggregation_type()) {
case DurationMetric_AggregationType_SUM:
- return make_unique<OringDurationTracker>(mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mBucketSizeNs,
- bucket);
+ return make_unique<OringDurationTracker>(eventKey, mWizard, mConditionTrackerIndex,
+ mNested, mCurrentBucketStartTimeNs,
+ mBucketSizeNs, mAnomalyTrackers, bucket);
case DurationMetric_AggregationType_MAX_SPARSE:
- return make_unique<MaxDurationTracker>(mWizard, mConditionTrackerIndex, mNested,
- mCurrentBucketStartTimeNs, mBucketSizeNs,
- bucket);
+ return make_unique<MaxDurationTracker>(eventKey, mWizard, mConditionTrackerIndex,
+ mNested, mCurrentBucketStartTimeNs,
+ mBucketSizeNs, mAnomalyTrackers, bucket);
}
}
@@ -131,7 +131,6 @@
void DurationMetricProducer::onSlicedConditionMayChange(const uint64_t eventTime) {
VLOG("Metric %s onSlicedConditionMayChange", mMetric.name().c_str());
// Now for each of the on-going event, check if the condition has changed for them.
- flushIfNeeded(eventTime);
for (auto& pair : mCurrentSlicedDuration) {
pair.second->onSlicedConditionMayChange(eventTime);
}
@@ -142,27 +141,11 @@
mCondition = conditionMet;
// TODO: need to populate the condition change time from the event which triggers the condition
// change, instead of using current time.
-
- flushIfNeeded(eventTime);
for (auto& pair : mCurrentSlicedDuration) {
pair.second->onConditionChanged(conditionMet, eventTime);
}
}
-static void addDurationBucketsToReport(StatsLogReport_DurationMetricDataWrapper& wrapper,
- const vector<KeyValuePair>& key,
- const vector<DurationBucketInfo>& buckets) {
- DurationMetricData* data = wrapper.add_data();
- for (const auto& kv : key) {
- data->add_dimension()->CopyFrom(kv);
- }
- for (const auto& bucket : buckets) {
- data->add_bucket_info()->CopyFrom(bucket);
- VLOG("\t bucket [%lld - %lld] duration(ns): %lld", bucket.start_bucket_nanos(),
- bucket.end_bucket_nanos(), bucket.duration_nanos());
- }
-}
-
std::unique_ptr<std::vector<uint8_t>> DurationMetricProducer::onDumpReport() {
long long endTime = time(nullptr) * NS_PER_SEC;
@@ -231,7 +214,6 @@
if (mCurrentBucketStartTimeNs + mBucketSizeNs > eventTime) {
return;
}
-
VLOG("flushing...........");
for (auto it = mCurrentSlicedDuration.begin(); it != mCurrentSlicedDuration.end();) {
if (it->second->flushIfNeeded(eventTime)) {
@@ -244,6 +226,7 @@
int numBucketsForward = (eventTime - mCurrentBucketStartTimeNs) / mBucketSizeNs;
mCurrentBucketStartTimeNs += numBucketsForward * mBucketSizeNs;
+ mCurrentBucketNum += numBucketsForward;
}
void DurationMetricProducer::onMatchedLogEventInternal(
@@ -262,7 +245,7 @@
HashableDimensionKey atomKey = getHashableKey(getDimensionKey(event, mInternalDimension));
if (mCurrentSlicedDuration.find(eventKey) == mCurrentSlicedDuration.end()) {
- mCurrentSlicedDuration[eventKey] = createDurationTracker(mPastBuckets[eventKey]);
+ mCurrentSlicedDuration[eventKey] = createDurationTracker(eventKey, mPastBuckets[eventKey]);
}
auto it = mCurrentSlicedDuration.find(eventKey);