xref: /aosp_15_r20/external/perfetto/src/traceconv/trace_to_json.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "src/traceconv/trace_to_json.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include <stdio.h>
20*6dbdd20aSAndroid Build Coastguard Worker 
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/scoped_file.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_utils.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/temp_file.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/trace_processor/trace_processor.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "src/traceconv/utils.h"
27*6dbdd20aSAndroid Build Coastguard Worker 
28*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
29*6dbdd20aSAndroid Build Coastguard Worker namespace trace_to_text {
30*6dbdd20aSAndroid Build Coastguard Worker 
31*6dbdd20aSAndroid Build Coastguard Worker namespace {
32*6dbdd20aSAndroid Build Coastguard Worker 
33*6dbdd20aSAndroid Build Coastguard Worker const char kTraceHeader[] = R"({
34*6dbdd20aSAndroid Build Coastguard Worker   "traceEvents": [],
35*6dbdd20aSAndroid Build Coastguard Worker )";
36*6dbdd20aSAndroid Build Coastguard Worker 
37*6dbdd20aSAndroid Build Coastguard Worker const char kTraceFooter[] = R"(,
38*6dbdd20aSAndroid Build Coastguard Worker   "controllerTraceDataKey": "systraceController"
39*6dbdd20aSAndroid Build Coastguard Worker })";
40*6dbdd20aSAndroid Build Coastguard Worker 
ExportUserspaceEvents(trace_processor::TraceProcessor * tp,TraceWriter * writer)41*6dbdd20aSAndroid Build Coastguard Worker bool ExportUserspaceEvents(trace_processor::TraceProcessor* tp,
42*6dbdd20aSAndroid Build Coastguard Worker                            TraceWriter* writer) {
43*6dbdd20aSAndroid Build Coastguard Worker   fprintf(stderr, "Converting userspace events%c", kProgressChar);
44*6dbdd20aSAndroid Build Coastguard Worker   fflush(stderr);
45*6dbdd20aSAndroid Build Coastguard Worker 
46*6dbdd20aSAndroid Build Coastguard Worker   // Write userspace trace to a temporary file.
47*6dbdd20aSAndroid Build Coastguard Worker   // TODO(eseckler): Support streaming the result out of TP directly instead.
48*6dbdd20aSAndroid Build Coastguard Worker   auto file = base::TempFile::Create();
49*6dbdd20aSAndroid Build Coastguard Worker   base::StackString<100> query("select export_json(\"%s\")",
50*6dbdd20aSAndroid Build Coastguard Worker                                file.path().c_str());
51*6dbdd20aSAndroid Build Coastguard Worker   auto it = tp->ExecuteQuery(query.ToStdString());
52*6dbdd20aSAndroid Build Coastguard Worker 
53*6dbdd20aSAndroid Build Coastguard Worker   if (!it.Next()) {
54*6dbdd20aSAndroid Build Coastguard Worker     auto status = it.Status();
55*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_CHECK(!status.ok());
56*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_ELOG("Could not convert userspace events: %s", status.c_message());
57*6dbdd20aSAndroid Build Coastguard Worker     return false;
58*6dbdd20aSAndroid Build Coastguard Worker   }
59*6dbdd20aSAndroid Build Coastguard Worker 
60*6dbdd20aSAndroid Build Coastguard Worker   base::ScopedFstream source(fopen(file.path().c_str(), "r"));
61*6dbdd20aSAndroid Build Coastguard Worker   if (!source) {
62*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_ELOG("Could not convert userspace events: Couldn't read file %s",
63*6dbdd20aSAndroid Build Coastguard Worker                   file.path().c_str());
64*6dbdd20aSAndroid Build Coastguard Worker     return false;
65*6dbdd20aSAndroid Build Coastguard Worker   }
66*6dbdd20aSAndroid Build Coastguard Worker 
67*6dbdd20aSAndroid Build Coastguard Worker   char buf[BUFSIZ];
68*6dbdd20aSAndroid Build Coastguard Worker   size_t size;
69*6dbdd20aSAndroid Build Coastguard Worker   while ((size = fread(buf, sizeof(char), BUFSIZ, *source)) > 0) {
70*6dbdd20aSAndroid Build Coastguard Worker     // Skip writing the closing brace since we'll append system trace data.
71*6dbdd20aSAndroid Build Coastguard Worker     if (feof(*source))
72*6dbdd20aSAndroid Build Coastguard Worker       size--;
73*6dbdd20aSAndroid Build Coastguard Worker     writer->Write(buf, size);
74*6dbdd20aSAndroid Build Coastguard Worker   }
75*6dbdd20aSAndroid Build Coastguard Worker   return true;
76*6dbdd20aSAndroid Build Coastguard Worker }
77*6dbdd20aSAndroid Build Coastguard Worker 
78*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
79*6dbdd20aSAndroid Build Coastguard Worker 
TraceToJson(std::istream * input,std::ostream * output,bool compress,Keep truncate_keep,bool full_sort)80*6dbdd20aSAndroid Build Coastguard Worker int TraceToJson(std::istream* input,
81*6dbdd20aSAndroid Build Coastguard Worker                 std::ostream* output,
82*6dbdd20aSAndroid Build Coastguard Worker                 bool compress,
83*6dbdd20aSAndroid Build Coastguard Worker                 Keep truncate_keep,
84*6dbdd20aSAndroid Build Coastguard Worker                 bool full_sort) {
85*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<TraceWriter> trace_writer(
86*6dbdd20aSAndroid Build Coastguard Worker       compress ? new DeflateTraceWriter(output) : new TraceWriter(output));
87*6dbdd20aSAndroid Build Coastguard Worker 
88*6dbdd20aSAndroid Build Coastguard Worker   trace_processor::Config config;
89*6dbdd20aSAndroid Build Coastguard Worker   config.sorting_mode = full_sort
90*6dbdd20aSAndroid Build Coastguard Worker                             ? trace_processor::SortingMode::kForceFullSort
91*6dbdd20aSAndroid Build Coastguard Worker                             : trace_processor::SortingMode::kDefaultHeuristics;
92*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<trace_processor::TraceProcessor> tp =
93*6dbdd20aSAndroid Build Coastguard Worker       trace_processor::TraceProcessor::CreateInstance(config);
94*6dbdd20aSAndroid Build Coastguard Worker 
95*6dbdd20aSAndroid Build Coastguard Worker   if (!ReadTraceUnfinalized(tp.get(), input))
96*6dbdd20aSAndroid Build Coastguard Worker     return 1;
97*6dbdd20aSAndroid Build Coastguard Worker   if (auto status = tp->NotifyEndOfFile(); !status.ok()) {
98*6dbdd20aSAndroid Build Coastguard Worker     return 1;
99*6dbdd20aSAndroid Build Coastguard Worker   }
100*6dbdd20aSAndroid Build Coastguard Worker 
101*6dbdd20aSAndroid Build Coastguard Worker   // TODO(eseckler): Support truncation of userspace event data.
102*6dbdd20aSAndroid Build Coastguard Worker   if (ExportUserspaceEvents(tp.get(), trace_writer.get())) {
103*6dbdd20aSAndroid Build Coastguard Worker     trace_writer->Write(",\n");
104*6dbdd20aSAndroid Build Coastguard Worker   } else {
105*6dbdd20aSAndroid Build Coastguard Worker     trace_writer->Write(kTraceHeader);
106*6dbdd20aSAndroid Build Coastguard Worker   }
107*6dbdd20aSAndroid Build Coastguard Worker 
108*6dbdd20aSAndroid Build Coastguard Worker   int ret = ExtractSystrace(tp.get(), trace_writer.get(),
109*6dbdd20aSAndroid Build Coastguard Worker                             /*wrapped_in_json=*/true, truncate_keep);
110*6dbdd20aSAndroid Build Coastguard Worker   if (ret)
111*6dbdd20aSAndroid Build Coastguard Worker     return ret;
112*6dbdd20aSAndroid Build Coastguard Worker 
113*6dbdd20aSAndroid Build Coastguard Worker   trace_writer->Write(kTraceFooter);
114*6dbdd20aSAndroid Build Coastguard Worker   return 0;
115*6dbdd20aSAndroid Build Coastguard Worker }
116*6dbdd20aSAndroid Build Coastguard Worker 
117*6dbdd20aSAndroid Build Coastguard Worker }  // namespace trace_to_text
118*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
119