Adding multi layer aggregation in DurationMetric
Newly supported metrics examples:
1) Compute [Total|Max] duration of [an app] holding [ANY] wake lock while [this app] is in
[background] and [screen off], bucket size 30seconds, and slice output by uid.
2) Compute [Total|Max] duration of [ANY app] holding [ANY] wake lock while [this app] is in
[background] and [screen off], bucket size 30 seconds.
+ DurationMetric proto has a "what" which is a SimpleCondition. It defines the atom level start
and stop of the duration timer, and it has its atom dimension. e.g., for wake locks, the atom
dimensions wil be uid and wl name.
+ Now dimension is explicitly specified in SimpleCondition proto instead of inferred from the "link"
+ Added support for "Or" and "Max" through 2 layers of aggregation.
TODO: (1) The way we track slicedCondition in duration metric is not efficient. optimize!
(2) The output dimension should all use int32 instead of KeyMatcher. Fix in a future cl.
Test: Added some unit tests using gmock. Will add more unit tests.
Change-Id: I58a827624f01f9a54fcb80709c4de4ff94a8bc67
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index b000e13..2af17c2 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -124,6 +124,39 @@
return config;
}
+StatsdConfig buildDimensionMetricsWithMultiTags() {
+ StatsdConfig config;
+ config.set_config_id(12345L);
+
+ LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
+ eventMatcher->set_name("BATTERY_VERY_LOW");
+ SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+ simpleLogEntryMatcher->set_tag(2);
+
+ eventMatcher = config.add_log_entry_matcher();
+ eventMatcher->set_name("BATTERY_VERY_VERY_LOW");
+ simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
+ simpleLogEntryMatcher->set_tag(3);
+
+ eventMatcher = config.add_log_entry_matcher();
+ eventMatcher->set_name("BATTERY_LOW");
+
+ LogEntryMatcher_Combination* combination = eventMatcher->mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+ combination->add_matcher("BATTERY_VERY_LOW");
+ combination->add_matcher("BATTERY_VERY_VERY_LOW");
+
+ // Count process state changes, slice by uid, while SCREEN_IS_OFF
+ CountMetric* metric = config.add_count_metric();
+ metric->set_metric_id(3);
+ metric->set_what("BATTERY_LOW");
+ metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);
+ KeyMatcher* keyMatcher = metric->add_dimension();
+ keyMatcher->set_key(1);
+
+ return config;
+}
+
StatsdConfig buildCircleConditions() {
StatsdConfig config;
config.set_config_id(12345L);
@@ -180,6 +213,21 @@
trackerToConditionMap));
}
+TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
+ StatsdConfig config = buildDimensionMetricsWithMultiTags();
+ set<int> allTagIds;
+ vector<sp<LogMatchingTracker>> allLogEntryMatchers;
+ vector<sp<ConditionTracker>> allConditionTrackers;
+ vector<sp<MetricProducer>> allMetricProducers;
+ unordered_map<int, std::vector<int>> conditionToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToMetricMap;
+ unordered_map<int, std::vector<int>> trackerToConditionMap;
+
+ EXPECT_FALSE(initStatsdConfig(config, allTagIds, allLogEntryMatchers, allConditionTrackers,
+ allMetricProducers, conditionToMetricMap, trackerToMetricMap,
+ trackerToConditionMap));
+}
+
TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
StatsdConfig config = buildCircleMatchers();
set<int> allTagIds;