Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44cf27c1 authored by Yao Chen's avatar Yao Chen
Browse files

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
parent f2e65f67
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@ LOCAL_SRC_FILES := \
    src/statsd_config.proto \
    src/DropboxReader.cpp \
    src/matchers/LogEntryMatcherManager.cpp \
    src/metrics/CountMetricProducer.cpp \
    src/metrics/ConditionTracker.cpp \
    src/metrics/MetricsManager.cpp \


LOCAL_CFLAGS += \
+3 −2
Original line number Diff line number Diff line
@@ -17,7 +17,8 @@
#ifndef DROPBOX_WRITER_H
#define DROPBOX_WRITER_H

#include <frameworks/base/cmds/statsd/src/stats_log.pb.h>
#include <utils/RefBase.h>
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"

using std::string;

@@ -25,7 +26,7 @@ namespace android {
namespace os {
namespace statsd {

class DropboxWriter {
class DropboxWriter : public virtual RefBase {
public:
    /* tag will be part of the file name, and used as the key to build the file index inside
       DropBoxManagerService.
+47 −25
Original line number Diff line number Diff line
@@ -16,52 +16,74 @@

#include <StatsLogProcessor.h>

#include <cutils/log.h>
#include <frameworks/base/cmds/statsd/src/stats_log.pb.h>
#include <log/log_event_list.h>
#include <metrics/CountMetricProducer.h>
#include <parse_util.h>
#include <utils/Errors.h>

using namespace android;
using std::make_unique;
using std::unique_ptr;
using std::vector;

namespace android {
namespace os {
namespace statsd {

StatsLogProcessor::StatsLogProcessor() : m_dropbox_writer("all-logs") {
    // Initialize the EventTagMap, which is how we know the names of the numeric event tags.
    // If this fails, we can't print well, but something will print.
    m_tags = android_openEventTagMap(NULL);

    // Printing format
    m_format = android_log_format_new();
    android_log_setPrintFormat(m_format, FORMAT_THREADTIME);
    // hardcoded config
    // this should be called from StatsService when it receives a statsd_config
    UpdateConfig(0, buildFakeConfig());
}

StatsLogProcessor::~StatsLogProcessor() {
    if (m_tags != NULL) {
        android_closeEventTagMap(m_tags);
    }
    android_log_format_free(m_format);
}

void StatsLogProcessor::OnLogEvent(const log_msg& msg) {
    status_t err;
    AndroidLogEntry entry;
    char buf[1024];
StatsdConfig StatsLogProcessor::buildFakeConfig() {
    // HACK: Hard code a test metric for counting screen on events...
    StatsdConfig config;
    config.set_config_id(12345L);

    err = android_log_processBinaryLogBuffer(&(const_cast<log_msg*>(&msg)->entry_v1), &entry,
                                             m_tags, buf, sizeof(buf));
    CountMetric* metric = config.add_count_metric();
    metric->set_metric_id(20150717L);
    metric->set_what("SCREEN_IS_ON");
    metric->mutable_bucket()->set_bucket_size_millis(30 * 1000L);

    LogEntryMatcher* eventMatcher = config.add_log_entry_matcher();
    eventMatcher->set_name("SCREEN_IS_ON");

    SimpleLogEntryMatcher* simpleLogEntryMatcher = eventMatcher->mutable_simple_log_entry_matcher();
    simpleLogEntryMatcher->add_tag(2 /*SCREEN_STATE_CHANGE*/);
    simpleLogEntryMatcher->add_key_value_matcher()->mutable_key_matcher()
            ->set_key(1 /*SCREEN_STATE_CHANGE__DISPLAY_STATE*/);
    simpleLogEntryMatcher->mutable_key_value_matcher(0)
            ->set_eq_int(2/*SCREEN_STATE_CHANGE__DISPLAY_STATE__STATE_ON*/);
    return config;
}

    // dump all statsd logs to dropbox for now.
    // TODO: Add filtering, aggregation, etc.
    if (err == NO_ERROR) {
// TODO: what if statsd service restarts? How do we know what logs are already processed before?
void StatsLogProcessor::OnLogEvent(const log_msg& msg) {
    // TODO: Use EventMetric to filter the events we want to log.
    EventMetricData eventMetricData = parse(msg);
    m_dropbox_writer.addEventMetricData(eventMetricData);

    // pass the event to metrics managers.
    for (auto& pair : mMetricsManagers) {
        pair.second->onLogEvent(msg);
    }
}

void StatsLogProcessor::UpdateConfig(const int config_source, StatsdConfig config) {
    m_configs[config_source] = config;
void StatsLogProcessor::UpdateConfig(const int config_source, const StatsdConfig& config) {
    auto it = mMetricsManagers.find(config_source);
    if (it != mMetricsManagers.end()) {
        it->second->finish();
    }

    ALOGD("Updated configuration for source %i", config_source);

    mMetricsManagers.insert({config_source, std::make_unique<MetricsManager>(config)});
}

}  // namespace statsd
+10 −16
Original line number Diff line number Diff line
@@ -17,8 +17,13 @@
#define STATS_LOG_PROCESSOR_H

#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "DropboxWriter.h"
#include "LogReader.h"
#include "metrics/MetricsManager.h"
#include "parse_util.h"

#include <log/logprint.h>
#include <stdio.h>
#include <unordered_map>

namespace android {
@@ -32,26 +37,15 @@ public:

    virtual void OnLogEvent(const log_msg& msg);

    virtual void UpdateConfig(const int config_source, StatsdConfig config);
    void UpdateConfig(const int config_source, const StatsdConfig& config);

private:
    /**
     * Numeric to string tag name mapping.
     */
    EventTagMap* m_tags;

    /**
     * Pretty printing format.
     */
    AndroidLogFormat* m_format;

    // TODO: use EventMetrics to log the events.
    DropboxWriter m_dropbox_writer;

    /**
     * Configs that have been specified, keyed by the source. This allows us to override the config
     * from a source later.
     */
    std::unordered_map<int, StatsdConfig> m_configs;
    std::unordered_map<int, std::unique_ptr<MetricsManager>> mMetricsManagers;

    static StatsdConfig buildFakeConfig();
};

}  // namespace statsd
+0 −1
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@
#include <android/os/IStatsCompanionService.h>
#include <binder/IResultReceiver.h>
#include <binder/IShellCallback.h>
#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
#include <utils/Looper.h>

#include <deque>
Loading