Add metric computation skeleton to statsd.
This cl is to let statsd understand statsd_config, and compute metrics
defined in the config.
+ StatsLogProcessor is given a StatsdConfig (hard coded right now).
We construct a MetricProducer for each of the metric, and the metrics
share Condition and LogEntryMatchers
+ Added the CountMetricProducer type for CountMetric.
We can now count times of SCREEN_ON events given a config.
TODO: 1) conditions are not implemented.
2) slicings are not implemented in CountMetric
3) move the interaction to dropbox to a separate thread
4) decide how the in memory metrics would be used by anomaly detection
Test: manual test.
$ adb shell /system/bin/statsd
$ cat config_file.dat | adb shell cmd stats config
Change-Id: I38f4059c0dc5a827c338131d4a6fa7d4cbe865db
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
new file mode 100644
index 0000000..fbd013e
--- /dev/null
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CountMetric"
+#define DEBUG true // STOPSHIP if true
+#define VLOG(...) \
+ if (DEBUG) ALOGD(__VA_ARGS__);
+
+#include "CountMetricProducer.h"
+#include "parse_util.h"
+
+#include <cutils/log.h>
+#include <limits.h>
+#include <stdlib.h>
+
+using std::unordered_map;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+CountMetricProducer::CountMetricProducer(const CountMetric& metric,
+ const sp<ConditionTracker> condition)
+ : mMetric(metric),
+ mConditionTracker(condition),
+ mStartTime(std::time(nullptr)),
+ mCounter(0),
+ mCurrentBucketStartTime(mStartTime) {
+ // TODO: evaluate initial conditions. and set mConditionMet.
+ if (metric.has_bucket() && metric.bucket().has_bucket_size_millis()) {
+ mBucketSize_sec = metric.bucket().bucket_size_millis() / 1000;
+ } else {
+ mBucketSize_sec = LONG_MAX;
+ }
+
+ VLOG("created. bucket size %lu start_time: %lu", mBucketSize_sec, mStartTime);
+}
+
+CountMetricProducer::CountMetricProducer(const CountMetric& metric)
+ : CountMetricProducer(metric, new ConditionTracker()) {
+}
+
+CountMetricProducer::~CountMetricProducer() {
+ VLOG("~CountMetricProducer() called");
+}
+
+void CountMetricProducer::finish() {
+ // TODO: write the StatsLogReport to dropbox using
+ // DropboxWriter.
+ onDumpReport();
+}
+
+void CountMetricProducer::onDumpReport() {
+ VLOG("dump report now...");
+}
+
+void CountMetricProducer::onMatchedLogEvent(const LogEventWrapper& event) {
+ time_t eventTime = event.timestamp_ns / 1000000000;
+
+ // this is old event, maybe statsd restarted?
+ if (eventTime < mStartTime) {
+ return;
+ }
+
+ if (mConditionTracker->isConditionMet()) {
+ flushCounterIfNeeded(eventTime);
+ mCounter++;
+ }
+}
+
+// When a new matched event comes in, we check if it falls into the current bucket. And flush the
+// counter to the StatsLogReport and adjust the bucket if needed.
+void CountMetricProducer::flushCounterIfNeeded(const time_t& eventTime) {
+ if (mCurrentBucketStartTime + mBucketSize_sec > eventTime) {
+ return;
+ }
+
+ // TODO: add a KeyValuePair to StatsLogReport.
+ ALOGD("CountMetric: dump counter %d", mCounter);
+
+ // reset counter
+ mCounter = 0;
+
+ // adjust the bucket start time
+ mCurrentBucketStartTime =
+ mCurrentBucketStartTime +
+ ((eventTime - mCurrentBucketStartTime) / mBucketSize_sec) * mBucketSize_sec;
+
+ VLOG("new bucket start time: %lu", mCurrentBucketStartTime);
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android