viewing-and-analyzing: simplify Python example
[lttng-docs.git] / contents / getting-started / viewing-and-analyzing.md
CommitLineData
5e0cbfb0
PP
1---
2id: viewing-and-analyzing-your-traces
3---
4
5This section describes how to visualize the data gathered after tracing
6the Linux kernel or a user space application.
7
8Many ways exist to read your LTTng traces:
9
10 * **`babeltrace`** is a command line utility which converts trace formats;
11 it supports the format used by LTTng,
12 <abbr title="Common Trace Format">CTF</abbr>, as well as a basic
13 text output which may be `grep`ed. The `babeltrace` command is
14 part of the
15 <a href="http://www.efficios.com/babeltrace" class="ext">Babeltrace</a> project.
16 * Babeltrace also includes a **Python binding** so that you may
17 easily open and read an LTTng trace with your own script, benefiting
18 from the power of Python.
da5e8984 19 * **<a href="http://projects.eclipse.org/projects/tools.tracecompass" class="ext">Trace Compass</a>**
b8734c94
PP
20 is an Eclipse plugin used to visualize and analyze various types of
21 traces, including LTTng's. It also comes as a standalone application
22 and can be downloaded from
da5e8984 23 <a href="http://secretaire.dorsal.polymtl.ca/~gbastien/TracingRCP/TraceCompass/" class="ext">here</a>
b8734c94
PP
24 for a daily build of the latest source code. A version containing
25 some experimental features like Virtual Machine analysis and
26 Critical Path analysis is also available
da5e8984 27 <a href="http://secretaire.dorsal.polymtl.ca/~gbastien/TracingRCP/DorsalExperimental/" class="ext">here</a>.
5e0cbfb0
PP
28
29LTTng trace files are usually recorded in the `~/lttng-traces` directory.
30Let's now view the trace and perform a basic analysis using
31`babeltrace`.
32
33The simplest way to list all the recorded events of a trace is to pass its
34path to `babeltrace` with no options:
35
36<pre class="term">
37babeltrace ~/lttng-traces/my-session
38</pre>
39
40`babeltrace` will find all traces within the given path recursively and
41output all their events, merging them intelligently.
42
43Listing all the system calls of a Linux kernel trace with their arguments is
44easy with `babeltrace` and `grep`:
45
46<pre class="term">
47babeltrace ~/lttng-traces/my-kernel-session | grep sys_
48</pre>
49
50Counting events is also straightforward:
51
52<pre class="term">
b80ba306 53babeltrace ~/lttng-traces/my-kernel-session | grep sys_read | wc --lines
5e0cbfb0
PP
54</pre>
55
56The text output of `babeltrace` is useful for isolating events by simple
57matching using `grep` and similar utilities. However, more elaborate filters
58such as keeping only events with a field value falling within a specific range
59are not trivial to write using a shell. Moreover, reductions and even the
60most basic computations involving multiple events are virtually impossible
61to implement.
62
63Fortunately, Babeltrace ships with a Python 3 binding which makes it
64really easy to read the events of an LTTng trace sequentially and compute
65the desired information.
66
67Here's a simple example using the Babeltrace Python binding. The following
68script accepts an LTTng Linux kernel trace path as its first argument and
69outputs the short names of the top 5 running processes on CPU 0 during the
70whole trace:
71
72~~~ python
73import sys
74from collections import Counter
75import babeltrace
76
77
78def top5proc():
79 if len(sys.argv) != 2:
80 msg = 'Usage: python {} TRACEPATH'.format(sys.argv[0])
81 raise ValueError(msg)
82
83 # a trace collection holds one to many traces
84 col = babeltrace.TraceCollection()
85
86 # add the trace provided by the user
87 # (LTTng traces always have the 'ctf' format)
88 if col.add_trace(sys.argv[1], 'ctf') is None:
89 raise RuntimeError('Cannot add trace')
90
91 # this counter dict will hold execution times:
92 #
93 # task command name -> total execution time (ns)
94 exec_times = Counter()
95
96 # this holds the last `sched_switch` timestamp
97 last_ts = None
98
99 # iterate events
100 for event in col.events:
101 # keep only `sched_switch` events
102 if event.name != 'sched_switch':
103 continue
104
105 # keep only events which happened on CPU 0
106 if event['cpu_id'] != 0:
107 continue
108
109 # event timestamp
110 cur_ts = event.timestamp
111
112 if last_ts is None:
113 # we start here
114 last_ts = cur_ts
115
116 # previous task command (short) name
117 prev_comm = event['prev_comm']
118
119 # initialize entry in our dict if not yet done
120 if prev_comm not in exec_times:
121 exec_times[prev_comm] = 0
122
123 # compute previous command execution time
124 diff = cur_ts - last_ts
125
126 # update execution time of this command
127 exec_times[prev_comm] += diff
128
129 # update last timestamp
130 last_ts = cur_ts
131
132 # display top 10
a345f8e0 133 for name, ns in exec_times.most_common(5):
5e0cbfb0
PP
134 s = ns / 1000000000
135 print('{:20}{} s'.format(name, s))
136
137
138if __name__ == '__main__':
139 top5proc()
140~~~
141
142Save this script as `top5proc.py` and run it with Python 3, providing the
143path to an LTTng Linux kernel trace as the first argument:
144
145<pre class="term">
146python3 top5proc.py ~/lttng-sessions/my-session-.../kernel
147</pre>
148
149Make sure the path you provide is the directory containing actual trace
150files (`channel0_0`, `metadata`, etc.): the `babeltrace` utility recurses
151directories, but the Python binding does not.
152
153Here's an example of output:
154
155~~~ text
156swapper/0 48.607245889 s
157chromium 7.192738188 s
158pavucontrol 0.709894415 s
159Compositor 0.660867933 s
160Xorg.bin 0.616753786 s
161~~~
162
163Note that `swapper/0` is the "idle" process of CPU 0 on Linux; since we
164weren't using the CPU that much when tracing, its first position in the list
165makes sense.
This page took 0.051153 seconds and 4 git commands to generate.