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

Commit 8f2f3d82 authored by Bookatz's avatar Bookatz
Browse files

Anomaly Alert declarations in StatsdStats

StatsdStats now tracks the number of times an anomaly is detected (per
config, per alert name).

Also adds a configKey to AnomalyTracker, which is needed, not only for
statsdstats, but also (in the future) for reporting the header
information to incidentd.

Bug: 67978682
Test: adb shell data/nativetest64/statsd_test/statsd_test
Change-Id: Ib254db7e1edb4f0f193f4772d17f14934cdf7e30
parent 1d0136d3
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "Log.h"

#include "AnomalyTracker.h"
#include "guardrail/StatsdStats.h"

#include <android/os/IIncidentManager.h>
#include <android/os/IncidentReportArgs.h>
@@ -31,8 +32,9 @@ namespace statsd {
// TODO: Separate DurationAnomalyTracker as a separate subclass and let each MetricProducer
//       decide and let which one it wants.
// TODO: Get rid of bucketNumbers, and return to the original circular array method.
AnomalyTracker::AnomalyTracker(const Alert& alert)
AnomalyTracker::AnomalyTracker(const Alert& alert, const ConfigKey& configKey)
    : mAlert(alert),
      mConfigKey(configKey),
      mNumOfPastBuckets(mAlert.number_of_buckets() - 1) {
    VLOG("AnomalyTracker() called");
    if (mAlert.number_of_buckets() <= 0) {
@@ -220,6 +222,8 @@ void AnomalyTracker::declareAnomaly(const uint64_t& timestampNs) {
    } else {
        ALOGW("An anomaly has occurred! (But informing incidentd not requested.)");
    }

    StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.name());
}

void AnomalyTracker::declareAnomalyIfAlarmExpired(const HashableDimensionKey& dimensionKey,
+6 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <gtest/gtest_prod.h>
#include "AnomalyMonitor.h"
#include "config/ConfigKey.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
#include "stats_util.h"  // HashableDimensionKey and DimToValMap

@@ -35,7 +36,7 @@ using std::shared_ptr;
// Does NOT allow negative values.
class AnomalyTracker : public virtual RefBase {
public:
    AnomalyTracker(const Alert& alert);
    AnomalyTracker(const Alert& alert, const ConfigKey& configKey);

    virtual ~AnomalyTracker();

@@ -107,9 +108,13 @@ public:

protected:
    void flushPastBuckets(const int64_t& currBucketNum);

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

    // A reference to the Alert's config key.
    const ConfigKey& mConfigKey;

    // Number of past buckets. One less than the total number of buckets needed
    // for the anomaly detection (since the current bucket is not in the past).
    int mNumOfPastBuckets;
+24 −7
Original line number Diff line number Diff line
@@ -41,9 +41,6 @@ using std::vector;
const int FIELD_ID_BEGIN_TIME = 1;
const int FIELD_ID_END_TIME = 2;
const int FIELD_ID_CONFIG_STATS = 3;
const int FIELD_ID_MATCHER_STATS = 4;
const int FIELD_ID_CONDITION_STATS = 5;
const int FIELD_ID_METRIC_STATS = 6;
const int FIELD_ID_ATOM_STATS = 7;
const int FIELD_ID_UIDMAP_STATS = 8;
const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
@@ -104,11 +101,12 @@ void StatsdStats::noteConfigRemovedInternalLocked(const ConfigKey& key) {
    if (it != mConfigStats.end()) {
        int32_t nowTimeSec = time(nullptr);
        it->second.set_deletion_time_sec(nowTimeSec);
        // Add condition stats, metrics stats, matcher stats
        addSubStatsToConfig(key, it->second);
        // Add condition stats, metrics stats, matcher stats, alert stats
        addSubStatsToConfigLocked(key, it->second);
        // Remove them after they are added to the config stats.
        mMatcherStats.erase(key);
        mMetricsStats.erase(key);
        mAlertStats.erase(key);
        mConditionStats.erase(key);
        mIceBox.push_back(it->second);
        mConfigStats.erase(it);
@@ -222,6 +220,12 @@ void StatsdStats::noteMatcherMatched(const ConfigKey& key, const string& name) {
    matcherStats[name]++;
}

void StatsdStats::noteAnomalyDeclared(const ConfigKey& key, const string& name) {
    lock_guard<std::mutex> lock(mLock);
    auto& alertStats = mAlertStats[key];
    alertStats[name]++;
}

void StatsdStats::noteRegisteredAnomalyAlarmChanged() {
    lock_guard<std::mutex> lock(mLock);
    mAnomalyAlarmRegisteredStats++;
@@ -254,6 +258,7 @@ void StatsdStats::resetInternalLocked() {
    mConditionStats.clear();
    mMetricsStats.clear();
    std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0);
    mAlertStats.clear();
    mAnomalyAlarmRegisteredStats = 0;
    mMatcherStats.clear();
    for (auto& config : mConfigStats) {
@@ -263,10 +268,11 @@ void StatsdStats::resetInternalLocked() {
        config.second.clear_matcher_stats();
        config.second.clear_condition_stats();
        config.second.clear_metric_stats();
        config.second.clear_alert_stats();
    }
}

void StatsdStats::addSubStatsToConfig(const ConfigKey& key,
void StatsdStats::addSubStatsToConfigLocked(const ConfigKey& key,
                                      StatsdStatsReport_ConfigStats& configStats) {
    // Add matcher stats
    if (mMatcherStats.find(key) != mMatcherStats.end()) {
@@ -298,6 +304,16 @@ void StatsdStats::addSubStatsToConfig(const ConfigKey& key,
            VLOG("metrics %s max output tuple size %d", stats.first.c_str(), stats.second);
        }
    }
    // Add anomaly detection alert stats
    if (mAlertStats.find(key) != mAlertStats.end()) {
        const auto& alertStats = mAlertStats[key];
        for (const auto& stats : alertStats) {
            auto output = configStats.add_alert_stats();
            output->set_name(stats.first);
            output->set_declared_times(stats.second);
            VLOG("alert %s declared %d times", stats.first.c_str(), stats.second);
        }
    }
}

void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
@@ -367,7 +383,7 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
            }
        }

        addSubStatsToConfig(pair.first, configStats);
        addSubStatsToConfigLocked(pair.first, configStats);

        const int numBytes = configStats.ByteSize();
        vector<char> buffer(numBytes);
@@ -379,6 +395,7 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
        configStats.clear_matcher_stats();
        configStats.clear_condition_stats();
        configStats.clear_metric_stats();
        configStats.clear_alert_stats();
    }

    VLOG("********Atom stats***********");
+14 −1
Original line number Diff line number Diff line
@@ -111,6 +111,14 @@ public:
     */
    void noteMatcherMatched(const ConfigKey& key, const std::string& name);

    /**
     * Report that an anomaly detection alert has been declared.
     *
     * [key]: The config key that this alert belongs to.
     * [name]: The name of the alert.
     */
    void noteAnomalyDeclared(const ConfigKey& key, const std::string& name);

    /**
     * Report an atom event has been logged.
     */
@@ -183,6 +191,10 @@ private:
    // StatsCompanionService.
    int mAnomalyAlarmRegisteredStats = 0;

    // Stores the number of times an anomaly detection alert has been declared
    // (per config, per alert name).
    std::map<const ConfigKey, std::map<const std::string, int>> mAlertStats;

    // Stores how many times a matcher have been matched.
    std::map<const ConfigKey, std::map<const std::string, int>> mMatcherStats;

@@ -190,7 +202,8 @@ private:

    void resetInternalLocked();

    void addSubStatsToConfig(const ConfigKey& key, StatsdStatsReport_ConfigStats& configStats);
    void addSubStatsToConfigLocked(const ConfigKey& key,
                                   StatsdStatsReport_ConfigStats& configStats);

    void noteDataDropped(const ConfigKey& key, int32_t timeSec);

+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ sp<AnomalyTracker> DurationMetricProducer::createAnomalyTracker(const Alert &ale
        return nullptr;
    }
    // TODO: return a DurationAnomalyTracker (which should sublclass AnomalyTracker)
    return new AnomalyTracker(alert);
    return new AnomalyTracker(alert, mConfigKey);
}

void DurationMetricProducer::startNewProtoOutputStreamLocked(long long startTime) {
Loading