diff options
| author | 2017-12-08 03:50:57 +0000 | |
|---|---|---|
| committer | 2017-12-08 03:50:57 +0000 | |
| commit | c51ec6767f7fb17336ca59bbab22d476879c400a (patch) | |
| tree | 522db3f4a76826e855450b4f4b78200583b4f6bd | |
| parent | 2514d1ca7910a34502c04e9b5e70066431a3a78c (diff) | |
| parent | 8f2f3d82053693b0dac828e848e2bb238e1db2d2 (diff) | |
Merge changes Ib254db7e,I4aa0539a
* changes:
Anomaly Alert declarations in StatsdStats
Anomaly detection statsdstats
| -rw-r--r-- | cmds/statsd/src/StatsService.cpp | 2 | ||||
| -rw-r--r-- | cmds/statsd/src/StatsService.h | 4 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AnomalyMonitor.cpp | 21 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AnomalyMonitor.h | 6 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AnomalyTracker.cpp | 6 | ||||
| -rw-r--r-- | cmds/statsd/src/anomaly/AnomalyTracker.h | 7 | ||||
| -rw-r--r-- | cmds/statsd/src/guardrail/StatsdStats.cpp | 49 | ||||
| -rw-r--r-- | cmds/statsd/src/guardrail/StatsdStats.h | 25 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/DurationMetricProducer.cpp | 2 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/MetricProducer.h | 2 | ||||
| -rw-r--r-- | cmds/statsd/src/stats_log.proto | 11 | ||||
| -rw-r--r-- | cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp | 6 | ||||
| -rw-r--r-- | cmds/statsd/tests/guardrail/StatsdStats_test.cpp | 32 | ||||
| -rw-r--r-- | cmds/statsd/tests/metrics/CountMetricProducer_test.cpp | 2 | ||||
| -rw-r--r-- | cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp | 4 | ||||
| -rw-r--r-- | cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp | 2 | ||||
| -rw-r--r-- | cmds/statsd/tests/metrics/OringDurationTracker_test.cpp | 4 |
17 files changed, 156 insertions, 29 deletions
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index fa7fe0c0bae7..dc12efb2666e 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -72,7 +72,7 @@ void CompanionDeathRecipient::binderDied(const wp<IBinder>& who) { // ====================================================================== StatsService::StatsService(const sp<Looper>& handlerLooper) - : mAnomalyMonitor(new AnomalyMonitor(2)) // TODO: Put this comment somewhere better + : mAnomalyMonitor(new AnomalyMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS)) { mUidMap = new UidMap(); mConfigManager = new ConfigManager(); diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index bdae1ef62ff0..e434f65872a6 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -46,6 +46,10 @@ public: StatsService(const sp<Looper>& handlerLooper); virtual ~StatsService(); + /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */ + // TODO: Consider making this configurable. And choose a good number. + const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5; + virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); virtual status_t dump(int fd, const Vector<String16>& args); virtual status_t command(FILE* in, FILE* out, FILE* err, Vector<String8>& args); diff --git a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp index 2b2bcfc18fbf..4912648b648d 100644 --- a/cmds/statsd/src/anomaly/AnomalyMonitor.cpp +++ b/cmds/statsd/src/anomaly/AnomalyMonitor.cpp @@ -18,6 +18,7 @@ #include "Log.h" #include "anomaly/AnomalyMonitor.h" +#include "guardrail/StatsdStats.h" namespace android { namespace os { @@ -76,10 +77,7 @@ void AnomalyMonitor::remove(sp<const AnomalyAlarm> alarm) { if (!wasPresent) return; if (mPq.empty()) { if (DEBUG) ALOGD("Queue is empty. Cancel any alarm."); - mRegisteredAlarmTimeSec = 0; - if (mStatsCompanionService != nullptr) { - mStatsCompanionService->cancelAnomalyAlarm(); - } + cancelRegisteredAlarmTime_l(); return; } uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec; @@ -106,10 +104,7 @@ unordered_set<sp<const AnomalyAlarm>, SpHash<AnomalyAlarm>> AnomalyMonitor::popS if (!oldAlarms.empty()) { if (mPq.empty()) { if (DEBUG) ALOGD("Queue is empty. Cancel any alarm."); - mRegisteredAlarmTimeSec = 0; - if (mStatsCompanionService != nullptr) { - mStatsCompanionService->cancelAnomalyAlarm(); - } + cancelRegisteredAlarmTime_l(); } else { // Always update the registered alarm in this case (unlike remove()). updateRegisteredAlarmTime_l(mPq.top()->timestampSec); @@ -123,6 +118,16 @@ void AnomalyMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) { mRegisteredAlarmTimeSec = timestampSec; if (mStatsCompanionService != nullptr) { mStatsCompanionService->setAnomalyAlarm(secToMs(mRegisteredAlarmTimeSec)); + StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); + } +} + +void AnomalyMonitor::cancelRegisteredAlarmTime_l() { + if (DEBUG) ALOGD("Cancelling reg alarm."); + mRegisteredAlarmTimeSec = 0; + if (mStatsCompanionService != nullptr) { + mStatsCompanionService->cancelAnomalyAlarm(); + StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); } } diff --git a/cmds/statsd/src/anomaly/AnomalyMonitor.h b/cmds/statsd/src/anomaly/AnomalyMonitor.h index e19c46929a19..7acc7904bb57 100644 --- a/cmds/statsd/src/anomaly/AnomalyMonitor.h +++ b/cmds/statsd/src/anomaly/AnomalyMonitor.h @@ -138,6 +138,12 @@ private: */ void updateRegisteredAlarmTime_l(uint32_t timestampSec); + /** + * Cancels the alarm registered with StatsCompanionService. + * Also correspondingly sets mRegisteredAlarmTimeSec to 0. + */ + void cancelRegisteredAlarmTime_l(); + /** Converts uint32 timestamp in seconds to a Java long in msec. */ int64_t secToMs(uint32_t timeSec); }; diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp index 7bacb441ee48..e8b408328181 100644 --- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp +++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp @@ -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, diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h index 49e83235f73b..874add2ba798 100644 --- a/cmds/statsd/src/anomaly/AnomalyTracker.h +++ b/cmds/statsd/src/anomaly/AnomalyTracker.h @@ -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; diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index 29574579b2a0..b02b9daa4b2d 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -41,11 +41,9 @@ 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; const int FIELD_ID_MATCHER_STATS_NAME = 1; const int FIELD_ID_MATCHER_STATS_COUNT = 2; @@ -59,6 +57,8 @@ const int FIELD_ID_METRIC_STATS_COUNT = 2; const int FIELD_ID_ATOM_STATS_TAG = 1; const int FIELD_ID_ATOM_STATS_COUNT = 2; +const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1; + // TODO: add stats for pulled atoms. StatsdStats::StatsdStats() { mPushedAtomStats.resize(android::util::kMaxPushedAtomId + 1); @@ -101,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); @@ -219,6 +220,17 @@ 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++; +} + void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) { lock_guard<std::mutex> lock(mLock); @@ -246,6 +258,8 @@ void StatsdStats::resetInternalLocked() { mConditionStats.clear(); mMetricsStats.clear(); std::fill(mPushedAtomStats.begin(), mPushedAtomStats.end(), 0); + mAlertStats.clear(); + mAnomalyAlarmRegisteredStats = 0; mMatcherStats.clear(); for (auto& config : mConfigStats) { config.second.clear_broadcast_sent_time_sec(); @@ -254,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()) { @@ -289,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) { @@ -358,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); @@ -370,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***********"); @@ -386,6 +412,15 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { } } + if (mAnomalyAlarmRegisteredStats > 0) { + VLOG("********AnomalyAlarmStats stats***********"); + long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS); + proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED, + mAnomalyAlarmRegisteredStats); + proto.end(token); + VLOG("Anomaly alarm registrations: %d", mAnomalyAlarmRegisteredStats); + } + const int numBytes = mUidMapStats.ByteSize(); vector<char> buffer(numBytes); mUidMapStats.SerializeToArray(&buffer[0], numBytes); diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index d6f6566cbc33..394056303722 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -112,11 +112,24 @@ 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. */ void noteAtomLogged(int atomId, int32_t timeSec); /** + * Report that statsd modified the anomaly alarm registered with StatsCompanionService. + */ + void noteRegisteredAnomalyAlarmChanged(); + + /** * Records the number of snapshot and delta entries that are being dropped from the uid map. */ void noteUidMapDropped(int snapshots, int deltas); @@ -174,6 +187,14 @@ private: // This is a vector, not a map because it will be accessed A LOT -- for each stats log. std::vector<int> mPushedAtomStats; + // Stores the number of times statsd modified the anomaly alarm registered with + // 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; @@ -181,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); @@ -195,6 +217,7 @@ private: FRIEND_TEST(StatsdStatsTest, TestSubStats); FRIEND_TEST(StatsdStatsTest, TestAtomLog); FRIEND_TEST(StatsdStatsTest, TestTimestampThreshold); + FRIEND_TEST(StatsdStatsTest, TestAnomalyMonitor); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp index fd484c25dbaa..cedea301de27 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -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) { diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index e7e84ab1dcc8..adeb3cdf258a 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -94,7 +94,7 @@ public: } virtual sp<AnomalyTracker> createAnomalyTracker(const Alert &alert) { - return new AnomalyTracker(alert); + return new AnomalyTracker(alert, mConfigKey); } void addAnomalyTracker(sp<AnomalyTracker> tracker) { diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto index 60d9a3dbb9d2..f8b91fe0ef0a 100644 --- a/cmds/statsd/src/stats_log.proto +++ b/cmds/statsd/src/stats_log.proto @@ -193,6 +193,11 @@ message StatsdStatsReport { optional int32 max_tuple_counts = 2; } + message AlertStats { + optional string name = 1; + optional int32 declared_times = 2; + } + message ConfigStats { optional int32 uid = 1; optional string name = 2; @@ -210,6 +215,7 @@ message StatsdStatsReport { repeated MatcherStats matcher_stats = 13; repeated ConditionStats condition_stats = 14; repeated MetricStats metric_stats = 15; + repeated AlertStats alert_stats = 16; } repeated ConfigStats config_stats = 3; @@ -229,4 +235,9 @@ message StatsdStatsReport { optional int32 dropped_changes = 5; } optional UidMapStats uidmap_stats = 8; + + message AnomalyAlarmStats { + optional int32 alarms_registered = 1; + } + optional AnomalyAlarmStats anomaly_alarm_stats = 9; }
\ No newline at end of file diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp index 65c2a05543b9..f38576398f11 100644 --- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp +++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp @@ -30,6 +30,8 @@ namespace android { namespace os { namespace statsd { +const ConfigKey kConfigKey(0, "test"); + void AddValueToBucket(const std::vector<std::pair<string, long>>& key_value_pair_list, std::shared_ptr<DimToValMap> bucket) { for (auto itr = key_value_pair_list.begin(); itr != key_value_pair_list.end(); itr++) { @@ -51,7 +53,7 @@ TEST(AnomalyTrackerTest, TestConsecutiveBuckets) { alert.set_refractory_period_secs(2 * bucketSizeNs / NS_PER_SEC); alert.set_trigger_if_sum_gt(2); - AnomalyTracker anomalyTracker(alert); + AnomalyTracker anomalyTracker(alert, kConfigKey); std::shared_ptr<DimToValMap> bucket0 = MockBucket({{"a", 1}, {"b", 2}, {"c", 1}}); int64_t eventTimestamp0 = 10; @@ -168,7 +170,7 @@ TEST(AnomalyTrackerTest, TestSparseBuckets) { alert.set_refractory_period_secs(2 * bucketSizeNs / NS_PER_SEC); alert.set_trigger_if_sum_gt(2); - AnomalyTracker anomalyTracker(alert); + AnomalyTracker anomalyTracker(alert, kConfigKey); std::shared_ptr<DimToValMap> bucket9 = MockBucket({{"a", 1}, {"b", 2}, {"c", 1}}); std::shared_ptr<DimToValMap> bucket16 = MockBucket({{"b", 4}}); diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp index a8193dd92e8c..9fed4f8b5e30 100644 --- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp +++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp @@ -118,6 +118,10 @@ TEST(StatsdStatsTest, TestSubStats) { stats.noteMetricDimensionSize(key, "metric1", 201); stats.noteMetricDimensionSize(key, "metric1", 202); + stats.noteAnomalyDeclared(key, "alert1"); + stats.noteAnomalyDeclared(key, "alert1"); + stats.noteAnomalyDeclared(key, "alert2"); + // broadcast-> 2 stats.noteBroadcastSent(key); stats.noteBroadcastSent(key); @@ -142,7 +146,6 @@ TEST(StatsdStatsTest, TestSubStats) { EXPECT_EQ(3, configReport.dump_report_time_sec_size()); EXPECT_EQ(2, configReport.matcher_stats_size()); - // matcher1 is the first in the list if (!configReport.matcher_stats(0).name().compare("matcher1")) { EXPECT_EQ(2, configReport.matcher_stats(0).matched_times()); @@ -157,6 +160,13 @@ TEST(StatsdStatsTest, TestSubStats) { EXPECT_EQ("matcher1", configReport.matcher_stats(1).name()); } + EXPECT_EQ(2, configReport.alert_stats_size()); + bool alert1first = !configReport.alert_stats(0).name().compare("alert1"); + EXPECT_EQ("alert1", configReport.alert_stats(alert1first ? 0 : 1).name()); + EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).declared_times()); + EXPECT_EQ("alert2", configReport.alert_stats(alert1first ? 1 : 0).name()); + EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).declared_times()); + EXPECT_EQ(1, configReport.condition_stats_size()); EXPECT_EQ("condition1", configReport.condition_stats(0).name()); EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts()); @@ -169,6 +179,7 @@ TEST(StatsdStatsTest, TestSubStats) { stats.noteMatcherMatched(key, "matcher99"); stats.noteConditionDimensionSize(key, "condition99", 300); stats.noteMetricDimensionSize(key, "metric99", 270); + stats.noteAnomalyDeclared(key, "alert99"); // now the config stats should only contain the stats about the new event. stats.dumpStats(&output, false); @@ -187,6 +198,10 @@ TEST(StatsdStatsTest, TestSubStats) { EXPECT_EQ(1, configReport2.metric_stats_size()); EXPECT_EQ("metric99", configReport2.metric_stats(0).name()); EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts()); + + EXPECT_EQ(1, configReport2.alert_stats_size()); + EXPECT_EQ("alert99", configReport2.alert_stats(0).name()); + EXPECT_EQ(1, configReport2.alert_stats(0).declared_times()); } TEST(StatsdStatsTest, TestAtomLog) { @@ -224,6 +239,21 @@ TEST(StatsdStatsTest, TestAtomLog) { EXPECT_TRUE(sensorAtomGood); } + +TEST(StatsdStatsTest, TestAnomalyMonitor) { + StatsdStats stats; + stats.noteRegisteredAnomalyAlarmChanged(); + stats.noteRegisteredAnomalyAlarmChanged(); + + vector<uint8_t> output; + stats.dumpStats(&output, false); + StatsdStatsReport report; + bool good = report.ParseFromArray(&output[0], output.size()); + EXPECT_TRUE(good); + + EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered()); +} + TEST(StatsdStatsTest, TestTimestampThreshold) { StatsdStats stats; vector<int32_t> timestamps; diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp index 9b94099625a5..d973ba1676a9 100644 --- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp @@ -196,7 +196,7 @@ TEST(CountMetricProducerTest, TestAnomalyDetection) { int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs; int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs; - sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert); + sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey); CountMetric metric; metric.set_name("1"); diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index ed13db25397a..59475d266217 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -33,6 +33,8 @@ namespace android { namespace os { namespace statsd { +const ConfigKey kConfigKey(0, "test"); + TEST(GaugeMetricProducerTest, TestWithCondition) { int64_t bucketStartTimeNs = 10000000000; int64_t bucketSizeNs = 60 * 1000 * 1000 * 1000LL; @@ -148,7 +150,7 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) { alert.set_metric_name("1"); alert.set_trigger_if_sum_gt(25); alert.set_number_of_buckets(2); - sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert); + sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey); gaugeProducer.addAnomalyTracker(anomalyTracker); std::shared_ptr<LogEvent> event1 = std::make_shared<LogEvent>(1, bucketStartTimeNs + 1); diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp index 1adcc1146c42..4e5e0d6dbfb3 100644 --- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp +++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp @@ -208,7 +208,7 @@ TEST(MaxDurationTrackerTest, TestAnomalyDetection) { uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1; uint64_t bucketSizeNs = 30 * NS_PER_SEC; - sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert); + sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey); MaxDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, -1, true, bucketStartTimeNs, bucketSizeNs, {anomalyTracker}); diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp index fa7b9a734524..99d3e054d893 100644 --- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp +++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp @@ -269,7 +269,7 @@ TEST(OringDurationTrackerTest, TestPredictAnomalyTimestamp) { uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1; uint64_t bucketSizeNs = 30 * NS_PER_SEC; - sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert); + sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey); OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true, bucketStartTimeNs, bucketSizeNs, {anomalyTracker}); @@ -331,7 +331,7 @@ TEST(OringDurationTrackerTest, TestAnomalyDetection) { uint64_t eventStartTimeNs = bucketStartTimeNs + NS_PER_SEC + 1; uint64_t bucketSizeNs = 30 * NS_PER_SEC; - sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert); + sp<AnomalyTracker> anomalyTracker = new AnomalyTracker(alert, kConfigKey); OringDurationTracker tracker(kConfigKey, "metric", eventKey, wizard, 1, true /*nesting*/, bucketStartTimeNs, bucketSizeNs, {anomalyTracker}); |