Merge "Includes annotations with statsd reports." into pi-dev

This commit is contained in:
TreeHugger Robot
2018-04-04 02:50:32 +00:00
committed by Android (Google) Code Review
8 changed files with 113 additions and 13 deletions

View File

@@ -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);

View File

@@ -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.
*/

View File

@@ -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==========================");

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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]);