• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <perfetto.h>
20 
21 #include <fstream>
22 #include <thread>
23 
24 // The definition of our custom data source. Instances of this class will be
25 // automatically created and destroyed by Perfetto.
26 class CustomDataSource : public perfetto::DataSource<CustomDataSource> {
27  public:
OnSetup(const SetupArgs &)28   void OnSetup(const SetupArgs&) override {
29     // Use this callback to apply any custom configuration to your data source
30     // based on the TraceConfig in SetupArgs.
31   }
32 
33   // Optional callbacks for tracking the lifecycle of the data source.
OnStart(const StartArgs &)34   void OnStart(const StartArgs&) override {}
OnStop(const StopArgs &)35   void OnStop(const StopArgs&) override {}
36 };
37 
38 PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
39 PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
40 
InitializePerfetto()41 void InitializePerfetto() {
42   perfetto::TracingInitArgs args;
43   // The backends determine where trace events are recorded. For this example we
44   // are going to use the in-process tracing service, which only includes in-app
45   // events.
46   args.backends = perfetto::kInProcessBackend;
47   perfetto::Tracing::Initialize(args);
48 
49   // Register our custom data source. Only the name is required, but other
50   // properties can be advertised too.
51   perfetto::DataSourceDescriptor dsd;
52   dsd.set_name("com.example.custom_data_source");
53   CustomDataSource::Register(dsd);
54 }
55 
StartTracing()56 std::unique_ptr<perfetto::TracingSession> StartTracing() {
57   // The trace config defines which types of data sources are enabled for
58   // recording. In this example we enable the custom data source we registered
59   // above.
60   perfetto::TraceConfig cfg;
61   cfg.add_buffers()->set_size_kb(1024);
62   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
63   ds_cfg->set_name("com.example.custom_data_source");
64 
65   auto tracing_session = perfetto::Tracing::NewTrace();
66   tracing_session->Setup(cfg);
67   tracing_session->StartBlocking();
68   return tracing_session;
69 }
70 
StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session)71 void StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session) {
72   // Flush to make sure the last written event ends up in the trace.
73   CustomDataSource::Trace(
74       [](CustomDataSource::TraceContext ctx) { ctx.Flush(); });
75 
76   // Stop tracing and read the trace data.
77   tracing_session->StopBlocking();
78   std::vector<char> trace_data(tracing_session->ReadTraceBlocking());
79 
80   // Write the result into a file.
81   // Note: To save memory with longer traces, you can tell Perfetto to write
82   // directly into a file by passing a file descriptor into Setup() above.
83   std::ofstream output;
84   output.open("example_custom_data_source.pftrace",
85               std::ios::out | std::ios::binary);
86   output.write(&trace_data[0], trace_data.size());
87   output.close();
88 }
89 
main(int,const char **)90 int main(int, const char**) {
91   InitializePerfetto();
92   auto tracing_session = StartTracing();
93 
94   // Write an event using our custom data source.
95   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
96     auto packet = ctx.NewTracePacket();
97     packet->set_timestamp(42);
98     packet->set_for_testing()->set_str("Hello world!");
99   });
100 
101   StopTracing(std::move(tracing_session));
102   return 0;
103 }
104