Merge "Includes annotations with statsd reports." into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b61f80b42b
@@ -77,6 +77,9 @@ const int FIELD_ID_CONFIG_STATS_CONDITION_STATS = 14;
|
||||
const int FIELD_ID_CONFIG_STATS_METRIC_STATS = 15;
|
||||
const int FIELD_ID_CONFIG_STATS_ALERT_STATS = 16;
|
||||
const int FIELD_ID_CONFIG_STATS_METRIC_DIMENSION_IN_CONDITION_STATS = 17;
|
||||
const int FIELD_ID_CONFIG_STATS_ANNOTATION = 18;
|
||||
const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT64 = 1;
|
||||
const int FIELD_ID_CONFIG_STATS_ANNOTATION_INT32 = 2;
|
||||
|
||||
const int FIELD_ID_MATCHER_STATS_ID = 1;
|
||||
const int FIELD_ID_MATCHER_STATS_COUNT = 2;
|
||||
@@ -116,8 +119,10 @@ void StatsdStats::addToIceBoxLocked(shared_ptr<ConfigStats>& stats) {
|
||||
mIceBox.push_back(stats);
|
||||
}
|
||||
|
||||
void StatsdStats::noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
|
||||
int matchersCount, int alertsCount, bool isValid) {
|
||||
void StatsdStats::noteConfigReceived(
|
||||
const ConfigKey& key, int metricsCount, int conditionsCount, int matchersCount,
|
||||
int alertsCount, const std::list<std::pair<const int64_t, const int32_t>>& annotations,
|
||||
bool isValid) {
|
||||
lock_guard<std::mutex> lock(mLock);
|
||||
int32_t nowTimeSec = getWallClockSec();
|
||||
|
||||
@@ -133,6 +138,9 @@ void StatsdStats::noteConfigReceived(const ConfigKey& key, int metricsCount, int
|
||||
configStats->matcher_count = matchersCount;
|
||||
configStats->alert_count = alertsCount;
|
||||
configStats->is_valid = isValid;
|
||||
for (auto& v : annotations) {
|
||||
configStats->annotations.emplace_back(v);
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
mConfigStats[key] = configStats;
|
||||
@@ -351,6 +359,7 @@ void StatsdStats::resetInternalLocked() {
|
||||
config.second->broadcast_sent_time_sec.clear();
|
||||
config.second->data_drop_time_sec.clear();
|
||||
config.second->dump_report_time_sec.clear();
|
||||
config.second->annotations.clear();
|
||||
config.second->matcher_stats.clear();
|
||||
config.second->condition_stats.clear();
|
||||
config.second->metric_stats.clear();
|
||||
@@ -394,6 +403,11 @@ void StatsdStats::dumpStats(FILE* out) const {
|
||||
configStats->deletion_time_sec, configStats->metric_count,
|
||||
configStats->condition_count, configStats->matcher_count, configStats->alert_count,
|
||||
configStats->is_valid);
|
||||
for (const auto& annotation : configStats->annotations) {
|
||||
fprintf(out, "\tannotation: %lld, %d\n", (long long)annotation.first,
|
||||
annotation.second);
|
||||
}
|
||||
|
||||
for (const auto& broadcastTime : configStats->broadcast_sent_time_sec) {
|
||||
fprintf(out, "\tbroadcast time: %d\n", broadcastTime);
|
||||
}
|
||||
@@ -497,6 +511,15 @@ void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* pr
|
||||
dump);
|
||||
}
|
||||
|
||||
for (const auto& annotation : configStats.annotations) {
|
||||
uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
|
||||
FIELD_ID_CONFIG_STATS_ANNOTATION);
|
||||
proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT64,
|
||||
(long long)annotation.first);
|
||||
proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_ANNOTATION_INT32, annotation.second);
|
||||
proto->end(token);
|
||||
}
|
||||
|
||||
for (const auto& pair : configStats.matcher_stats) {
|
||||
uint64_t tmpToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
|
||||
FIELD_ID_CONFIG_STATS_MATCHER_STATS);
|
||||
|
||||
@@ -66,6 +66,9 @@ struct ConfigStats {
|
||||
// Stores the number of times an anomaly detection alert has been declared.
|
||||
// The map size is capped by kMaxConfigCount.
|
||||
std::map<const int64_t, int> alert_stats;
|
||||
|
||||
// Stores the config ID for each sub-config used.
|
||||
std::list<std::pair<const int64_t, const int32_t>> annotations;
|
||||
};
|
||||
|
||||
struct UidMapStats {
|
||||
@@ -142,7 +145,9 @@ public:
|
||||
* If the config is not valid, this config stats will be put into icebox immediately.
|
||||
*/
|
||||
void noteConfigReceived(const ConfigKey& key, int metricsCount, int conditionsCount,
|
||||
int matchersCount, int alertCount, bool isValid);
|
||||
int matchersCount, int alertCount,
|
||||
const std::list<std::pair<const int64_t, const int32_t>>& annotations,
|
||||
bool isValid);
|
||||
/**
|
||||
* Report a config has been removed.
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <utils/SystemClock.h>
|
||||
|
||||
using android::util::FIELD_COUNT_REPEATED;
|
||||
using android::util::FIELD_TYPE_INT32;
|
||||
using android::util::FIELD_TYPE_INT64;
|
||||
using android::util::FIELD_TYPE_MESSAGE;
|
||||
using android::util::ProtoOutputStream;
|
||||
|
||||
@@ -47,6 +49,9 @@ namespace os {
|
||||
namespace statsd {
|
||||
|
||||
const int FIELD_ID_METRICS = 1;
|
||||
const int FIELD_ID_ANNOTATIONS = 7;
|
||||
const int FIELD_ID_ANNOTATIONS_INT64 = 1;
|
||||
const int FIELD_ID_ANNOTATIONS_INT32 = 2;
|
||||
|
||||
MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
|
||||
const long timeBaseSec, const long currentTimeSec,
|
||||
@@ -85,6 +90,11 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
|
||||
}
|
||||
}
|
||||
|
||||
// Store the sub-configs used.
|
||||
for (const auto& annotation : config.annotation()) {
|
||||
mAnnotations.emplace_back(annotation.field_int64(), annotation.field_int32());
|
||||
}
|
||||
|
||||
// Guardrail. Reject the config if it's too big.
|
||||
if (mAllMetricProducers.size() > StatsdStats::kMaxMetricCountPerConfig ||
|
||||
mAllConditionTrackers.size() > StatsdStats::kMaxConditionCountPerConfig ||
|
||||
@@ -97,11 +107,9 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
|
||||
mConfigValid = false;
|
||||
}
|
||||
// no matter whether this config is valid, log it in the stats.
|
||||
StatsdStats::getInstance().noteConfigReceived(key, mAllMetricProducers.size(),
|
||||
mAllConditionTrackers.size(),
|
||||
mAllAtomMatchers.size(),
|
||||
mAllAnomalyTrackers.size(),
|
||||
mConfigValid);
|
||||
StatsdStats::getInstance().noteConfigReceived(
|
||||
key, mAllMetricProducers.size(), mAllConditionTrackers.size(), mAllAtomMatchers.size(),
|
||||
mAllAnomalyTrackers.size(), mAnnotations, mConfigValid);
|
||||
}
|
||||
|
||||
MetricsManager::~MetricsManager() {
|
||||
@@ -188,6 +196,14 @@ void MetricsManager::onDumpReport(const uint64_t dumpTimeStampNs, ProtoOutputStr
|
||||
protoOutput->end(token);
|
||||
}
|
||||
}
|
||||
for (const auto& annotation : mAnnotations) {
|
||||
uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
|
||||
FIELD_ID_ANNOTATIONS);
|
||||
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ANNOTATIONS_INT64,
|
||||
(long long)annotation.first);
|
||||
protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_ANNOTATIONS_INT32, annotation.second);
|
||||
protoOutput->end(token);
|
||||
}
|
||||
mLastReportTimeNs = dumpTimeStampNs;
|
||||
mLastReportWallClockNs = getWallClockNs();
|
||||
VLOG("=========================Metric Reports End==========================");
|
||||
|
||||
@@ -107,6 +107,9 @@ private:
|
||||
// Logs from uids that are not in the list will be ignored to avoid spamming.
|
||||
std::set<int32_t> mAllowedLogSources;
|
||||
|
||||
// Contains the annotations passed in with StatsdConfig.
|
||||
std::list<std::pair<const int64_t, const int32_t>> mAnnotations;
|
||||
|
||||
// To guard access to mAllowedLogSources
|
||||
mutable std::mutex mAllowedLogSourcesMutex;
|
||||
|
||||
|
||||
@@ -186,6 +186,12 @@ message ConfigMetricsReport {
|
||||
optional int64 last_report_wall_clock_nanos = 5;
|
||||
|
||||
optional int64 current_report_wall_clock_nanos = 6;
|
||||
|
||||
message Annotation {
|
||||
optional int64 field_int64 = 1;
|
||||
optional int32 field_int32 = 2;
|
||||
}
|
||||
repeated Annotation annotation = 7;
|
||||
}
|
||||
|
||||
message ConfigMetricsReportList {
|
||||
@@ -242,6 +248,11 @@ message StatsdStatsReport {
|
||||
repeated MetricStats metric_stats = 15;
|
||||
repeated AlertStats alert_stats = 16;
|
||||
repeated MetricStats metric_dimension_in_condition_stats = 17;
|
||||
message Annotation {
|
||||
optional int64 field_int64 = 1;
|
||||
optional int32 field_int32 = 2;
|
||||
}
|
||||
repeated Annotation annotation = 18;
|
||||
}
|
||||
|
||||
repeated ConfigStats config_stats = 3;
|
||||
|
||||
@@ -347,4 +347,13 @@ message StatsdConfig {
|
||||
repeated string allowed_log_source = 12;
|
||||
|
||||
repeated int64 no_report_metric = 13;
|
||||
|
||||
message Annotation {
|
||||
optional int64 field_int64 = 1;
|
||||
optional int32 field_int32 = 2;
|
||||
}
|
||||
repeated Annotation annotation = 14;
|
||||
|
||||
// Field number 1000 is reserved for later use.
|
||||
reserved 1000;
|
||||
}
|
||||
|
||||
@@ -149,6 +149,35 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) {
|
||||
EXPECT_EQ(2, uidmap.snapshots(0).package_info_size());
|
||||
}
|
||||
|
||||
TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) {
|
||||
// Setup simple config key corresponding to empty config.
|
||||
sp<UidMap> m = new UidMap();
|
||||
sp<AlarmMonitor> anomalyAlarmMonitor;
|
||||
sp<AlarmMonitor> subscriberAlarmMonitor;
|
||||
int broadcastCount = 0;
|
||||
StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
|
||||
[&broadcastCount](const ConfigKey& key) { broadcastCount++; });
|
||||
ConfigKey key(3, 4);
|
||||
StatsdConfig config;
|
||||
auto annotation = config.add_annotation();
|
||||
annotation->set_field_int64(1);
|
||||
annotation->set_field_int32(2);
|
||||
config.add_allowed_log_source("AID_ROOT");
|
||||
p.OnConfigUpdated(1, key, config);
|
||||
|
||||
// Expect to get no metrics, but snapshot specified above in uidmap.
|
||||
vector<uint8_t> bytes;
|
||||
p.onDumpReport(key, 1, &bytes);
|
||||
|
||||
ConfigMetricsReportList output;
|
||||
output.ParseFromArray(bytes.data(), bytes.size());
|
||||
EXPECT_TRUE(output.reports_size() > 0);
|
||||
auto report = output.reports(0);
|
||||
EXPECT_EQ(1, report.annotation_size());
|
||||
EXPECT_EQ(1, report.annotation(0).field_int64());
|
||||
EXPECT_EQ(2, report.annotation(0).field_int32());
|
||||
}
|
||||
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,7 @@ TEST(StatsdStatsTest, TestValidConfigAdd) {
|
||||
const int conditionsCount = 20;
|
||||
const int matchersCount = 30;
|
||||
const int alertsCount = 10;
|
||||
stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount,
|
||||
stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
|
||||
true /*valid config*/);
|
||||
vector<uint8_t> output;
|
||||
stats.dumpStats(&output, false /*reset stats*/);
|
||||
@@ -61,7 +61,7 @@ TEST(StatsdStatsTest, TestInvalidConfigAdd) {
|
||||
const int conditionsCount = 20;
|
||||
const int matchersCount = 30;
|
||||
const int alertsCount = 10;
|
||||
stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount,
|
||||
stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
|
||||
false /*bad config*/);
|
||||
vector<uint8_t> output;
|
||||
stats.dumpStats(&output, false);
|
||||
@@ -82,7 +82,8 @@ TEST(StatsdStatsTest, TestConfigRemove) {
|
||||
const int conditionsCount = 20;
|
||||
const int matchersCount = 30;
|
||||
const int alertsCount = 10;
|
||||
stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, true);
|
||||
stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
|
||||
true);
|
||||
vector<uint8_t> output;
|
||||
stats.dumpStats(&output, false);
|
||||
StatsdStatsReport report;
|
||||
@@ -104,7 +105,7 @@ TEST(StatsdStatsTest, TestConfigRemove) {
|
||||
TEST(StatsdStatsTest, TestSubStats) {
|
||||
StatsdStats stats;
|
||||
ConfigKey key(0, 12345);
|
||||
stats.noteConfigReceived(key, 2, 3, 4, 5, true);
|
||||
stats.noteConfigReceived(key, 2, 3, 4, 5, {std::make_pair(123, 456)}, true);
|
||||
|
||||
stats.noteMatcherMatched(key, StringToId("matcher1"));
|
||||
stats.noteMatcherMatched(key, StringToId("matcher1"));
|
||||
@@ -142,6 +143,9 @@ TEST(StatsdStatsTest, TestSubStats) {
|
||||
EXPECT_EQ(2, configReport.broadcast_sent_time_sec_size());
|
||||
EXPECT_EQ(1, configReport.data_drop_time_sec_size());
|
||||
EXPECT_EQ(3, configReport.dump_report_time_sec_size());
|
||||
EXPECT_EQ(1, configReport.annotation_size());
|
||||
EXPECT_EQ(123, configReport.annotation(0).field_int64());
|
||||
EXPECT_EQ(456, configReport.annotation(0).field_int32());
|
||||
|
||||
EXPECT_EQ(2, configReport.matcher_stats_size());
|
||||
// matcher1 is the first in the list
|
||||
@@ -259,7 +263,7 @@ TEST(StatsdStatsTest, TestTimestampThreshold) {
|
||||
timestamps.push_back(i);
|
||||
}
|
||||
ConfigKey key(0, 12345);
|
||||
stats.noteConfigReceived(key, 2, 3, 4, 5, true);
|
||||
stats.noteConfigReceived(key, 2, 3, 4, 5, {}, true);
|
||||
|
||||
for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
|
||||
stats.noteDataDropped(key, timestamps[i]);
|
||||
|
||||
Reference in New Issue
Block a user