summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2017-12-08 03:50:57 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-12-08 03:50:57 +0000
commitc51ec6767f7fb17336ca59bbab22d476879c400a (patch)
tree522db3f4a76826e855450b4f4b78200583b4f6bd
parent2514d1ca7910a34502c04e9b5e70066431a3a78c (diff)
parent8f2f3d82053693b0dac828e848e2bb238e1db2d2 (diff)
Merge changes Ib254db7e,I4aa0539a
* changes: Anomaly Alert declarations in StatsdStats Anomaly detection statsdstats
-rw-r--r--cmds/statsd/src/StatsService.cpp2
-rw-r--r--cmds/statsd/src/StatsService.h4
-rw-r--r--cmds/statsd/src/anomaly/AnomalyMonitor.cpp21
-rw-r--r--cmds/statsd/src/anomaly/AnomalyMonitor.h6
-rw-r--r--cmds/statsd/src/anomaly/AnomalyTracker.cpp6
-rw-r--r--cmds/statsd/src/anomaly/AnomalyTracker.h7
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.cpp49
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.h25
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp2
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.h2
-rw-r--r--cmds/statsd/src/stats_log.proto11
-rw-r--r--cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp6
-rw-r--r--cmds/statsd/tests/guardrail/StatsdStats_test.cpp32
-rw-r--r--cmds/statsd/tests/metrics/CountMetricProducer_test.cpp2
-rw-r--r--cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp4
-rw-r--r--cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp2
-rw-r--r--cmds/statsd/tests/metrics/OringDurationTracker_test.cpp4
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});