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