Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be10ddfe authored by Yangster-mac's avatar Yangster-mac
Browse files

Flush the past buckets in anomaly tracker when time jumps forward

E2e test for count/duration anomaly trackers.

Test: new statsd tests.

BUG: b/74446029

Change-Id: Ia9be0240ba5021d44c1e1f096d67563e9138bb59
parent 651ac4d1
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -205,7 +205,9 @@ LOCAL_SRC_FILES := \
    tests/e2e/GaugeMetric_e2e_push_test.cpp \
    tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp \
    tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp \
    tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
    tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp \
    tests/e2e/Anomaly_count_e2e_test.cpp \
    tests/e2e/Anomaly_duration_sum_e2e_test.cpp

LOCAL_STATIC_LIBRARIES := \
    $(statsd_common_static_libraries) \
+10 −3
Original line number Diff line number Diff line
@@ -69,6 +69,11 @@ public:
    void dumpStates(FILE* out, bool verbose);

private:
    // For testing only.
    inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
        return mAnomalyAlarmMonitor;
    }

    mutable mutex mMetricsMutex;

    std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers;
@@ -133,13 +138,15 @@ private:
    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition);
    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition);



    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition);
    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition);
    FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition);


    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
};

}  // namespace statsd
+7 −7
Original line number Diff line number Diff line
@@ -66,6 +66,9 @@ size_t AnomalyTracker::index(int64_t bucketNum) const {

void AnomalyTracker::advanceMostRecentBucketTo(const int64_t& bucketNum) {
    VLOG("advanceMostRecentBucketTo() called.");
    if (mNumOfPastBuckets <= 0) {
        return;
    }
    if (bucketNum <= mMostRecentBucketNum) {
        ALOGW("Cannot advance buckets backwards (bucketNum=%lld but mMostRecentBucketNum=%lld)",
              (long long)bucketNum, (long long)mMostRecentBucketNum);
@@ -170,7 +173,8 @@ void AnomalyTracker::addBucketToSum(const shared_ptr<DimToValMap>& bucket) {

int64_t AnomalyTracker::getPastBucketValue(const MetricDimensionKey& key,
                                           const int64_t& bucketNum) const {
    if (bucketNum < 0 || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets
    if (bucketNum < 0 || mMostRecentBucketNum < 0
            || bucketNum <= mMostRecentBucketNum - mNumOfPastBuckets
            || bucketNum > mMostRecentBucketNum) {
        return 0;
    }
@@ -241,14 +245,10 @@ void AnomalyTracker::detectAndDeclareAnomaly(const uint64_t& timestampNs,
}

bool AnomalyTracker::isInRefractoryPeriod(const uint64_t& timestampNs,
                                          const MetricDimensionKey& key) {
                                          const MetricDimensionKey& key) const {
    const auto& it = mRefractoryPeriodEndsSec.find(key);
    if (it != mRefractoryPeriodEndsSec.end()) {
        if (timestampNs < it->second * NS_PER_SEC) {
            return true;
        } else {
            mRefractoryPeriodEndsSec.erase(key);
        }
        return timestampNs < it->second * NS_PER_SEC;
    }
    return false;
}
+11 −2
Original line number Diff line number Diff line
@@ -113,6 +113,13 @@ public:
    }

protected:
    // For testing only.
    // Returns the alarm timestamp in seconds for the query dimension if it exists. Otherwise
    // returns 0.
    virtual uint32_t getAlarmTimestampSec(const MetricDimensionKey& dimensionKey) const {
        return 0;   // The base AnomalyTracker class doesn't have alarms.
    }

    // statsd_config.proto Alert message that defines this tracker.
    const Alert mAlert;

@@ -159,8 +166,7 @@ protected:
    void subtractValueFromSum(const MetricDimensionKey& key, const int64_t& bucketValue);

    // Returns true if in the refractory period, else false.
    // If there is a stored refractory period but it ended prior to timestampNs, it is removed.
    bool isInRefractoryPeriod(const uint64_t& timestampNs, const MetricDimensionKey& key);
    bool isInRefractoryPeriod(const uint64_t& timestampNs, const MetricDimensionKey& key) const;

    // Calculates the corresponding bucket index within the circular array.
    // Requires bucketNum >= 0.
@@ -176,6 +182,9 @@ protected:
    FRIEND_TEST(AnomalyTrackerTest, TestSparseBuckets);
    FRIEND_TEST(GaugeMetricProducerTest, TestAnomalyDetection);
    FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
};

}  // namespace statsd
+3 −4
Original line number Diff line number Diff line
@@ -40,9 +40,8 @@ void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey,
    // Alarms are stored in secs. Must round up, since if it fires early, it is ignored completely.
    uint32_t timestampSec = static_cast<uint32_t>((timestampNs -1) / NS_PER_SEC) + 1; // round up
    if (isInRefractoryPeriod(timestampNs, dimensionKey)) {
        // TODO: Bug! By the refractory's end, the data might be erased and the alarm inapplicable.
        VLOG("Setting a delayed anomaly alarm lest it fall in the refractory period");
        timestampSec = getRefractoryPeriodEndsSec(dimensionKey) + 1;
        VLOG("Not setting anomaly alarm since it would fall in the refractory period.");
        return;
    }

    auto itr = mAlarms.find(dimensionKey);
Loading