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