xref: /aosp_15_r20/external/perfetto/examples/sdk/example_startup_trace.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2022 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 // This example demonstrates startup tracing with a custom data source.
18*6dbdd20aSAndroid Build Coastguard Worker // Startup tracing can work only with kSystemBackend. Before running
19*6dbdd20aSAndroid Build Coastguard Worker // this example, `traced` must already be running in a separate process.
20*6dbdd20aSAndroid Build Coastguard Worker 
21*6dbdd20aSAndroid Build Coastguard Worker // Run system tracing: ninja -C out/default/ traced && ./out/default/traced
22*6dbdd20aSAndroid Build Coastguard Worker // And then run this example: ninja -C out/default example_startup_trace &&
23*6dbdd20aSAndroid Build Coastguard Worker //                            ./out/default/example_startup_trace
24*6dbdd20aSAndroid Build Coastguard Worker 
25*6dbdd20aSAndroid Build Coastguard Worker #if defined(PERFETTO_SDK_EXAMPLE_USE_INTERNAL_HEADERS)
26*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/data_source_descriptor.h"
28*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/trace_config.h"
29*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/data_source.h"
30*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/tracing.h"
31*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/test_event.pbzero.h"
32*6dbdd20aSAndroid Build Coastguard Worker #else
33*6dbdd20aSAndroid Build Coastguard Worker #include <perfetto.h>
34*6dbdd20aSAndroid Build Coastguard Worker #endif
35*6dbdd20aSAndroid Build Coastguard Worker 
36*6dbdd20aSAndroid Build Coastguard Worker #include <fstream>
37*6dbdd20aSAndroid Build Coastguard Worker #include <iostream>
38*6dbdd20aSAndroid Build Coastguard Worker #include <thread>
39*6dbdd20aSAndroid Build Coastguard Worker 
40*6dbdd20aSAndroid Build Coastguard Worker namespace {
41*6dbdd20aSAndroid Build Coastguard Worker 
42*6dbdd20aSAndroid Build Coastguard Worker // The definition of our custom data source. Instances of this class will be
43*6dbdd20aSAndroid Build Coastguard Worker // automatically created and destroyed by Perfetto.
44*6dbdd20aSAndroid Build Coastguard Worker class CustomDataSource : public perfetto::DataSource<CustomDataSource> {};
45*6dbdd20aSAndroid Build Coastguard Worker 
InitializePerfetto()46*6dbdd20aSAndroid Build Coastguard Worker void InitializePerfetto() {
47*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TracingInitArgs args;
48*6dbdd20aSAndroid Build Coastguard Worker   // The backends determine where trace events are recorded. For this example we
49*6dbdd20aSAndroid Build Coastguard Worker   // are going to use the system-wide tracing service, because the in-process
50*6dbdd20aSAndroid Build Coastguard Worker   // backend doesn't support startup tracing.
51*6dbdd20aSAndroid Build Coastguard Worker   args.backends = perfetto::kSystemBackend;
52*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::Initialize(args);
53*6dbdd20aSAndroid Build Coastguard Worker 
54*6dbdd20aSAndroid Build Coastguard Worker   // Register our custom data source. Only the name is required, but other
55*6dbdd20aSAndroid Build Coastguard Worker   // properties can be advertised too.
56*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
57*6dbdd20aSAndroid Build Coastguard Worker   dsd.set_name("com.example.startup_trace");
58*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Register(dsd);
59*6dbdd20aSAndroid Build Coastguard Worker }
60*6dbdd20aSAndroid Build Coastguard Worker 
61*6dbdd20aSAndroid Build Coastguard Worker // The trace config defines which types of data sources are enabled for
62*6dbdd20aSAndroid Build Coastguard Worker // recording.
GetTraceConfig()63*6dbdd20aSAndroid Build Coastguard Worker perfetto::TraceConfig GetTraceConfig() {
64*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
65*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
66*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
67*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("com.example.startup_trace");
68*6dbdd20aSAndroid Build Coastguard Worker   return cfg;
69*6dbdd20aSAndroid Build Coastguard Worker }
70*6dbdd20aSAndroid Build Coastguard Worker 
StartStartupTracing()71*6dbdd20aSAndroid Build Coastguard Worker void StartStartupTracing() {
72*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::SetupStartupTracingOpts args;
73*6dbdd20aSAndroid Build Coastguard Worker   args.backend = perfetto::kSystemBackend;
74*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::SetupStartupTracingBlocking(GetTraceConfig(), args);
75*6dbdd20aSAndroid Build Coastguard Worker }
76*6dbdd20aSAndroid Build Coastguard Worker 
StartTracing()77*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<perfetto::TracingSession> StartTracing() {
78*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session = perfetto::Tracing::NewTrace();
79*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->Setup(GetTraceConfig());
80*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->StartBlocking();
81*6dbdd20aSAndroid Build Coastguard Worker   return tracing_session;
82*6dbdd20aSAndroid Build Coastguard Worker }
83*6dbdd20aSAndroid Build Coastguard Worker 
StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session)84*6dbdd20aSAndroid Build Coastguard Worker void StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session) {
85*6dbdd20aSAndroid Build Coastguard Worker   // Flush to make sure the last written event ends up in the trace.
86*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace(
87*6dbdd20aSAndroid Build Coastguard Worker       [](CustomDataSource::TraceContext ctx) { ctx.Flush(); });
88*6dbdd20aSAndroid Build Coastguard Worker 
89*6dbdd20aSAndroid Build Coastguard Worker   // Stop tracing and read the trace data.
90*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->StopBlocking();
91*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> trace_data(tracing_session->ReadTraceBlocking());
92*6dbdd20aSAndroid Build Coastguard Worker 
93*6dbdd20aSAndroid Build Coastguard Worker   // Write the result into a file.
94*6dbdd20aSAndroid Build Coastguard Worker   // Note: To save memory with longer traces, you can tell Perfetto to write
95*6dbdd20aSAndroid Build Coastguard Worker   // directly into a file by passing a file descriptor into Setup() above.
96*6dbdd20aSAndroid Build Coastguard Worker   std::ofstream output;
97*6dbdd20aSAndroid Build Coastguard Worker   const char* filename = "example_startup_trace.pftrace";
98*6dbdd20aSAndroid Build Coastguard Worker   output.open(filename, std::ios::out | std::ios::binary);
99*6dbdd20aSAndroid Build Coastguard Worker   output.write(trace_data.data(),
100*6dbdd20aSAndroid Build Coastguard Worker                static_cast<std::streamsize>(trace_data.size()));
101*6dbdd20aSAndroid Build Coastguard Worker   output.close();
102*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_LOG(
103*6dbdd20aSAndroid Build Coastguard Worker       "Trace written in %s file. To read this trace in "
104*6dbdd20aSAndroid Build Coastguard Worker       "text form, run `./tools/traceconv text %s`",
105*6dbdd20aSAndroid Build Coastguard Worker       filename, filename);
106*6dbdd20aSAndroid Build Coastguard Worker }
107*6dbdd20aSAndroid Build Coastguard Worker 
108*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
109*6dbdd20aSAndroid Build Coastguard Worker 
110*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
111*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
112*6dbdd20aSAndroid Build Coastguard Worker 
main(int,const char **)113*6dbdd20aSAndroid Build Coastguard Worker int main(int, const char**) {
114*6dbdd20aSAndroid Build Coastguard Worker   InitializePerfetto();
115*6dbdd20aSAndroid Build Coastguard Worker 
116*6dbdd20aSAndroid Build Coastguard Worker   StartStartupTracing();
117*6dbdd20aSAndroid Build Coastguard Worker 
118*6dbdd20aSAndroid Build Coastguard Worker   // Write an event using our custom data source before starting tracing
119*6dbdd20aSAndroid Build Coastguard Worker   // session.
120*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
121*6dbdd20aSAndroid Build Coastguard Worker     auto packet = ctx.NewTracePacket();
122*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp(41);
123*6dbdd20aSAndroid Build Coastguard Worker     packet->set_for_testing()->set_str("Startup Event");
124*6dbdd20aSAndroid Build Coastguard Worker   });
125*6dbdd20aSAndroid Build Coastguard Worker 
126*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session = StartTracing();
127*6dbdd20aSAndroid Build Coastguard Worker 
128*6dbdd20aSAndroid Build Coastguard Worker   // Write an event using our custom data source.
129*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
130*6dbdd20aSAndroid Build Coastguard Worker     auto packet = ctx.NewTracePacket();
131*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp(42);
132*6dbdd20aSAndroid Build Coastguard Worker     packet->set_for_testing()->set_str("Main Event");
133*6dbdd20aSAndroid Build Coastguard Worker   });
134*6dbdd20aSAndroid Build Coastguard Worker   StopTracing(std::move(tracing_session));
135*6dbdd20aSAndroid Build Coastguard Worker 
136*6dbdd20aSAndroid Build Coastguard Worker   return 0;
137*6dbdd20aSAndroid Build Coastguard Worker }
138