Improve metatrace, allow to be used in production
Before this CL meta-tracing was based on serializing
events on the fly as JSON and writing them on a file.
This had a number of disadvantages: (1) perf, string
manipulation + write() isn't really nice on fast-paths;
(2) interoperaability: it required an env var and
required loading a separate json file.
This CL improves meta-tracing as follows:
1. Events are stored in a statically allocated
(.rwdata) ring-buffer in a very efficient way
using 16 bytes per event.
2. They are serialized into protos asynchronously.
3. They can be injected into the real trace, exposed
as a data source.
Meta-tracing is organized into three layers:
1. The core base class: it only holds event records in a
ring-buffer and does NOT deal with serialization.
This allows any part of the codebase to use
meta-tracing, even base/ if we'll need it in future.
2. A MetatraceWriter class that is able to write event
records into the trace using a TraceWriter.
3. a MetatraceDataSource: hooks it up to traced-probes.
The split between 2 and 3 is to allow other components
(e.g. Chrome, heapprofd) to take advantage of meta-tracing
outside of traced_probes.
Bug: 133312949
Test: perfetto_unittests --gtest_filter=Metatrace*
Change-Id: Ife1390e599e8c2ca3f4e1039e73398619dbd1af6
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 9e4596c..a8237b5 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -36,6 +36,7 @@
#include "src/traced/probes/filesystem/inode_file_data_source.h"
#include "src/traced/probes/ftrace/ftrace_config.h"
#include "src/traced/probes/ftrace/ftrace_data_source.h"
+#include "src/traced/probes/metatrace/metatrace_data_source.h"
#include "src/traced/probes/packages_list/packages_list_data_source.h"
#include "src/traced/probes/power/android_power_data_source.h"
#include "src/traced/probes/probes_data_source.h"
@@ -129,6 +130,12 @@
desc.set_name(kPackagesListSourceName);
endpoint_->RegisterDataSource(desc);
}
+
+ {
+ DataSourceDescriptor desc;
+ desc.set_name(MetatraceDataSource::kDataSourceName);
+ endpoint_->RegisterDataSource(desc);
+ }
}
void ProbesProducer::OnDisconnect() {
@@ -183,6 +190,8 @@
data_source = CreateAndroidLogDataSource(session_id, config);
} else if (config.name() == kPackagesListSourceName) {
data_source = CreatePackagesListDataSource(session_id, config);
+ } else if (config.name() == MetatraceDataSource::kDataSourceName) {
+ data_source = CreateMetatraceDataSource(session_id, config);
}
if (!data_source) {
@@ -312,6 +321,14 @@
endpoint_->CreateTraceWriter(buffer_id), config));
}
+std::unique_ptr<ProbesDataSource> ProbesProducer::CreateMetatraceDataSource(
+ TracingSessionID session_id,
+ const DataSourceConfig& config) {
+ auto buffer_id = static_cast<BufferID>(config.target_buffer());
+ return std::unique_ptr<ProbesDataSource>(new MetatraceDataSource(
+ task_runner_, session_id, endpoint_->CreateTraceWriter(buffer_id)));
+}
+
void ProbesProducer::StopDataSource(DataSourceInstanceID id) {
PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
auto it = data_sources_.find(id);
@@ -472,6 +489,7 @@
case SysStatsDataSource::kTypeId:
case AndroidLogDataSource::kTypeId:
case PackagesListDataSource::kTypeId:
+ case MetatraceDataSource::kTypeId:
break;
default:
PERFETTO_DFATAL("Invalid data source.");