summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-01-20 02:34:40 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-01-20 02:34:40 +0000
commitf7157470a3244d0125bb6649a8922aa6abd6f4b2 (patch)
tree7b94a658d7cd11c38ed8f72f550f890c7668b7e8
parent18fb2fe4cf1a5b071b27308e0b1fa4f769997761 (diff)
parente4d44919aa90f16285a9966dcc632c128b932374 (diff)
Merge "Statsd -> Perfetto integration"
-rw-r--r--Android.mk1
-rw-r--r--cmds/statsd/Android.mk3
-rw-r--r--cmds/statsd/src/anomaly/AnomalyTracker.cpp3
-rw-r--r--cmds/statsd/src/external/Perfetto.cpp111
-rw-r--r--cmds/statsd/src/external/Perfetto.h35
-rw-r--r--cmds/statsd/src/perfetto/perfetto_config.proto61
-rw-r--r--cmds/statsd/src/statsd_config.proto4
-rw-r--r--cmds/statsd/tools/dogfood/Android.mk2
-rw-r--r--cmds/statsd/tools/loadtest/Android.mk1
9 files changed, 219 insertions, 2 deletions
diff --git a/Android.mk b/Android.mk
index 298b85ddf084..866d2a7b0e54 100644
--- a/Android.mk
+++ b/Android.mk
@@ -781,6 +781,7 @@ LOCAL_PROTOC_FLAGS := \
LOCAL_SOURCE_FILES_ALL_GENERATED := true
LOCAL_SRC_FILES := \
cmds/am/proto/instrumentation_data.proto \
+ cmds/statsd/src/perfetto/perfetto_config.proto \
$(call all-proto-files-under, core/proto) \
$(call all-proto-files-under, libs/incident/proto) \
$(call all-proto-files-under, cmds/statsd/src)
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 5eff54887be1..01f4a84bbb93 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -34,6 +34,7 @@ statsd_common_src := \
src/config/ConfigKey.cpp \
src/config/ConfigListener.cpp \
src/config/ConfigManager.cpp \
+ src/external/Perfetto.cpp \
src/external/StatsPuller.cpp \
src/external/StatsCompanionServicePuller.cpp \
src/external/SubsystemSleepStatePuller.cpp \
@@ -57,6 +58,7 @@ statsd_common_src := \
src/metrics/MetricsManager.cpp \
src/metrics/metrics_manager_util.cpp \
src/packages/UidMap.cpp \
+ src/perfetto/perfetto_config.proto \
src/storage/StorageManager.cpp \
src/StatsLogProcessor.cpp \
src/StatsService.cpp \
@@ -209,6 +211,7 @@ LOCAL_MODULE := statsdprotolite
LOCAL_SRC_FILES := \
src/stats_log.proto \
src/statsd_config.proto \
+ src/perfetto/perfetto_config.proto \
src/atoms.proto
LOCAL_PROTOC_OPTIMIZE_TYPE := lite
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index f10b2cf618cd..9b65acf86604 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -18,6 +18,7 @@
#include "Log.h"
#include "AnomalyTracker.h"
+#include "external/Perfetto.h"
#include "guardrail/StatsdStats.h"
#include <android/os/IIncidentManager.h>
@@ -239,7 +240,7 @@ void AnomalyTracker::informSubscribers(const HashableDimensionKey& key) {
}
break;
case Subscription::SubscriberInformationCase::kPerfettoDetails:
- ALOGW("Perfetto reports not implemented.");
+ CollectPerfettoTraceAndUploadToDropbox(subscription.perfetto_details());
break;
default:
break;
diff --git a/cmds/statsd/src/external/Perfetto.cpp b/cmds/statsd/src/external/Perfetto.cpp
new file mode 100644
index 000000000000..f7b33e77c557
--- /dev/null
+++ b/cmds/statsd/src/external/Perfetto.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include "Log.h"
+
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert
+
+#include <android-base/unique_fd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <string>
+
+namespace {
+const char kDropboxTag[] = "perfetto";
+}
+
+namespace android {
+namespace os {
+namespace statsd {
+
+bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config) {
+ ALOGD("Starting trace collection through perfetto");
+
+ if (!config.has_trace_config()) {
+ ALOGE("The perfetto trace config is empty, aborting");
+ return false;
+ }
+
+ android::base::unique_fd readPipe;
+ android::base::unique_fd writePipe;
+ if (!android::base::Pipe(&readPipe, &writePipe)) {
+ ALOGE("pipe() failed while calling the Perfetto client: %s", strerror(errno));
+ return false;
+ }
+
+ pid_t pid = fork();
+ if (pid < 0) {
+ ALOGE("fork() failed while calling the Perfetto client: %s", strerror(errno));
+ return false;
+ }
+
+ if (pid == 0) {
+ // Child process.
+
+ // No malloc calls or library calls after this point. Remember that even
+ // ALOGx (aka android_printLog()) can use dynamic memory for vsprintf().
+
+ writePipe.reset(); // Close the write end (owned by the main process).
+
+ // Replace stdin with |readPipe| so the main process can write into it.
+ if (dup2(readPipe.get(), STDIN_FILENO) < 0) _exit(1);
+ execl("/system/bin/perfetto", "perfetto", "--background", "--config", "-", "--dropbox",
+ kDropboxTag, nullptr);
+
+ // execl() doesn't return in case of success, if we get here something failed.
+ _exit(1);
+ }
+
+ // Main process.
+
+ readPipe.reset(); // Close the read end (owned by the child process).
+
+ // Using fopen() because fwrite() has the right logic to chunking write()
+ // over a pipe (see __sfvwrite()).
+ FILE* writePipeStream = fdopen(writePipe.get(), "wb");
+ if (!writePipeStream) {
+ ALOGE("fdopen() failed while calling the Perfetto client: %s", strerror(errno));
+ return false;
+ }
+
+ std::string cfgProto = config.trace_config().SerializeAsString();
+ size_t bytesWritten = fwrite(cfgProto.data(), 1, cfgProto.size(), writePipeStream);
+ fclose(writePipeStream);
+ if (bytesWritten != cfgProto.size() || cfgProto.size() == 0) {
+ ALOGE("fwrite() failed (ret: %zd) while calling the Perfetto client: %s", bytesWritten,
+ strerror(errno));
+ return false;
+ }
+
+ // This does NOT wait for the full duration of the trace. It just waits until the process
+ // has read the config from stdin and detached.
+ int childStatus = 0;
+ waitpid(pid, &childStatus, 0);
+ if (!WIFEXITED(childStatus) || WEXITSTATUS(childStatus) != 0) {
+ ALOGE("Child process failed (0x%x) while calling the Perfetto client", childStatus);
+ return false;
+ }
+
+ ALOGD("CollectPerfettoTraceAndUploadToDropbox() succeeded");
+ return true;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/external/Perfetto.h b/cmds/statsd/src/external/Perfetto.h
new file mode 100644
index 000000000000..e2e02533f17f
--- /dev/null
+++ b/cmds/statsd/src/external/Perfetto.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+using android::os::StatsLogEventWrapper;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class PerfettoDetails; // Declared in statsd_config.pb.h
+
+// Starts the collection of a Perfetto trace with the given |config|.
+// The trace is uploaded to Dropbox by the perfetto cmdline util once done.
+// This method returns immediately after passing the config and does NOT wait
+// for the full duration of the trace.
+bool CollectPerfettoTraceAndUploadToDropbox(const PerfettoDetails& config);
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/perfetto/perfetto_config.proto b/cmds/statsd/src/perfetto/perfetto_config.proto
new file mode 100644
index 000000000000..dc868f997a63
--- /dev/null
+++ b/cmds/statsd/src/perfetto/perfetto_config.proto
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+package perfetto.protos;
+
+message DataSourceConfig {
+ message FtraceConfig {
+ repeated string event_names = 1;
+ }
+
+ optional string name = 1;
+
+ optional uint32 target_buffer = 2;
+
+ optional FtraceConfig ftrace_config = 100;
+}
+
+message TraceConfig {
+ message BufferConfig {
+ optional uint32 size_kb = 1;
+
+ enum OptimizeFor {
+ DEFAULT = 0;
+ ONE_SHOT_READ = 1;
+
+ }
+ optional OptimizeFor optimize_for = 3;
+
+ enum FillPolicy {
+ UNSPECIFIED = 0;
+ RING_BUFFER = 1;
+ }
+ optional FillPolicy fill_policy = 4;
+ }
+ repeated BufferConfig buffers = 1;
+
+ message DataSource {
+ optional protos.DataSourceConfig config = 1;
+
+ repeated string producer_name_filter = 2;
+ }
+ repeated DataSource data_sources = 2;
+
+ optional uint32 duration_ms = 3;
+}
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 624785486043..cd60ee74e3ad 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -22,6 +22,8 @@ package android.os.statsd;
option java_package = "com.android.internal.os";
option java_outer_classname = "StatsdConfigProto";
+import "frameworks/base/cmds/statsd/src/perfetto/perfetto_config.proto";
+
enum Position {
POSITION_UNKNOWN = 0;
FIRST = 1;
@@ -272,7 +274,7 @@ message IncidentdDetails {
}
message PerfettoDetails {
- optional int32 perfetto_stuff = 1;
+ optional perfetto.protos.TraceConfig trace_config = 1;
}
message Subscription {
diff --git a/cmds/statsd/tools/dogfood/Android.mk b/cmds/statsd/tools/dogfood/Android.mk
index a4c080063284..73fbaa4e2ad0 100644
--- a/cmds/statsd/tools/dogfood/Android.mk
+++ b/cmds/statsd/tools/dogfood/Android.mk
@@ -21,9 +21,11 @@ LOCAL_PACKAGE_NAME := StatsdDogfood
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += ../../src/stats_log.proto \
../../src/atoms.proto \
+ ../../src/perfetto/perfetto_config.proto \
../../src/statsd_config.proto
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/../../src/
+
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_STATIC_JAVA_LIBRARIES := platformprotoslite
diff --git a/cmds/statsd/tools/loadtest/Android.mk b/cmds/statsd/tools/loadtest/Android.mk
index 0a0fd6647fbb..f5722c2c3d19 100644
--- a/cmds/statsd/tools/loadtest/Android.mk
+++ b/cmds/statsd/tools/loadtest/Android.mk
@@ -21,6 +21,7 @@ LOCAL_PACKAGE_NAME := StatsdLoadtest
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += ../../src/stats_log.proto \
../../src/atoms.proto \
+ ../../src/perfetto/perfetto_config.proto \
../../src/statsd_config.proto
LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/../../src/
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res