xref: /aosp_15_r20/external/perfetto/examples/sdk/example_custom_data_source.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // This example demonstrates a custom tracing data source.
18 
19 // This source file can be built in two ways:
20 // 1. As part of the regular GN build, against standard includes.
21 // 2. To test that the amalgmated SDK works, against the perfetto.h source.
22 #if defined(PERFETTO_SDK_EXAMPLE_USE_INTERNAL_HEADERS)
23 #include "perfetto/tracing.h"
24 #include "perfetto/tracing/core/data_source_descriptor.h"
25 #include "perfetto/tracing/core/trace_config.h"
26 #include "perfetto/tracing/data_source.h"
27 #include "perfetto/tracing/tracing.h"
28 #include "protos/perfetto/trace/test_event.pbzero.h"
29 #else
30 #include <perfetto.h>
31 #endif
32 
33 #include <fstream>
34 #include <thread>
35 
36 namespace {
37 
38 // The definition of our custom data source. Instances of this class will be
39 // automatically created and destroyed by Perfetto.
40 class CustomDataSource : public perfetto::DataSource<CustomDataSource> {
41  public:
OnSetup(const SetupArgs &)42   void OnSetup(const SetupArgs&) override {
43     // Use this callback to apply any custom configuration to your data source
44     // based on the TraceConfig in SetupArgs.
45   }
46 
47   // Optional callbacks for tracking the lifecycle of the data source.
OnStart(const StartArgs &)48   void OnStart(const StartArgs&) override {}
OnStop(const StopArgs &)49   void OnStop(const StopArgs&) override {}
50 };
51 
InitializePerfetto()52 void InitializePerfetto() {
53   perfetto::TracingInitArgs args;
54   // The backends determine where trace events are recorded. For this example we
55   // are going to use the in-process tracing service, which only includes in-app
56   // events.
57   args.backends = perfetto::kInProcessBackend;
58   perfetto::Tracing::Initialize(args);
59 
60   // Register our custom data source. Only the name is required, but other
61   // properties can be advertised too.
62   perfetto::DataSourceDescriptor dsd;
63   dsd.set_name("com.example.custom_data_source");
64   CustomDataSource::Register(dsd);
65 }
66 
StartTracing()67 std::unique_ptr<perfetto::TracingSession> StartTracing() {
68   // The trace config defines which types of data sources are enabled for
69   // recording. In this example we enable the custom data source we registered
70   // above.
71   perfetto::TraceConfig cfg;
72   cfg.add_buffers()->set_size_kb(1024);
73   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
74   ds_cfg->set_name("com.example.custom_data_source");
75 
76   auto tracing_session = perfetto::Tracing::NewTrace();
77   tracing_session->Setup(cfg);
78   tracing_session->StartBlocking();
79   return tracing_session;
80 }
81 
StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session)82 void StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session) {
83   // Flush to make sure the last written event ends up in the trace.
84   CustomDataSource::Trace(
85       [](CustomDataSource::TraceContext ctx) { ctx.Flush(); });
86 
87   // Stop tracing and read the trace data.
88   tracing_session->StopBlocking();
89   std::vector<char> trace_data(tracing_session->ReadTraceBlocking());
90 
91   // Write the result into a file.
92   // Note: To save memory with longer traces, you can tell Perfetto to write
93   // directly into a file by passing a file descriptor into Setup() above.
94   std::ofstream output;
95   const char* filename = "example_custom_data_source.pftrace";
96   output.open(filename, std::ios::out | std::ios::binary);
97   output.write(&trace_data[0], static_cast<std::streamsize>(trace_data.size()));
98   output.close();
99   PERFETTO_LOG(
100       "Trace written in %s file. To read this trace in "
101       "text form, run `./tools/traceconv text %s`",
102       filename, filename);
103 }
104 
105 }  // namespace
106 
107 PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
108 PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
109 
main(int,const char **)110 int main(int, const char**) {
111   InitializePerfetto();
112   auto tracing_session = StartTracing();
113 
114   // Write an event using our custom data source.
115   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
116     auto packet = ctx.NewTracePacket();
117     packet->set_timestamp(42);
118     packet->set_for_testing()->set_str("Hello world!");
119   });
120 
121   StopTracing(std::move(tracing_session));
122   return 0;
123 }
124