Revert "Revert "Start auto-generating the stats log API.""
Test: builds successfully
This reverts commit 931945399859ab91545ba2c2a914f044092d5e2e.
Change-Id: I22bca4a32adf86040b9d72ad5b45999aba28f586
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
new file mode 100644
index 0000000..5586057
--- /dev/null
+++ b/cmds/statsd/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2015 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.
+//
+
+// ==========================================================
+// Build the library for use on the host
+// ==========================================================
+cc_library_host_shared {
+ name: "libstats_proto_host",
+ srcs: [
+ "src/stats_events.proto",
+ "src/stats_log.proto",
+ "src/statsd_config.proto",
+ ],
+
+ shared_libs: [
+ "libplatformprotos",
+ ],
+
+ proto: {
+ type: "full",
+ export_proto_headers: true,
+ },
+}
+
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 4c95007..d9c37ef 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -14,22 +14,51 @@
LOCAL_PATH:= $(call my-dir)
-# ================
-# proto static lib
-# ================
-include $(CLEAR_VARS)
-LOCAL_MODULE := statsd_proto
-LOCAL_MODULE_TAGS := optional
+statsd_common_src := \
+ ../../core/java/android/os/IStatsCompanionService.aidl \
+ ../../core/java/android/os/IStatsManager.aidl \
+ src/stats_log.proto \
+ src/statsd_config.proto \
+ src/stats_events.proto \
+ src/condition/CombinationConditionTracker.cpp \
+ src/condition/condition_util.cpp \
+ src/condition/SimpleConditionTracker.cpp \
+ src/matchers/CombinationLogMatchingTracker.cpp \
+ src/matchers/matcher_util.cpp \
+ src/matchers/SimpleLogMatchingTracker.cpp \
+ src/metrics/CountAnomalyTracker.cpp \
+ src/metrics/CountMetricProducer.cpp \
+ src/metrics/MetricsManager.cpp \
+ src/metrics/metrics_manager_util.cpp \
+ src/AnomalyMonitor.cpp \
+ src/DropboxReader.cpp \
+ src/DropboxWriter.cpp \
+ src/KernelWakelockPuller.cpp \
+ src/LogEntryPrinter.cpp \
+ src/LogReader.cpp \
+ src/StatsLogProcessor.cpp \
+ src/StatsPullerManager.cpp \
+ src/StatsService.cpp \
+ src/stats_util.cpp \
+ src/UidMap.cpp
-LOCAL_SRC_FILES := $(call all-proto-files-under, src)
+statsd_common_c_includes := \
+ $(LOCAL_PATH)/src
-LOCAL_PROTOC_FLAGS :=
-LOCAL_PROTOC_OPTIMIZE_TYPE := lite-static
+statsd_common_aidl_includes := \
+ $(LOCAL_PATH)/../../core/java
-include $(BUILD_STATIC_LIBRARY)
-
-STATSD_PROTO_INCLUDES := $(local-generated-sources-dir)/src/$(LOCAL_PATH)
+statsd_common_shared_libraries := \
+ libbase \
+ libbinder \
+ libcutils \
+ libincident \
+ liblog \
+ libselinux \
+ libutils \
+ libservices \
+ libandroidfw
# =========
# statsd
@@ -40,9 +69,8 @@
LOCAL_MODULE := statsd
LOCAL_SRC_FILES := \
- ../../core/java/android/os/IStatsCompanionService.aidl \
- ../../core/java/android/os/IStatsManager.aidl \
- $(call all-cpp-files-under,src) \
+ $(statsd_common_src) \
+ src/main.cpp
LOCAL_CFLAGS += \
-Wall \
@@ -60,24 +88,12 @@
LOCAL_CFLAGS += \
-Os
endif
+LOCAL_PROTOC_OPTIMIZE_TYPE := lite-static
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/../../core/java
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src \
- STATSD_PROTO_INCLUDES
+LOCAL_AIDL_INCLUDES := $(statsd_common_c_includes)
+LOCAL_C_INCLUDES += $(statsd_common_c_includes)
-LOCAL_STATIC_LIBRARIES := statsd_proto
-
-LOCAL_SHARED_LIBRARIES := \
- libbase \
- libbinder \
- libcutils \
- libincident \
- liblog \
- libselinux \
- libutils \
- libservices \
- libandroidfw \
- libprotobuf-cpp-lite \
+LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries)
LOCAL_MODULE_CLASS := EXECUTABLES
@@ -85,6 +101,7 @@
include $(BUILD_EXECUTABLE)
+
# ==============
# statsd_test
# ==============
@@ -95,8 +112,8 @@
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src \
- STATSD_PROTO_INCLUDES
+LOCAL_AIDL_INCLUDES := $(statsd_common_c_includes)
+LOCAL_C_INCLUDES += $(statsd_common_c_includes)
LOCAL_CFLAGS += \
-Wall \
@@ -107,38 +124,25 @@
-Wno-unused-parameter
LOCAL_SRC_FILES := \
- src/stats_log.proto \
- src/statsd_config.proto \
- ../../core/java/android/os/IStatsCompanionService.aidl \
- ../../core/java/android/os/IStatsManager.aidl \
- src/StatsService.cpp \
- src/AnomalyMonitor.cpp \
- src/stats_util.cpp \
- src/LogEntryPrinter.cpp \
- src/LogReader.cpp \
- src/matchers/matcher_util.cpp \
- src/condition/SimpleConditionTracker.cpp \
- src/condition/CombinationConditionTracker.cpp \
- src/matchers/SimpleLogMatchingTracker.cpp \
- src/matchers/CombinationLogMatchingTracker.cpp \
- src/metrics/metrics_manager_util.cpp \
- src/metrics/CountMetricProducer.cpp \
- src/metrics/CountAnomalyTracker.cpp \
- src/condition/condition_util.cpp \
- src/UidMap.cpp \
- $(call all-cpp-files-under, tests) \
+ $(statsd_common_src) \
+ tests/indexed_priority_queue_test.cpp \
+ tests/LogReader_test.cpp \
+ tests/MetricsManager_test.cpp \
+ tests/UidMap_test.cpp \
+ tests/LogEntryMatcher_test.cpp \
+ tests/AnomalyMonitor_test.cpp \
+ tests/ConditionTracker_test.cpp
LOCAL_STATIC_LIBRARIES := \
- libgmock \
- statsd_proto \
+ libgmock
-LOCAL_SHARED_LIBRARIES := \
- libbase \
- libbinder \
- libcutils \
- liblog \
- libselinux \
- libutils \
- libprotobuf-cpp-lite \
+LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries)
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := lite
+
+statsd_common_src:=
+statsd_common_aidl_includes:=
+statsd_common_c_includes:=
include $(BUILD_NATIVE_TEST)
+
diff --git a/cmds/statsd/src/LogEntryPrinter.cpp b/cmds/statsd/src/LogEntryPrinter.cpp
index 63465b0..3b6f679 100644
--- a/cmds/statsd/src/LogEntryPrinter.cpp
+++ b/cmds/statsd/src/LogEntryPrinter.cpp
@@ -20,6 +20,11 @@
#include <log/logprint.h>
#include <utils/Errors.h>
+#include "matchers/matcher_util.h"
+
+#define PRINT_WITH_LIBLOG 0
+#define PRINT_WITH_LOG_EVENT_WRAPPER 1
+
using namespace android;
namespace android {
@@ -44,16 +49,24 @@
}
void LogEntryPrinter::OnLogEvent(const log_msg& msg) {
- status_t err;
- AndroidLogEntry entry;
- char buf[1024];
+ if (PRINT_WITH_LIBLOG) {
+ status_t err;
+ AndroidLogEntry entry;
+ char buf[1024];
- err = android_log_processBinaryLogBuffer(&(const_cast<log_msg*>(&msg)->entry_v1), &entry,
- m_tags, buf, sizeof(buf));
- if (err == NO_ERROR) {
- android_log_printLogLine(m_format, m_out, &entry);
- } else {
- printf("log entry: %s\n", buf);
+ err = android_log_processBinaryLogBuffer(&(const_cast<log_msg*>(&msg)->entry_v1), &entry,
+ m_tags, buf, sizeof(buf));
+ if (err == NO_ERROR) {
+ android_log_printLogLine(m_format, m_out, &entry);
+ } else {
+ printf("log entry: %s\n", buf);
+ fflush(stdout);
+ }
+ }
+
+ if (PRINT_WITH_LOG_EVENT_WRAPPER) {
+ LogEventWrapper event = parseLogEvent(msg);
+ printf("event: %s\n", event.toString().c_str());
fflush(stdout);
}
}
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index 557c032..3308f3a 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -26,8 +26,11 @@
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "stats_util.h"
+#include <sstream>
+
using std::set;
using std::string;
+using std::ostringstream;
using std::unordered_map;
using std::vector;
@@ -35,6 +38,42 @@
namespace os {
namespace statsd {
+string LogEventWrapper::toString() const {
+ std::ostringstream result;
+ result << "{ " << timestamp_ns << " (" << tagId << ")";
+ for (int index = 1; ; index++) {
+ auto intVal = intMap.find(index);
+ auto strVal = strMap.find(index);
+ auto boolVal = boolMap.find(index);
+ auto floatVal = floatMap.find(index);
+ if (intVal != intMap.end()) {
+ result << " ";
+ result << std::to_string(index);
+ result << "->";
+ result << std::to_string(intVal->second);
+ } else if (strVal != strMap.end()) {
+ result << " ";
+ result << std::to_string(index);
+ result << "->";
+ result << strVal->second;
+ } else if (boolVal != boolMap.end()) {
+ result << " ";
+ result << std::to_string(index);
+ result << "->";
+ result << std::to_string(boolVal->second);
+ } else if (floatVal != floatMap.end()) {
+ result << " ";
+ result << std::to_string(index);
+ result << "->";
+ result << std::to_string(floatVal->second);
+ } else {
+ break;
+ }
+ }
+ result << " }";
+ return result.str();
+}
+
LogEventWrapper parseLogEvent(log_msg msg) {
LogEventWrapper wrapper;
wrapper.timestamp_ns = msg.entry_v1.sec * NS_PER_SEC + msg.entry_v1.nsec;
@@ -48,38 +87,32 @@
if (context) {
memset(&elem, 0, sizeof(elem));
- size_t index = 0;
- int32_t key = -1;
+ // TODO: The log is actually structured inside one list. This is convenient
+ // because we'll be able to use it to put the attribution (WorkSource) block first
+ // without doing our own tagging scheme. Until that change is in, just drop the
+ // list-related log elements and the order we get there is our index-keyed data
+ // structure.
+ int32_t key = 1;
do {
elem = android_log_read_next(context);
switch ((int)elem.type) {
case EVENT_TYPE_INT:
- if (index % 2 == 0) {
- key = elem.data.int32;
- } else {
- wrapper.intMap[key] = elem.data.int32;
- }
- index++;
+ wrapper.intMap[key] = elem.data.int32;
+ key++;
break;
case EVENT_TYPE_FLOAT:
- if (index % 2 == 1) {
- wrapper.floatMap[key] = elem.data.float32;
- }
- index++;
+ wrapper.floatMap[key] = elem.data.float32;
+ key++;
break;
case EVENT_TYPE_STRING:
- if (index % 2 == 1) {
- // without explicit calling string() constructor, there will be an
- // additional 0 in the end of the string.
- wrapper.strMap[key] = string(elem.data.string);
- }
- index++;
+ // without explicit calling string() constructor, there will be an
+ // additional 0 in the end of the string.
+ wrapper.strMap[key] = string(elem.data.string);
+ key++;
break;
case EVENT_TYPE_LONG:
- if (index % 2 == 1) {
- wrapper.intMap[key] = elem.data.int64;
- }
- index++;
+ wrapper.intMap[key] = elem.data.int64;
+ key++;
break;
case EVENT_TYPE_LIST:
break;
@@ -91,10 +124,6 @@
elem.complete = true;
break;
}
-
- if (elem.complete) {
- break;
- }
} while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
android_log_destroy(&context);
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
index 6d8e762..ac17bbe 100644
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -20,6 +20,7 @@
#include <log/log_read.h>
#include <log/logprint.h>
#include <set>
+#include <string>
#include <unordered_map>
#include <vector>
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
@@ -36,6 +37,8 @@
std::unordered_map<int, std::string> strMap;
std::unordered_map<int, bool> boolMap;
std::unordered_map<int, float> floatMap;
+
+ std::string toString() const;
} LogEventWrapper;
enum MatchingState {
diff --git a/cmds/statsd/src/stats_events.proto b/cmds/statsd/src/stats_events.proto
index 1e17895..cd00ba8 100644
--- a/cmds/statsd/src/stats_events.proto
+++ b/cmds/statsd/src/stats_events.proto
@@ -15,49 +15,116 @@
*/
syntax = "proto2";
-option optimize_for = LITE_RUNTIME;
+// TODO: Not the right package and class name
package android.os.statsd;
-
option java_package = "com.android.os";
option java_outer_classname = "StatsEventProto";
+/**
+ * The master event class. This message defines all of the available
+ * raw stats log events from the Android system, also known as "atoms."
+ *
+ * This field contains a single oneof with all of the available messages.
+ * The stats-log-api-gen tool runs as part of the Android build and
+ * generates the android.util.StatsLog class, which contains the constants
+ * and methods that Android uses to log.
+ *
+ * This StatsEvent class is not actually built into the Android system.
+ * Instead, statsd on Android constructs these messages synthetically,
+ * in the format defined here and in stats_log.proto.
+ */
message StatsEvent {
- oneof event {
- // Screen state change.
- ScreenStateChange screen_state_change = 2;
- // Process state change.
- ProcessStateChange process_state_change = 1112;
- }
+ oneof event {
+ ScreenStateChanged screen_state_changed = 1;
+ ProcessStateChanged process_state_changed = 2;
+ WakeLockChanged wakelock_changed = 3;
+ }
}
-// Logs changes in screen state. This event is logged in
-// frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
-message ScreenStateChange {
- // Screen state enums follow the values defined in below file.
- // frameworks/base/core/java/android/view/Display.java
- enum State {
- STATE_UNKNOWN = 0;
- STATE_OFF = 1;
- STATE_ON = 2;
- STATE_DOZE = 3;
- STATE_DOZE_SUSPEND = 4;
- STATE_VR = 5;
- }
- // New screen state.
- optional State display_state = 1;
+/**
+ * A WorkSource represents the chained attribution of applications that
+ * resulted in a particular bit of work being done.
+ */
+message WorkSource {
+ // TODO
}
-// Logs changes in process state. This event is logged in
-// frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
-message ProcessStateChange {
- // Type of process event.
- enum State {
- START = 1;
- CRASH = 2;
- }
- optional State state = 1;
+/*
+ * *****************************************************************************
+ * Below are all of the individual atoms that are logged by Android via statsd
+ * and Westworld.
+ *
+ * RULES:
+ * - The field ids for each atom must start at 1, and count upwards by 1.
+ * Skipping field ids is not allowed.
+ * - These form an API, so renaming, renumbering or removing fields is
+ * not allowed between android releases. (This is not currently enforced,
+ * but there will be a tool to enforce this restriction).
+ * - The types must be built-in protocol buffer types, namely, no sub-messages
+ * are allowed (yet). The bytes type is also not allowed.
+ * - The CamelCase name of the message type should match the
+ * underscore_separated name as defined in StatsEvent.
+ * - If an atom represents work that can be attributed to an app, there can
+ * be exactly one WorkSource field. It must be field number 1.
+ * - A field that is a uid should be a string field, tagged with the [xxx]
+ * annotation. The generated code on android will be represented by UIDs,
+ * and those UIDs will be translated in xxx to those strings.
+ *
+ * CONVENTIONS:
+ * - Events are past tense. e.g. ScreenStateChanged, not ScreenStateChange
+ * - If there is a UID, it goes first. Think in an object-oriented fashion.
+ * *****************************************************************************
+ */
- // UID associated with the package.
- optional int32 uid = 2;
+/**
+ * Logs when the screen state changes.
+ *
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
+ */
+message ScreenStateChanged {
+ // TODO: Use the real screen state.
+ enum State {
+ STATE_UNKNOWN = 0;
+ STATE_OFF = 1;
+ STATE_ON = 2;
+ STATE_DOZE = 3;
+ STATE_DOZE_SUSPEND = 4;
+ STATE_VR = 5;
+ }
+ // New screen state.
+ optional State display_state = 1;
}
+
+/**
+ * Logs that the state of a process state, as per the activity manager has changed.
+ *
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
+ */
+message ProcessStateChanged {
+ // TODO: Use the real (mapped) process states.
+ optional int32 uid = 1; // TODO: should be a string tagged w/ uid annotation
+
+ // The state.
+ optional int32 state = 2;
+}
+
+/**
+ * Logs that the state of a wakelock has changed.
+ *
+ * Logged from:
+ * TODO
+ */
+message WakeLockChanged {
+ // TODO: Add attribution instead of uid.
+ optional int32 uid = 1;
+
+ // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
+ optional string tag = 2;
+
+ // TODO: Use a constant instead of boolean?
+ optional bool state = 3;
+}
+