trace_processor: add initial support for running metrics using shell
Context: go/perfetto-metrics
Bug: 129747127
Change-Id: Id07ddae420f00b376085142fd3b08e44467a0acb
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index ce8c481..d868d29 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -22,13 +22,16 @@
#include <functional>
#include <iostream>
+#include <vector>
#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/scoped_file.h"
+#include "perfetto/base/string_splitter.h"
#include "perfetto/base/time.h"
#include "perfetto/trace_processor/trace_processor.h"
+#include "perfetto/metrics/metrics.pb.h"
#include "perfetto/trace_processor/raw_query.pb.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
@@ -200,6 +203,15 @@
return 0;
}
+int RunMetrics(const std::vector<std::string>& metric_names) {
+ protos::TraceMetrics metrics_proto;
+ for (const auto& metric : metric_names) {
+ perfetto::base::ignore_result(metric);
+ }
+ perfetto::base::ignore_result(metrics_proto);
+ return 0;
+}
+
void PrintQueryResultInteractively(base::TimeNanos t_start,
const protos::RawQueryResult& res) {
if (res.has_error()) {
@@ -417,11 +429,13 @@
"Interactive trace processor shell.\n"
"Usage: %s [OPTIONS] trace_file.pb\n\n"
"Options:\n"
- " -d Enable virtual table debugging.\n"
- " -s FILE Read and execute contents of file before launching an "
- "interactive shell.\n"
- " -q FILE Read and execute an SQL query from a file.\n"
- " -e FILE Export the trace into a SQLite database.\n",
+ " -d Enable virtual table debugging.\n"
+ " -s FILE Read and execute contents of file before "
+ "launching an interactive shell.\n"
+ " -q FILE Read and execute an SQL query from a file.\n"
+ " -e FILE Export the trace into a SQLite database.\n"
+ " --run-metrics x,y,z Runs a comma separated list of metrics and "
+ "prints the result as a TraceMetrics proto to stdout.\n",
argv[0]);
}
@@ -433,6 +447,7 @@
const char* trace_file_path = nullptr;
const char* query_file_path = nullptr;
const char* sqlite_file_path = nullptr;
+ const char* metric_names = nullptr;
bool launch_shell = true;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
@@ -458,6 +473,13 @@
}
sqlite_file_path = argv[i];
continue;
+ } else if (strcmp(argv[i], "--run-metrics") == 0) {
+ if (++i == argc) {
+ PrintUsage(argv);
+ return 1;
+ }
+ metric_names = argv[i];
+ continue;
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
PrintUsage(argv);
return 0;
@@ -532,6 +554,16 @@
signal(SIGINT, [](int) { g_tp->InterruptQuery(); });
#endif
+ // First, see if we have some metrics to run. If we do, just run them and
+ // return.
+ if (metric_names) {
+ std::vector<std::string> metrics;
+ for (base::StringSplitter ss(metric_names, ','); ss.Next();) {
+ metrics.emplace_back(ss.cur_token());
+ }
+ return RunMetrics(std::move(metrics));
+ }
+
// If we were given a query file, load contents
std::vector<std::string> queries;
if (query_file_path) {