xref: /aosp_15_r20/external/perfetto/examples/sdk/example_system_wide.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2020 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 system-wide tracing with Perfetto.
18*6dbdd20aSAndroid Build Coastguard Worker //
19*6dbdd20aSAndroid Build Coastguard Worker // 1). To use it, first build the `tracebox` and this file. The tracebox will
20*6dbdd20aSAndroid Build Coastguard Worker // internally build tracing service (traced, which is long running
21*6dbdd20aSAndroid Build Coastguard Worker // process / daemon ) and perfetto consumer client, and many other perfetto
22*6dbdd20aSAndroid Build Coastguard Worker // tracing related tools.
23*6dbdd20aSAndroid Build Coastguard Worker // `ninja -C out/default/ tracebox example_system_wide`
24*6dbdd20aSAndroid Build Coastguard Worker //
25*6dbdd20aSAndroid Build Coastguard Worker // 2). Run traced (long running process), and open another terminal tab.
26*6dbdd20aSAndroid Build Coastguard Worker // `./out/default/tracebox traced`
27*6dbdd20aSAndroid Build Coastguard Worker //
28*6dbdd20aSAndroid Build Coastguard Worker // 3). Run this file. This is main application to trace.
29*6dbdd20aSAndroid Build Coastguard Worker // `./out/default/example_system_wide`
30*6dbdd20aSAndroid Build Coastguard Worker //
31*6dbdd20aSAndroid Build Coastguard Worker // 4). Use perfetto client to start a session and record trace in a file.
32*6dbdd20aSAndroid Build Coastguard Worker // `./out/default/tracebox perfetto -c /tmp/trace_config.txt --txt
33*6dbdd20aSAndroid Build Coastguard Worker //      -o /tmp/trace_output`
34*6dbdd20aSAndroid Build Coastguard Worker //
35*6dbdd20aSAndroid Build Coastguard Worker // but before running that command, put following trace config (protobuf config)
36*6dbdd20aSAndroid Build Coastguard Worker // in a file named `/tmp/trace_config.txt`
37*6dbdd20aSAndroid Build Coastguard Worker // This can also be copied from: https://pastebin.com/embed_iframe/ufmtBBuq
38*6dbdd20aSAndroid Build Coastguard Worker // ---------------------
39*6dbdd20aSAndroid Build Coastguard Worker // buffers: {
40*6dbdd20aSAndroid Build Coastguard Worker //     size_kb: 63488
41*6dbdd20aSAndroid Build Coastguard Worker // }
42*6dbdd20aSAndroid Build Coastguard Worker // data_sources: {
43*6dbdd20aSAndroid Build Coastguard Worker //     config {
44*6dbdd20aSAndroid Build Coastguard Worker //         name: "track_event"
45*6dbdd20aSAndroid Build Coastguard Worker //     }
46*6dbdd20aSAndroid Build Coastguard Worker // }
47*6dbdd20aSAndroid Build Coastguard Worker // duration_ms: 10000
48*6dbdd20aSAndroid Build Coastguard Worker // ---------------------
49*6dbdd20aSAndroid Build Coastguard Worker // After running the command above, trace will be saved in `/tmp/trace_output`
50*6dbdd20aSAndroid Build Coastguard Worker // file. It is a binary content. We can read it by running:
51*6dbdd20aSAndroid Build Coastguard Worker // `./tools/traceconv text /tmp/trace_output`
52*6dbdd20aSAndroid Build Coastguard Worker // Or we can use "Open Trace File" option in the perfetto UI
53*6dbdd20aSAndroid Build Coastguard Worker // (https://ui.perfetto.dev)
54*6dbdd20aSAndroid Build Coastguard Worker //
55*6dbdd20aSAndroid Build Coastguard Worker // Learn More:
56*6dbdd20aSAndroid Build Coastguard Worker // https://perfetto.dev/docs/quickstart/linux-tracing#capturing-a-trace
57*6dbdd20aSAndroid Build Coastguard Worker 
58*6dbdd20aSAndroid Build Coastguard Worker #include "trace_categories.h"
59*6dbdd20aSAndroid Build Coastguard Worker 
60*6dbdd20aSAndroid Build Coastguard Worker #include <chrono>
61*6dbdd20aSAndroid Build Coastguard Worker #include <condition_variable>
62*6dbdd20aSAndroid Build Coastguard Worker #include <fstream>
63*6dbdd20aSAndroid Build Coastguard Worker #include <thread>
64*6dbdd20aSAndroid Build Coastguard Worker 
65*6dbdd20aSAndroid Build Coastguard Worker namespace {
66*6dbdd20aSAndroid Build Coastguard Worker 
67*6dbdd20aSAndroid Build Coastguard Worker class Observer : public perfetto::TrackEventSessionObserver {
68*6dbdd20aSAndroid Build Coastguard Worker  public:
Observer()69*6dbdd20aSAndroid Build Coastguard Worker   Observer() { perfetto::TrackEvent::AddSessionObserver(this); }
~Observer()70*6dbdd20aSAndroid Build Coastguard Worker   ~Observer() override { perfetto::TrackEvent::RemoveSessionObserver(this); }
71*6dbdd20aSAndroid Build Coastguard Worker 
OnStart(const perfetto::DataSourceBase::StartArgs &)72*6dbdd20aSAndroid Build Coastguard Worker   void OnStart(const perfetto::DataSourceBase::StartArgs&) override {
73*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex);
74*6dbdd20aSAndroid Build Coastguard Worker     cv.notify_one();
75*6dbdd20aSAndroid Build Coastguard Worker   }
76*6dbdd20aSAndroid Build Coastguard Worker 
WaitForTracingStart()77*6dbdd20aSAndroid Build Coastguard Worker   void WaitForTracingStart() {
78*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_LOG("Waiting for tracing to start...");
79*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex);
80*6dbdd20aSAndroid Build Coastguard Worker     cv.wait(lock, [] { return perfetto::TrackEvent::IsEnabled(); });
81*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_LOG("Tracing started");
82*6dbdd20aSAndroid Build Coastguard Worker   }
83*6dbdd20aSAndroid Build Coastguard Worker 
84*6dbdd20aSAndroid Build Coastguard Worker   std::mutex mutex;
85*6dbdd20aSAndroid Build Coastguard Worker   std::condition_variable cv;
86*6dbdd20aSAndroid Build Coastguard Worker };
87*6dbdd20aSAndroid Build Coastguard Worker 
InitializePerfetto()88*6dbdd20aSAndroid Build Coastguard Worker void InitializePerfetto() {
89*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TracingInitArgs args;
90*6dbdd20aSAndroid Build Coastguard Worker   // The backends determine where trace events are recorded. For this example we
91*6dbdd20aSAndroid Build Coastguard Worker   // are going to use the system-wide tracing service, so that we can see our
92*6dbdd20aSAndroid Build Coastguard Worker   // app's events in context with system profiling information.
93*6dbdd20aSAndroid Build Coastguard Worker   args.backends = perfetto::kSystemBackend;
94*6dbdd20aSAndroid Build Coastguard Worker   args.enable_system_consumer = false;
95*6dbdd20aSAndroid Build Coastguard Worker 
96*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::Initialize(args);
97*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Register();
98*6dbdd20aSAndroid Build Coastguard Worker }
99*6dbdd20aSAndroid Build Coastguard Worker 
DrawPlayer(int player_number)100*6dbdd20aSAndroid Build Coastguard Worker void DrawPlayer(int player_number) {
101*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT("rendering", "DrawPlayer", "player_number", player_number);
102*6dbdd20aSAndroid Build Coastguard Worker   // Sleep to simulate a long computation.
103*6dbdd20aSAndroid Build Coastguard Worker   std::this_thread::sleep_for(std::chrono::milliseconds(500));
104*6dbdd20aSAndroid Build Coastguard Worker }
105*6dbdd20aSAndroid Build Coastguard Worker 
DrawGame()106*6dbdd20aSAndroid Build Coastguard Worker void DrawGame() {
107*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT("rendering", "DrawGame");
108*6dbdd20aSAndroid Build Coastguard Worker   DrawPlayer(1);
109*6dbdd20aSAndroid Build Coastguard Worker   DrawPlayer(2);
110*6dbdd20aSAndroid Build Coastguard Worker }
111*6dbdd20aSAndroid Build Coastguard Worker 
112*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
113*6dbdd20aSAndroid Build Coastguard Worker 
main(int,const char **)114*6dbdd20aSAndroid Build Coastguard Worker int main(int, const char**) {
115*6dbdd20aSAndroid Build Coastguard Worker   InitializePerfetto();
116*6dbdd20aSAndroid Build Coastguard Worker 
117*6dbdd20aSAndroid Build Coastguard Worker   Observer observer;
118*6dbdd20aSAndroid Build Coastguard Worker   observer.WaitForTracingStart();
119*6dbdd20aSAndroid Build Coastguard Worker 
120*6dbdd20aSAndroid Build Coastguard Worker   // Simulate some work that emits trace events.
121*6dbdd20aSAndroid Build Coastguard Worker   // Note that we don't start and stop tracing here; for system-wide tracing
122*6dbdd20aSAndroid Build Coastguard Worker   // this needs to be done through the "perfetto" command line tool or the
123*6dbdd20aSAndroid Build Coastguard Worker   // Perfetto UI (https://ui.perfetto.dev).
124*6dbdd20aSAndroid Build Coastguard Worker   DrawGame();
125*6dbdd20aSAndroid Build Coastguard Worker 
126*6dbdd20aSAndroid Build Coastguard Worker   // Make sure the last event is closed for this example.
127*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
128*6dbdd20aSAndroid Build Coastguard Worker 
129*6dbdd20aSAndroid Build Coastguard Worker   return 0;
130*6dbdd20aSAndroid Build Coastguard Worker }
131