1 .. include:: common.rst
7 This section contains a few short and straightforward examples which
8 show how to use the Babeltrace |~| 2 Python bindings.
10 The :mod:`bt2` package provides the Babeltrace |~| 2 Python bindings.
11 Note that the :mod:`babeltrace` package is part of the Babeltrace |~| 1
12 project: it's somewhat out-of-date and not compatible with the
15 Assume that all the examples below are named :file:`example.py`.
21 The most convenient and high-level way to iterate the events of one or
22 more traces is with a :class:`bt2.TraceCollectionMessageIterator`
25 A :class:`bt2.TraceCollectionMessageIterator` object roughly offers the
26 same features as the ``convert`` command of the :command:`babeltrace2`
27 command-line program (see the :bt2man:`babeltrace2-convert(1)` manual
28 page), but in a programmatic, Pythonic way.
30 As of Babeltrace |~| |version|, the trace collection message iterator
31 class is a Python bindings-only feature: the Python code uses
32 libbabeltrace2 internally, but the latter does not offer this utility as
35 The :class:`bt2.TraceCollectionMessageIterator` interface features:
37 * **Automatic source component (trace format) discovery**.
39 ``convert`` command equivalent example:
43 $ babeltrace2 /path/to/my/trace
45 * **Explicit component class instantiation**.
47 ``convert`` command equivalent example:
51 $ babeltrace2 --component=source.my.format
53 * **Passing initialization parameters to both auto-discovered and
54 explicitly created components**.
56 ``convert`` command equivalent example:
60 $ babeltrace2 /path/to/my/trace --params=detailed=no \
61 --component=source.ctf.fs \
62 --params='inputs=["/path/to/my/trace"]'
64 * **Trace event muxing**.
66 The message iterator muxes (combines) the events from multiple
67 compatible streams into a single, time-sorted sequence of events.
71 $ babeltrace2 /path/to/trace1 /path/to/trace2 /path/to/trace3
73 * **Stream intersection mode**.
75 ``convert`` command equivalent example:
79 $ babeltrace2 /path/to/my/trace --stream-intersection
81 * **Stream trimming with beginning and/or end times**.
83 ``convert`` command equivalent example:
87 $ babeltrace2 /path/to/my/trace --begin=22:14:38 --end=22:15:07
89 While the :command:`babeltrace2 convert` command creates a ``sink.text.pretty``
90 component class (by default) to pretty-print events as plain text lines,
91 a :class:`bt2.TraceCollectionMessageIterator` object is a Python
92 iterator which makes its user a message consumer (there's no sink
97 for msg in bt2.TraceCollectionMessageIterator('/path/to/trace'):
98 if type(msg) is bt2._EventMessageConst:
101 .. _examples_tcmi_autodisc:
105 Pass one or more file paths, directory paths, or other strings when you
106 build a :class:`bt2.TraceCollectionMessageIterator` object to let it
107 automatically determine which source components to create for you.
109 If you pass a directory path, the message iterator traverses the
110 directory recursively to find traces, automatically selecting the
111 appropriate source component classes to instantiate.
113 The :class:`bt2.TraceCollectionMessageIterator` object and the
114 :command:`babeltrace2 convert` CLI command share the same automatic
115 component discovery algorithm. See the
116 :bt2link:`Create implicit components from non-option arguments <https://babeltrace.org/docs/v@ver@/man1/babeltrace2-convert.1/#doc-comp-create-impl-non-opt>`
117 section of the :bt2man:`babeltrace2-convert(1)` manual page for more
120 The following example shows how to use a
121 :class:`bt2.TraceCollectionMessageIterator` object to automatically
122 discover one or more traces from a single path (file or directory). For
123 each trace event, the example prints its name::
128 # Get the trace path from the first command-line argument.
131 # Create a trace collection message iterator with this path.
132 msg_it = bt2.TraceCollectionMessageIterator(path)
134 # Iterate the trace messages.
136 # `bt2._EventMessageConst` is the Python type of an event message.
137 if type(msg) is bt2._EventMessageConst:
138 # An event message holds a trace event.
141 # Print event's name.
148 $ python3 example.py /path/to/one/or/more/traces
156 kmem_cache_alloc_node
167 The example above is simplistic; it does not catch the exceptions that
168 some statements can raise:
170 * ``bt2.TraceCollectionMessageIterator(path)`` raises an exception if
171 it cannot find any trace.
173 * Each iteration of the loop, or, more precisely, the
174 :meth:`bt2.TraceCollectionMessageIterator.__next__` method, raises
175 an exception if there's any error during the iteration process.
177 For example, an internal source component message iterator can fail
178 when trying to decode a malformed trace file.
180 .. _examples_tcmi_expl:
182 Create explicit source components
183 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
184 If `automatic source component discovery <#examples-tcmi-autodisc>`_
185 doesn't work for you (for example, because the source component class
186 you actually need to instantiate doesn't offer the
187 ``babeltrace.support-info`` query object), create explicit source
188 components when you build a :class:`bt2.TraceCollectionMessageIterator`
191 The following example builds a trace collection message iterator to
192 explicitly instantiate a ``source.ctf.fs`` component class (found in the
193 ``ctf`` plugin). Again, for each trace event, the example prints its
199 # Find the `ctf` plugin (shipped with Babeltrace 2).
200 ctf_plugin = bt2.find_plugin('ctf')
202 # Get the `source.ctf.fs` component class from the plugin.
203 fs_cc = ctf_plugin.source_component_classes['fs']
205 # Create a trace collection message iterator, instantiating a single
206 # `source.ctf.fs` component class with the `inputs` initialization
207 # parameter set to open a single CTF trace.
208 msg_it = bt2.TraceCollectionMessageIterator(bt2.ComponentSpec(fs_cc, {
209 # Get the CTF trace path from the first command-line argument.
210 'inputs': [sys.argv[1]],
213 # Iterate the trace messages.
215 # `bt2._EventMessageConst` is the Python type of an event message.
216 if type(msg) is bt2._EventMessageConst:
217 # Print event's name.
218 print(msg.event.name)
224 $ python3 example.py /path/to/ctf/trace
232 kmem_cache_alloc_node
243 The example above looks similar to the previous one using
244 `automatic source component discovery <#examples-tcmi-autodisc>`_,
245 but there are notable differences:
247 * A ``source.ctf.fs`` component expects to receive the path to a
248 *single* `CTF <https://diamon.org/ctf/>`_ trace (a directory
249 containing a file named ``metadata``).
251 Unlike the previous example, you must pass the exact
252 :abbr:`CTF (Common Trace Format)` trace directory path, *not* a
253 parent directory path.
255 * Unlike the previous example, the example above can only read a single
258 If you want to read multiple :abbr:`CTF (Common Trace Format)` traces
259 using explicit component class instantiation with a single trace
260 collection message iterator, you must create one ``source.ctf.fs``
263 Note that the :class:`bt2.ComponentSpec` class offers the
264 :meth:`from_named_plugin_and_component_class` convenience static method
265 which finds the plugin and component class for you. You could therefore
266 rewrite the trace collection message iterator creation part of the
269 # Create a trace collection message iterator, instantiating a single
270 # `source.ctf.fs` component class with the `inputs` initialization
271 # parameter set to open a single CTF trace.
272 msg_it = bt2.TraceCollectionMessageIterator(
273 bt2.ComponentSpec.from_named_plugin_and_component_class('ctf', 'fs', {
274 # Get the CTF trace path from the first command-line argument.
275 'inputs': [sys.argv[1]],
279 .. _examples_tcmi_ev_field:
281 Get a specific event field's value
282 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
283 The :ref:`examples_tcmi_autodisc` and :ref:`examples_tcmi_expl` examples
284 show that a :class:`bt2.TraceCollectionMessageIterator` iterates the
285 time-sorted *messages* of one or more traces.
287 One specific type of message is :class:`bt2._EventMessageConst`, which
288 holds a trace event object.
292 Everything you can find in the :mod:`bt2` package is publicly
295 Names which start with ``_`` (underscore), like
296 :class:`bt2._EventMessageConst`, indicate that you can't
297 *instantiate* such a class (you cannot call the class). However, the
298 type itself remains public so that you can use its name to check an
301 .. code-block:: python
303 if type(msg) is bt2._EventMessageConst:
306 .. code-block:: python
308 if isinstance(field, bt2._IntegerFieldConst):
311 Access an event object's field by using the event as a simple mapping
312 (like a read-only :class:`dict`), where keys are field names. The field
313 can belong to any part of the event (contexts or payload) and to its
314 packet's context, if any::
319 # Create a trace collection message iterator from the first
320 # command-line argument.
321 msg_it = bt2.TraceCollectionMessageIterator(sys.argv[1])
323 # Iterate the trace messages.
325 # `bt2._EventMessageConst` is the Python type of an event message.
326 # Only keep such messages.
327 if type(msg) is not bt2._EventMessageConst:
330 # An event message holds a trace event.
333 # Only check `sched_switch` events.
334 if event.name != 'sched_switch':
337 # In an LTTng trace, the `cpu_id` field is a packet context field.
338 # The mapping interface of `event` can still find it.
339 cpu_id = event['cpu_id']
341 # Previous and next process short names are found in the event's
342 # `prev_comm` and `next_comm` fields.
343 prev_comm = event['prev_comm']
344 next_comm = event['next_comm']
346 # Print line, using field values.
347 msg = 'CPU {}: Switching process `{}` → `{}`'
348 print(msg.format(cpu_id, prev_comm, next_comm))
350 The example above assumes that the traces to open are
351 `LTTng <https://lttng.org/>`_ Linux kernel traces.
357 $ python3 example.py /path/to/one/or/more/lttng/traces
363 CPU 2: Switching process `Timer` → `swapper/2`
364 CPU 0: Switching process `swapper/0` → `firefox`
365 CPU 0: Switching process `firefox` → `swapper/0`
366 CPU 0: Switching process `swapper/0` → `rcu_preempt`
367 CPU 0: Switching process `rcu_preempt` → `swapper/0`
368 CPU 3: Switching process `swapper/3` → `alsa-sink-ALC26`
369 CPU 2: Switching process `swapper/2` → `Timer`
370 CPU 2: Switching process `Timer` → `swapper/2`
371 CPU 2: Switching process `swapper/2` → `pulseaudio`
372 CPU 0: Switching process `swapper/0` → `firefox`
373 CPU 1: Switching process `swapper/1` → `threaded-ml`
374 CPU 2: Switching process `pulseaudio` → `Timer`
376 If you need to access a specific field, use:
379 :attr:`bt2._EventConst.payload_field` property.
381 Event specific context
382 :attr:`bt2._EventConst.specific_context_field` property.
385 :attr:`bt2._EventConst.common_context_field` property.
388 :attr:`bt2._PacketConst.context_field` property.
390 Use Python's ``in`` operator to verify if:
392 A specific "root" field (in the list above) contains a given field by name
393 .. code-block:: python
395 if 'next_comm' in event.payload_field:
398 Any of the root fields contains a given field by name
399 .. code-block:: python
401 if 'next_comm' in event:
404 The following example iterates the events of a given trace, printing the
405 value of the ``fd`` payload field if it's available::
410 # Create a trace collection message iterator from the first command-line
412 msg_it = bt2.TraceCollectionMessageIterator(sys.argv[1])
414 # Iterate the trace messages.
416 # `bt2._EventMessageConst` is the Python type of an event message.
417 if type(msg) is bt2._EventMessageConst:
418 # Check if the `fd` event payload field exists.
419 if 'fd' in msg.event.payload_field:
420 # Print the `fd` event payload field's value.
421 print(msg.event.payload_field['fd'])
440 .. _examples_tcmi_ev_time:
444 The time, or timestamp, of an event object belongs to its message as
445 a *default clock snapshot*.
447 An event's clock snapshot is a *snapshot* (an immutable value) of the
448 value of the event's stream's clock when the event occurred. As of
449 Babeltrace |~| |version|, a stream can only have one clock: its default
452 Use the :attr:`default_clock_snapshot` property of an event message
453 to get its default clock snapshot. A clock snapshot object offers,
454 amongst other things, the following properties:
456 :attr:`value` (:class:`int`)
457 Value of the clock snapshot in clock cycles.
459 A stream clock can have any frequency (Hz).
461 :attr:`ns_from_origin` (:class:`int`)
462 Number of nanoseconds from the stream clock's origin (often the Unix
465 The following example prints, for each event, its name, its date/time,
466 and the difference, in seconds, since the previous event's time (if
473 # Create a trace collection message iterator from the first command-line
475 msg_it = bt2.TraceCollectionMessageIterator(sys.argv[1])
477 # Last event's time (ns from origin).
478 last_event_ns_from_origin = None
480 # Iterate the trace messages.
482 # `bt2._EventMessageConst` is the Python type of an event message.
483 if type(msg) is bt2._EventMessageConst:
484 # Get event message's default clock snapshot's ns from origin
486 ns_from_origin = msg.default_clock_snapshot.ns_from_origin
488 # Compute the time difference since the last event message.
491 if last_event_ns_from_origin is not None:
492 diff_s = (ns_from_origin - last_event_ns_from_origin) / 1e9
494 # Create a `datetime.datetime` object from `ns_from_origin` for
495 # presentation. Note that such an object is less accurate than
496 # `ns_from_origin` as it holds microseconds, not nanoseconds.
497 dt = datetime.datetime.fromtimestamp(ns_from_origin / 1e9)
500 fmt = '{} (+{:.6f} s): {}'
501 print(fmt.format(dt, diff_s, msg.event.name))
503 # Update last event's time.
504 last_event_ns_from_origin = ns_from_origin
510 $ python3 example.py /path/to/one/or/more/traces
516 2015-09-09 22:40:41.551451 (+0.000004 s): lttng_ust_statedump:end
517 2015-09-09 22:40:43.003397 (+1.451946 s): lttng_ust_dl:dlopen
518 2015-09-09 22:40:43.003412 (+0.000015 s): lttng_ust_dl:build_id
519 2015-09-09 22:40:43.003861 (+0.000449 s): lttng_ust_dl:dlopen
520 2015-09-09 22:40:43.003865 (+0.000004 s): lttng_ust_dl:build_id
521 2015-09-09 22:40:43.003879 (+0.000014 s): my_provider:my_first_tracepoint
522 2015-09-09 22:40:43.003895 (+0.000016 s): my_provider:my_first_tracepoint
523 2015-09-09 22:40:43.003898 (+0.000003 s): my_provider:my_other_tracepoint
524 2015-09-09 22:40:43.003922 (+0.000023 s): lttng_ust_dl:dlclose
526 Bonus: Print top 5 running processes using LTTng
527 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
528 As :ref:`examples_tcmi_ev_field` shows, a
529 :class:`bt2.TraceCollectionMessageIterator` can read
530 `LTTng <https://lttng.org/>`_ traces.
532 The following example is similar to :ref:`examples_tcmi_ev_time`: it
533 reads a whole LTTng Linux kernel trace, but instead of printing the time
534 difference for each event, it accumulates them to print the short names
535 of the top |~| 5 running processes on CPU |~| 0 during the whole trace.
537 .. code-block:: python
543 # Create a trace collection message iterator from the first command-line
545 msg_it = bt2.TraceCollectionMessageIterator(sys.argv[1])
547 # This counter dictionary will hold execution times:
549 # Task command name -> Total execution time (ns)
550 exec_times = collections.Counter()
552 # This holds the last `sched_switch` event time.
553 last_ns_from_origin = None
556 # `bt2._EventMessageConst` is the Python type of an event message.
557 # Only keep such messages.
558 if type(msg) is not bt2._EventMessageConst:
561 # An event message holds a trace event.
564 # Only check `sched_switch` events.
565 if event.name != 'sched_switch':
568 # Keep only events which occurred on CPU 0.
569 if event['cpu_id'] != 0:
572 # Get event message's default clock snapshot's ns from origin value.
573 ns_from_origin = msg.default_clock_snapshot.ns_from_origin
575 if last_ns_from_origin is None:
577 last_ns_from_origin = ns_from_origin
579 # Previous process's short name.
580 prev_comm = str(event['prev_comm'])
582 # Initialize an entry in our dictionary if not done yet.
583 if prev_comm not in exec_times:
584 exec_times[prev_comm] = 0
586 # Compute previous process's execution time.
587 diff_ns = ns_from_origin - last_ns_from_origin
589 # Update execution time of this command.
590 exec_times[prev_comm] += diff_ns
592 # Update last event's time.
593 last_ns_from_origin = ns_from_origin
596 for comm, ns in exec_times.most_common(5):
597 print('{:20}{} s'.format(comm, ns / 1e9))
603 $ python3 example.py /path/to/lttng/trace
609 swapper/0 326.294314471 s
610 chromium 2.500456202 s
611 Xorg.bin 0.546656895 s
612 threaded-ml 0.545098185 s
613 pulseaudio 0.53677713 s
615 Note that ``swapper/0`` is the "idle" process of CPU |~| 0 on Linux;
616 since we weren't using the CPU that much when tracing, its first
617 position in the list makes sense.
619 Inspect event classes
620 ~~~~~~~~~~~~~~~~~~~~~
621 Each event stream is a *stream class* instance.
623 A stream class contains *event classes*. A stream class's event classes
624 describe all the possible events you can find in its instances. Stream
625 classes and event classes form the *metadata* of streams and events.
627 The following example shows how to list all the event classes of a
628 stream class. For each event class, the example also prints the names of
629 its payload field class's first-level members.
633 As of Babeltrace |~| |version|, there's no way to access a stream class
634 without consuming at least one message for one of its instances
637 A source component can add new event classes to existing stream
638 classes during the trace processing task. Therefore, this example
639 only lists the initial stream class's event classes.
641 .. code-block:: python
646 # Create a trace collection message iterator from the first command-line
648 msg_it = bt2.TraceCollectionMessageIterator(sys.argv[1])
650 # Get the message iterator's first stream beginning message.
652 # `bt2._StreamBeginningMessageConst` is the Python type of a stream
654 if type(msg) is bt2._StreamBeginningMessageConst:
657 # A stream beginning message holds a stream.
660 # Get the stream's class.
661 stream_class = stream.cls
663 # The stream class object offers a mapping interface (like a read-only
664 # `dict`), where keys are event class IDs and values are
665 # `bt2._EventClassConst` objects.
666 for event_class in stream_class.values():
667 print('{}:'.format(event_class.name))
669 # The `payload_field_class` property of an event class returns a
670 # `bt2._StructureFieldClassConst` object. This object offers a
671 # mapping interface, where keys are member names and values are
672 # `bt2._StructureFieldClassMemberConst` objects.
673 for member in event_class.payload_field_class.values():
675 print(fmt.format(member.name, bt2.__name__,
676 member.field_class.__class__.__name__))
682 $ python3 example.py /path/to/trace
689 comm: `bt2._StringFieldClassConst`
690 tid: `bt2._SignedIntegerFieldClassConst`
691 prio: `bt2._SignedIntegerFieldClassConst`
692 orig_cpu: `bt2._SignedIntegerFieldClassConst`
693 dest_cpu: `bt2._SignedIntegerFieldClassConst`
695 prev_comm: `bt2._StringFieldClassConst`
696 prev_tid: `bt2._SignedIntegerFieldClassConst`
697 prev_prio: `bt2._SignedIntegerFieldClassConst`
698 prev_state: `bt2._SignedIntegerFieldClassConst`
699 next_comm: `bt2._StringFieldClassConst`
700 next_tid: `bt2._SignedIntegerFieldClassConst`
701 next_prio: `bt2._SignedIntegerFieldClassConst`
703 comm: `bt2._StringFieldClassConst`
704 tid: `bt2._SignedIntegerFieldClassConst`
705 prio: `bt2._SignedIntegerFieldClassConst`
706 target_cpu: `bt2._SignedIntegerFieldClassConst`
710 Build and run a trace processing graph
711 --------------------------------------
712 Internally, a :class:`bt2.TraceCollectionMessageIterator` object (see
713 :ref:`examples_tcmi`) builds a *trace processing graph*, just like the
714 :bt2man:`babeltrace2-convert(1)` CLI command, and then offers a
715 Python iterator interface on top of it.
717 See the :bt2man:`babeltrace2-intro(7)` manual page to learn more about
718 the Babeltrace |~| 2 project and its core concepts.
720 The following examples shows how to manually build and then run a trace
721 processing graph yourself (like the :bt2man:`babeltrace2-run(1)` CLI
722 command does). The general steps to do so are:
724 #. Create an empty graph.
726 #. Add components to the graph.
728 This process is also known as *instantiating a component class*
729 because the graph must first create the component from its class
732 A viable graph contains at least one source component and one sink
735 #. Connect component ports.
737 On initialization, components add input and output ports, depending
740 You can connect component output ports to input ports within a graph.
744 This is a blocking operation which makes each sink component consume
745 some messages in a round robin fashion until there are no more.
747 .. code-block:: python
752 # Create an empty graph.
755 # Add a `source.text.dmesg` component.
757 # graph.add_component() returns the created and added component.
759 # Such a component reads Linux kernel ring buffer messages (see
760 # `dmesg(1)`) from the standard input and creates corresponding event
761 # messages. See `babeltrace2-source.text.dmesg(7)`.
763 # `my source` is the unique name of this component within `graph`.
764 comp_cls = bt2.find_plugin('text').source_component_classes['dmesg']
765 src_comp = graph.add_component(comp_cls, 'my source')
767 # Add a `sink.text.pretty` component.
769 # Such a component pretty-prints event messages on the standard output
770 # (one message per line). See `babeltrace2-sink.text.pretty(7)`.
772 # The `babeltrace2 convert` CLI command uses a `sink.text.pretty`
773 # sink component by default.
774 comp_cls = bt2.find_plugin('text').sink_component_classes['pretty']
775 sink_comp = graph.add_component(comp_cls, 'my sink')
777 # Connect the `out` output port of the `source.text.dmesg` component
778 # to the `in` input port of the `sink.text.pretty` component.
779 graph.connect_ports(src_comp.output_ports['out'],
780 sink_comp.input_ports['in'])
782 # Run the trace processing graph.
789 $ dmesg -t | python3 example.py
795 string: { str = "ata1.00: NCQ Send/Recv Log not supported" }
796 string: { str = "ata1.00: ACPI cmd ef/02:00:00:00:00:a0 (SET FEATURES) succeeded" }
797 string: { str = "ata1.00: ACPI cmd f5/00:00:00:00:00:a0 (SECURITY FREEZE LOCK) filtered out" }
798 string: { str = "ata1.00: ACPI cmd ef/10:03:00:00:00:a0 (SET FEATURES) filtered out" }
799 string: { str = "ata1.00: NCQ Send/Recv Log not supported" }
800 string: { str = "ata1.00: configured for UDMA/133" }
801 string: { str = "ata1.00: Enabling discard_zeroes_data" }
802 string: { str = "OOM killer enabled." }
803 string: { str = "Restarting tasks ... done." }
804 string: { str = "PM: suspend exit" }
806 Query a component class
807 -----------------------
808 Component classes, provided by plugins, can implement a method to
809 support *query operations*.
811 A query operation is similar to a function call: the caller makes a
812 request (a query) with parameters and the component class's query
813 method returns a result object.
815 The query operation feature exists so that you can benefit from a
816 component class's implementation to get information about a trace, a
817 stream, a distant server, and so on. For example, the
818 ``source.ctf.lttng-live`` component class (see
819 :bt2man:`babeltrace2-source.ctf.lttng-live(7)`) offers the ``sessions``
820 object to list the available
821 `LTTng live <https://lttng.org/docs/v2.11/#doc-lttng-live>`_ tracing
822 session names and other properties.
824 The semantics of the query parameters and the returned object are
825 completely defined by the component class implementation: the library
826 and its Python bindings don't enforce or suggest any layout.
827 The best way to know which objects you can query from a component class,
828 what are the expected and optional parameters, and what the returned
829 object contains is to read this component class's documentation.
831 The following example queries the "standard" ``babeltrace.support-info``
833 :bt2man:`babeltrace2-query-babeltrace.support-info(7)`) from the
834 ``source.ctf.fs`` component class
835 (see :bt2man:`babeltrace2-source.ctf.fs(7)`) and
836 pretty-prints the result. The ``babeltrace.support-info`` query object
837 indicates whether or not a given path locates a
838 :abbr:`CTF (Common Trace Format)` trace directory::
843 # Get the `source.ctf.fs` component class from the `ctf` plugin.
844 comp_cls = bt2.find_plugin('ctf').source_component_classes['fs']
846 # The `babeltrace.support-info` query operation expects a `type`
847 # parameter (set to `directory` here) and an `input` parameter (the
848 # actual path or string to check, in this case the first command-line
851 # See `babeltrace2-query-babeltrace.support-info(7)`.
854 'input': sys.argv[1],
857 # Create a query executor.
859 # This is the environment in which query operations happens. The
860 # queried component class has access to this executor, for example to
861 # retrieve the query operation's logging level.
862 query_exec = bt2.QueryExecutor(comp_cls, 'babeltrace.support-info',
865 # Query the component class through the query executor.
867 # This method returns the result.
868 result = query_exec.query()
873 As you can see, no trace processing graph is involved (like in
874 :ref:`examples_tcmi` and :ref:`examples_graph`): a query operation
875 is *not* a sequential trace processing task, but a simple, atomic
882 $ python3 example.py /path/to/ctf/trace
888 {'group': '21c63a42-40bc-4c08-9761-3815ae01f43d', 'weight': 0.75}
890 This result indicates that the component class is 75 |~| % confident that
891 :file:`/path/to/ctf/trace` is a CTF trace directory path. It also shows
892 that this specific CTF trace belongs to the
893 ``21c63a42-40bc-4c08-9761-3815ae01f43d`` group; a single component can
894 handle multiple traces which belong to the same group.
896 Let's try the sample example with a path that doesn't locate a CTF
901 $ python3 example.py /etc
909 As expected, the zero weight indicates that ``/etc`` isn't a CTF trace