1/ Support nested message and repeated fields in statsd.
2/ Filter gauge fields by FieldMatcher.
3/ Wire up wakelock attribution chain.
4/ e2e test: wakelock duration metric with aggregated predicate dimensions.
5/ e2e test: count metric with multiple metric condition links for 2 predicates and 1 non-sliced predicate.
Test: statsd unit test passed.
Change-Id: I89db31cb068184a54e0a892fad710966d3127bc9
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 9031ed0..5bf3cff 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -20,6 +20,7 @@
#include "CountMetricProducer.h"
#include "guardrail/StatsdStats.h"
#include "stats_util.h"
+#include "stats_log_util.h"
#include <limits.h>
#include <stdlib.h>
@@ -51,12 +52,6 @@
// for CountMetricData
const int FIELD_ID_DIMENSION = 1;
const int FIELD_ID_BUCKET_INFO = 2;
-// for KeyValuePair
-const int FIELD_ID_KEY = 1;
-const int FIELD_ID_VALUE_STR = 2;
-const int FIELD_ID_VALUE_INT = 3;
-const int FIELD_ID_VALUE_BOOL = 4;
-const int FIELD_ID_VALUE_FLOAT = 5;
// for CountBucketInfo
const int FIELD_ID_START_BUCKET_NANOS = 1;
const int FIELD_ID_END_BUCKET_NANOS = 2;
@@ -75,7 +70,7 @@
}
// TODO: use UidMap if uid->pkg_name is required
- mDimension.insert(mDimension.begin(), metric.dimension().begin(), metric.dimension().end());
+ mDimensions = metric.dimensions();
if (metric.links().size() > 0) {
mConditionLinks.insert(mConditionLinks.begin(), metric.links().begin(),
@@ -95,6 +90,24 @@
VLOG("Metric %s onSlicedConditionMayChange", mName.c_str());
}
+void CountMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) {
+ flushIfNeededLocked(dumpTimeNs);
+ report->set_metric_name(mName);
+ report->set_start_report_nanos(mStartTimeNs);
+
+ auto count_metrics = report->mutable_count_metrics();
+ for (const auto& counter : mPastBuckets) {
+ CountMetricData* metricData = count_metrics->add_data();
+ *metricData->mutable_dimension() = counter.first.getDimensionsValue();
+ for (const auto& bucket : counter.second) {
+ CountBucketInfo* bucketInfo = metricData->add_bucket_info();
+ bucketInfo->set_start_bucket_nanos(bucket.mBucketStartNs);
+ bucketInfo->set_end_bucket_nanos(bucket.mBucketEndNs);
+ bucketInfo->set_count(bucket.mCount);
+ }
+ }
+}
+
void CountMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
flushIfNeededLocked(dumpTimeNs);
@@ -107,28 +120,16 @@
for (const auto& counter : mPastBuckets) {
const HashableDimensionKey& hashableKey = counter.first;
- const vector<KeyValuePair>& kvs = hashableKey.getKeyValuePairs();
VLOG(" dimension key %s", hashableKey.c_str());
long long wrapperToken =
protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
- // First fill dimension (KeyValuePairs).
- for (const auto& kv : kvs) {
- long long dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DIMENSION);
- protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_KEY, kv.key());
- if (kv.has_value_str()) {
- protoOutput->write(FIELD_TYPE_STRING | FIELD_ID_VALUE_STR, kv.value_str());
- } else if (kv.has_value_int()) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_INT, kv.value_int());
- } else if (kv.has_value_bool()) {
- protoOutput->write(FIELD_TYPE_BOOL | FIELD_ID_VALUE_BOOL, kv.value_bool());
- } else if (kv.has_value_float()) {
- protoOutput->write(FIELD_TYPE_FLOAT | FIELD_ID_VALUE_FLOAT, kv.value_float());
- }
- protoOutput->end(dimensionToken);
- }
+ // First fill dimension.
+ long long dimensionToken = protoOutput->start(
+ FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DIMENSION);
+ writeDimensionsValueProtoToStream(hashableKey.getDimensionsValue(), protoOutput);
+ protoOutput->end(dimensionToken);
// Then fill bucket_info (CountBucketInfo).
for (const auto& bucket : counter.second) {
@@ -183,7 +184,7 @@
void CountMetricProducer::onMatchedLogEventInternalLocked(
const size_t matcherIndex, const HashableDimensionKey& eventKey,
- const map<string, HashableDimensionKey>& conditionKey, bool condition,
+ const ConditionKey& conditionKey, bool condition,
const LogEvent& event) {
uint64_t eventTimeNs = event.GetTimestampNs();