python: make all _get_ref/_put_ref proper static methods
[babeltrace.git] / CONTRIBUTING.adoc
1 // Render with Asciidoctor
2
3 = Babeltrace{nbsp}2 contributor's guide
4 Jérémie Galarneau, Philippe Proulx
5 1 December 2020
6 :toc: left
7 :toclevels: 3
8 :icons: font
9 :nofooter:
10 :bt2: Babeltrace{nbsp}2
11 :c-cpp: C/{cpp}
12 :cpp11: {cpp}11
13
14 This is a partial contributor's guide for the
15 https://babeltrace.org[{bt2}] project. If you have any
16 questions that are not answered by this guide, please post them on
17 https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev[Babeltrace's
18 mailing list].
19
20 == {bt2} library
21
22 === Object reference counting and lifetime
23
24 This section covers the rationale behind the design of {bt2}'s
25 object lifetime management. This applies to the {bt2} library, as
26 well as to the CTF writer library (although the public reference
27 counting functions are not named the same way).
28
29 Starting from Babeltrace{nbsp}2.0, all publicly exposed objects inherit
30 a common base: `bt_object`. This base provides a number of facilities to
31 all objects, chief amongst which are lifetime management functions.
32
33 The lifetime of some public objects is managed by reference counting. In
34 this case, the API offers the `+bt_*_get_ref()+` and `+bt_*_put_ref()+`
35 functions which respectively increment and decrement an object's
36 reference count.
37
38 As far as lifetime management in concerned, {bt2} makes a clear
39 distinction between regular objects, which have a single parent, and
40 root objects, which don't.
41
42 ==== The problem
43
44 Let us consider a problematic case to illustrate the need for this
45 distinction.
46
47 A user of the {bt2} library creates a trace class, which _has_ a
48 stream class (the class of a stream) and that stream class, in turn,
49 _has_ an event class (the class of an event).
50
51 Nothing prevents this user from releasing his reference on any one of
52 these objects in any order. However, all objects in the
53 __trace--stream class--event class__ hierarchy can be retrieved
54 from any other.
55
56 For instance, the user could discard his reference on both the event
57 class and the stream class, only keeping a reference on the trace class.
58 From this trace class reference, stream classes can be enumerated,
59 providing the user with a new reference to the stream class he discarded
60 earlier. Event classes can also be enumerated from stream classes,
61 providing the user with references to the individual event classes.
62
63 Conversely, the user could also hold a reference to an event class and
64 retrieve its parent stream class. The trace class, in turn, can then be
65 retrieved from the stream class.
66
67 This example illustrates what could be interpreted as a circular
68 reference dependency existing between these objects. Of course, if the
69 objects in such a scenario were to hold references to each other (in
70 both directions), we would be in presence of a circular ownership
71 resulting in a leak of both objects as their reference counts would
72 never reach zero.
73
74 Nonetheless, the API must offer the guarantee that holding a node to any
75 node of the graph keeps all other reachable nodes alive.
76
77 ==== The solution
78
79 The scheme employed in {bt2} to break this cycle consists in the
80 "children" holding _reverse component references_ to their parents. That
81 is, in the context of the trace IR, that event classes hold a reference
82 to their parent stream class and stream classes hold a reference to
83 their parent trace class.
84
85 On the other hand, parents hold _claiming aggregation references_ to
86 their children. A claiming aggregation reference means that the object
87 being referenced should not be deleted as long as the reference still
88 exists. In this respect, it can be said that parents truly hold the
89 ownership of their children, since they control their lifetime.
90 Conversely, the reference counting mechanism is leveraged by children to
91 notify parents that no other child indirectly exposes the parent.
92
93 When a parented object's reference count reaches zero, it invokes
94 `+bt_*_put_ref()+` on its parent and does _not_ free itself. However,
95 from that point, the object depends on its parent to signal the moment
96 when it can be safely reclaimed.
97
98 The invocation of `+bt_*_put_ref()+` by the last children holding a
99 reference to its parent might trigger a cascade of `+bt_*_put_ref()+`
100 from child to parent. Eventually, a **root** object is reached. At that
101 point, if this orphaned object's reference count reaches zero, the
102 object invokes the destructor method defined by everyone of its children
103 as part of their base `struct bt_object`. The key point here is that the
104 cascade of destructor will necessarily originate from the root and
105 propagate in preorder to the children. These children will propagate the
106 destruction to their own children before reclaiming their own memory.
107 This ensures that a node's pointer to its parent is _always_ valid since
108 the parent has the responsibility of tearing-down their children before
109 cleaning themselves up.
110
111 Assuming a reference to an object is _acquired_ by calling
112 `+bt_*_get_ref()+` while its reference count is zero, the object
113 acquires, in turn, a reference on its parent using `+bt_*_get_ref()+`.
114 At that point, the child can be thought of as having converted its weak
115 reference to its parent into a regular reference. That is why this
116 reference is referred to as a _claiming_ aggregation reference.
117
118 ==== Caveats
119
120 This scheme imposes a number of strict rules defining the relation
121 between objects:
122
123 * Objects may only have one parent.
124 * Objects, beside the root, are only retrievable from their direct
125 parent or children.
126
127 ==== Example
128
129 The initial situation is rather simple: **User{nbsp}A** is holding a
130 reference to a trace class, **TC1**. As per the rules previously
131 enounced, stream classes **SC1** and **SC2** don't hold a reference to
132 **TC1** since their own reference counts are zero. The same holds true
133 for **EC1**, **EC2** and **EC3** with respect to **SC1** and **SC2**.
134
135 image::doc/contributing-images/bt-ref01.png[]
136
137 In this second step, we can see that **User{nbsp}A** has acquired a
138 reference on **SC2** through the trace class, **TC1**.
139
140 The stream class's reference count transitions from zero to one,
141 triggering the acquisition of a strong reference on **TC1** from
142 **SC2**.
143
144 Hence, at this point, the trace class's ownership is shared by
145 **User{nbsp}A** and **SC2**.
146
147 image::doc/contributing-images/bt-ref02.png[]
148
149 Next, **User{nbsp}A** acquires a reference on the **EC3** event class
150 through its parent stream class, **SC2**. Again, the transition of an
151 object's reference count from 0 to 1 triggers the acquisition of a
152 reference on its parent.
153
154 Note that SC2's reference count was incremented to 2. The trace class's
155 reference count remains unchanged.
156
157 image::doc/contributing-images/bt-ref03.png[]
158
159 **User{nbsp}A** decides to drop its reference on **SC2**. **SC2**'s
160 reference count returns back to 1, everything else remaining unchanged.
161
162 image::doc/contributing-images/bt-ref04.png[]
163
164 **User{nbsp}A** can then decide to drop its reference on the trace
165 class. This results in a reversal of the initial situation:
166 **User{nbsp}A** now owns an event, **EC3**, which is keeping everything
167 else alive and reachable.
168
169 image::doc/contributing-images/bt-ref05.png[]
170
171 If another object, **User{nbsp}B**, enters the picture and acquires a
172 reference on the **SC1** stream class, we see that **SC1**'s reference
173 count transitioned from 0 to 1, triggering the acquisition of a
174 reference on **TC1**.
175
176 image::doc/contributing-images/bt-ref06.png[]
177
178 **User{nbsp}B** hands off a reference to **EC1**, acquired through
179 **SC1**, to another object, **User{nbsp}C**. The acquisition of a
180 reference on **EC1**, which transitions from 0 to 1, triggers the
181 acquisition of a reference on its parent, **SC1**.
182
183 image::doc/contributing-images/bt-ref07.png[]
184
185 At some point, **User{nbsp}A** releases its reference on **EC3**. Since
186 **EC3**'s reference count transitions to zero, it releases its reference
187 on **SC2**. **SC2**'s reference count, in turn, reaches zero and it
188 releases its reference to **TC1**.
189
190 **TC1**'s reference count is now 1 and no further action is taken.
191
192 image::doc/contributing-images/bt-ref08.png[]
193
194 **User{nbsp}B** releases its reference on **SC1**. **User{nbsp}C**
195 becomes the sole owner of the whole hierarchy through his ownership of
196 **EC1**.
197
198 image::doc/contributing-images/bt-ref09.png[]
199
200 Finally, **User{nbsp}C** releases his ownership of **EC1**, triggering
201 the release of the whole hierarchy. Let's walk through the reclamation
202 of the whole graph.
203
204 Mirroring what happened when **User{nbsp}A** released its last reference
205 on **EC3**, the release of **EC1** by **User{nbsp}C** causes its
206 reference count to fall to zero.
207
208 This transition to zero causes **EC1** to release its reference on
209 **SC1**. **SC1**'s reference count reaching zero causes it to release
210 its reference on **TC1**.
211
212 image::doc/contributing-images/bt-ref10.png[]
213
214 Since the reference count of **TC1**, a root object, has reached zero,
215 it invokes the destructor method on its children. This method is
216 recursive and causes the stream classes to call the destructor method on
217 their event classes.
218
219 The event classes are reached and, having no children of their own, are
220 reclaimed.
221
222 image::doc/contributing-images/bt-ref11.png[]
223
224 The stream classes having destroyed their children, are then reclaimed
225 by the trace class.
226
227 image::doc/contributing-images/bt-ref12.png[]
228
229 Finally, the stream classes having been reclaimed, **TC1** is reclaimed.
230
231 image::doc/contributing-images/bt-ref13.png[]
232
233
234 == Logging
235
236 Logging is a great instrument for a developer to be able to collect
237 information about a running software.
238
239 {bt2} is a complex software with many layers. When a {bt2}
240 graph fails to run, what caused the failure? It could be caused by any
241 component, any message iterator, and any deeply nested validation of a
242 CTF IR object (within the `ctf` plugin), for example. With the
243 appropriate logging statements manually placed in the source code, we
244 can find the cause of a bug faster.
245
246 While <<choose-a-log-level,care must be taken>> when placing _DEBUG_ to
247 _FATAL_ logging statements, you should liberally instrument your
248 {bt2} module with _TRACE_ logging statements to help future you
249 and other developers understand what's happening at run time.
250
251 === Logging API
252
253 The {bt2} logging API is internal: it is not exposed to the users
254 of the library; only to their developers. The only thing that a library
255 user can control is the current log level of the library itself with
256 `bt_logging_set_global_level()` and the initial library's log level with
257 the `LIBBABELTRACE2_INIT_LOG_LEVEL` environment variable.
258
259 This API is based on https://github.com/wonder-mice/zf_log[zf_log], a
260 lightweight, yet featureful, MIT-licensed core logging library for C and
261 {cpp}. The zf_log source files were modified to have the `BT_` and
262 `bt_` prefixes, and other small changes, like color support and using
263 the project's `BT_DEBUG_MODE` definition instead of the standard
264 `NDEBUG`.
265
266 The logging functions are implemented in the logging convenience
267 library (`src/logging` directory).
268
269 [[logging-headers]]
270 ==== Headers
271
272 The logging API headers are:
273
274 `<babeltrace2/logging.h>`::
275 Public header which a library user can use to set and get
276 libbabeltrace2's current log level.
277
278 `"logging/log.h"`::
279 Internal, generic logging API which you can use in any {bt2}
280 module. This is the translation of `zf_log.h`.
281 +
282 This header offers the <<gen-logging-statements,generic logging
283 statement macros>>.
284
285 `"lib/logging.h"`::
286 Specific internal header to use within the library.
287 +
288 This header defines `BT_LOG_OUTPUT_LEVEL` to a custom, library-wide
289 hidden symbol which is the library's current log level before including
290 `"logging/log.h"`.
291 +
292 This header offers the <<lib-logging-statements,library-specific logging
293 statement macros>>.
294
295 `"logging/comp-logging.h"`::
296 Specific internal header to use within a component class.
297 +
298 This header offers the <<comp-logging-statements,component-specific
299 logging statement macros>>.
300
301 [[log-levels]]
302 ==== Log levels
303
304 The internal logging API offers the following log levels, in ascending
305 order of severity:
306
307 [options="header,autowidth",cols="4"]
308 |===
309 |Log level name
310 |Log level short name
311 |Internal API enumerator
312 |Public API enumerator
313
314 |_TRACE_
315 |`T`
316 |`BT_LOG_TRACE`
317 |`BT_LOGGING_LEVEL_TRACE`
318
319 |_DEBUG_
320 |`D`
321 |`BT_LOG_DEBUG`
322 |`BT_LOGGING_LEVEL_DEBUG`
323
324 |_INFO_
325 |`I`
326 |`BT_LOG_INFO`
327 |`BT_LOGGING_LEVEL_INFO`
328
329 |_WARNING_
330 |`W`
331 |`BT_LOG_WARNING`
332 |`BT_LOGGING_LEVEL_WARNING`
333
334 |_ERROR_
335 |`E`
336 |`BT_LOG_ERROR`
337 |`BT_LOGGING_LEVEL_ERROR`
338
339 |_FATAL_
340 |`F`
341 |`BT_LOG_FATAL`
342 |`BT_LOGGING_LEVEL_FATAL`
343
344 |_NONE_
345 |`N`
346 |`BT_LOG_NONE`
347 |`BT_LOGGING_LEVEL_NONE`
348 |===
349
350 The short name is accepted by the log level environment variables and by
351 the CLI's `--log-level` options.
352
353 See <<choose-a-log-level,how to decide which one to use>> below.
354
355 There are two important log level expressions:
356
357 [[build-time-log-level]]Build-time, minimal log level::
358 The minimal log level, or build-time log level, is set at build time
359 and determines the minimal log level of the logging statements which
360 can be executed. This applies to all the modules (CLI, library,
361 plugins, bindings, etc.).
362 +
363 All the logging statements with a level below this level are **not built
364 at all**. All the logging statements with a level equal to or greater
365 than this level _can_ be executed, depending on the
366 <<run-time-log-level,run-time log level>>.
367 +
368 You can set this level at configuration time with the
369 `BABELTRACE_MINIMAL_LOG_LEVEL` environment variable, for example:
370 +
371 --
372 ----
373 $ BABELTRACE_MINIMAL_LOG_LEVEL=INFO ./configure
374 ----
375 --
376 +
377 The default build-time log level is `DEBUG`. For optimal performance,
378 set it to `INFO`, which effectively disables all fast path logging in
379 all the {bt2} modules. You can't set it to `WARNING`, `ERROR`,
380 `FATAL`, or `NONE` because the impact on performance is minuscule
381 starting from the _INFO_ log level anyway and we want any {bt2}
382 build to always be able to print _INFO_-level logs.
383 +
384 The library's public API provides `bt_logging_get_minimal_level()` to
385 get the configured minimal log level.
386
387 [[run-time-log-level]]Run-time, dynamic log level::
388 The dynamic log level is set at run time and determines the current,
389 _active_ log level. All the logging statements with a level below
390 this level are not executed, **but they still evaluate the
391 condition**. All the logging statements with a level equal to or
392 greater than this level are executed, provided that their level is
393 also <<build-time-log-level,enabled at build time>>.
394 +
395 `zf_log` has a concept of a global run-time log level which uses the
396 `_bt_log_global_output_lvl` symbol. In practice, we never use this
397 symbol, and always make sure that `BT_LOG_OUTPUT_LEVEL` is defined to a
398 module-wise expression before including `"logging/log.h"`.
399 +
400 In the library, `"lib/logging.h"` defines its own
401 `BT_LOG_OUTPUT_LEVEL` to the library's log level symbol before it
402 includes `"logging/log.h"` itself.
403 +
404 In libbabeltrace2, the user can set the current run-time log level with
405 the `bt_logging_set_global_level()` function, for example:
406 +
407 --
408 [source,c]
409 ----
410 bt_logging_set_global_level(BT_LOGGING_LEVEL_INFO);
411 ----
412 --
413 +
414 The library's initial run-time log level is defined by the
415 `LIBBABELTRACE2_INIT_LOG_LEVEL` environment variable, or set to _NONE_
416 if this environment variable is undefined.
417 +
418 Other modules have their own way of setting their run-time log level.
419 +
420 For example, the CLI uses the `BABELTRACE_CLI_LOG_LEVEL` environment
421 variable, as well as its global `--log-level` option:
422 +
423 ----
424 $ babeltrace2 --log-level=I ...
425 ----
426 +
427 The components use their own log level (as returned by
428 `bt_component_get_logging_level()`). With the CLI, you can set a
429 specific component's log level with its own, position-dependent
430 `--log-level` option:
431 +
432 ----
433 $ babeltrace2 /path/to/trace -c sink.ctf.fs --log-level=D
434 ----
435 +
436 Code which is common to the whole project, for example `src/common`
437 and `src/compat`, use function parameters to get its run-time log
438 level, for example:
439 +
440 [source,c]
441 ----
442 char *bt_common_get_home_plugin_path(int log_level);
443 ----
444 +
445 Typically, when a logging-enabled module calls such a function, it
446 passes its own log level expression directly (`BT_LOG_OUTPUT_LEVEL`):
447 +
448 [source,c]
449 ----
450 path = bt_common_get_home_plugin_path(BT_LOG_OUTPUT_LEVEL);
451 ----
452 +
453 Otherwise, just pass `BT_LOG_NONE`:
454 +
455 ----
456 path = bt_common_get_home_plugin_path(BT_LOG_NONE);
457 ----
458
459 [[gen-logging-statements]]
460 ==== Generic logging statement macros
461
462 The {bt2} logging statement macros work just like `printf()`
463 (except the `+BT_LOG*_STR()+` ones) and contain their <<log-levels,log
464 level>> (short name) in their name.
465
466 Each of the following macros evaluate the
467 <<build-time-log-level,build-time log level>> definition and
468 <<run-time-log-level,run-time log level>> expression (as defined by
469 `BT_LOG_OUTPUT_LEVEL`) to log conditionally.
470
471 See <<logging-instrument-c-file-gen>> and
472 <<logging-instrument-h-file-gen>> to learn how to be able to use the
473 following macros.
474
475 `+BT_LOGT("format string", ...)+`::
476 Generic trace logging statement.
477
478 `+BT_LOGD("format string", ...)+`::
479 Generic debug logging statement.
480
481 `+BT_LOGI("format string", ...)+`::
482 Generic info logging statement.
483
484 `+BT_LOGW("format string", ...)+`::
485 Generic warning logging statement.
486
487 `+BT_LOGE("format string", ...)+`::
488 Generic error logging statement.
489
490 `+BT_LOGF("format string", ...)+`::
491 Generic fatal logging statement.
492
493 `+BT_LOGT_STR("preformatted string")+`::
494 Generic preformatted string trace logging statement.
495
496 `+BT_LOGD_STR("preformatted string")+`::
497 Generic preformatted string debug logging statement.
498
499 `+BT_LOGI_STR("preformatted string")+`::
500 Generic preformatted string info logging statement.
501
502 `+BT_LOGW_STR("preformatted string")+`::
503 Generic preformatted string warning logging statement.
504
505 `+BT_LOGE_STR("preformatted string")+`::
506 Generic preformatted string error logging statement.
507
508 `+BT_LOGF_STR("preformatted string")+`::
509 Generic preformatted string fatal logging statement.
510
511 `+BT_LOGT_MEM(data_ptr, data_size, "format string", ...)+`::
512 Generic memory trace logging statement.
513
514 `+BT_LOGD_MEM(data_ptr, data_size, "format string", ...)+`::
515 Generic memory debug logging statement.
516
517 `+BT_LOGI_MEM(data_ptr, data_size, "format string", ...)+`::
518 Generic memory info logging statement.
519
520 `+BT_LOGW_MEM(data_ptr, data_size, "format string", ...)+`::
521 Generic memory warning logging statement.
522
523 `+BT_LOGE_MEM(data_ptr, data_size, "format string", ...)+`::
524 Generic memory error logging statement.
525
526 `+BT_LOGF_MEM(data_ptr, data_size, "format string", ...)+`::
527 Generic memory fatal logging statement.
528
529 `+BT_LOGT_ERRNO("initial message", "format string", ...)+`::
530 Generic `errno` string trace logging statement.
531
532 `+BT_LOGD_ERRNO("initial message", "format string", ...)+`::
533 Generic `errno` string debug logging statement.
534
535 `+BT_LOGI_ERRNO("initial message", "format string", ...)+`::
536 Generic `errno` string info logging statement.
537
538 `+BT_LOGW_ERRNO("initial message", "format string", ...)+`::
539 Generic `errno` string warning logging statement.
540
541 `+BT_LOGE_ERRNO("initial message", "format string", ...)+`::
542 Generic `errno` string error logging statement.
543
544 `+BT_LOGF_ERRNO("initial message", "format string", ...)+`::
545 Generic `errno` string fatal logging statement.
546
547 [[lib-logging-statements]]
548 ==== Library-specific logging statement macros
549
550 The {bt2} library contains an internal logging API based on the
551 generic logging framework. You can use it to log known {bt2}
552 objects without having to manually log each member.
553
554 See <<logging-instrument-c-file-lib>>
555 and <<logging-instrument-h-file-lib>> to
556 learn how to be able to use the following macros.
557
558 The library logging statement macros are named `+BT_LIB_LOG*()+` instead
559 of `+BT_LOG*()+`:
560
561 `+BT_LIB_LOGT("format string", ...)+`::
562 Library trace logging statement.
563
564 `+BT_LIB_LOGD("format string", ...)+`::
565 Library debug logging statement.
566
567 `+BT_LIB_LOGI("format string", ...)+`::
568 Library info logging statement.
569
570 `+BT_LIB_LOGW("format string", ...)+`::
571 Library warning logging statement.
572
573 `+BT_LIB_LOGE("format string", ...)+`::
574 Library error logging statement.
575
576 `+BT_LIB_LOGF("format string", ...)+`::
577 Library fatal logging statement.
578
579 `+BT_LIB_LOGW_APPEND_CAUSE("format string", ...)+`::
580 Library warning logging statement, and unconditional error cause
581 appending.
582
583 `+BT_LIB_LOGE_APPEND_CAUSE("format string", ...)+`::
584 Library error logging statement, and unconditional error cause
585 appending.
586
587 The macros above accept the typical `printf()` conversion specifiers
588 with the following limitations:
589
590 * The `+*+` width specifier is not accepted.
591 * The `+*+` precision specifier is not accepted.
592 * The `j` and `t` length modifiers are not accepted.
593 * The `n` format specifier is not accepted.
594 * The format specifiers defined in `<inttypes.h>` are not accepted,
595 except for `PRId64`, `PRIu64`, `PRIx64`, `PRIX64`, `PRIo64`, and
596 `PRIi64`.
597
598 The {bt2} library custom conversion specifier is accepted. Its
599 syntax is either `%!u` to format a UUID (`bt_uuid` type), or:
600
601 . Introductory `%!` sequence.
602
603 . **Optional**: `[` followed by a custom prefix for the printed fields
604 of this specifier, followed by `]`. The standard form is to end this
605 prefix with `-` so that, for example, with the prefix `tc-`, the
606 complete field name becomes `tc-addr`.
607
608 . **Optional**: `pass:[+]` to print extended object members. This
609 depends on the provided format specifier.
610
611 . Format specifier (see below).
612
613 The available format specifiers are:
614
615 [options="header,autowidth",cols="3"]
616 |===
617 |Specifier
618 |Object
619 |Expected C type
620
621 |`F`
622 |Trace IR field class
623 |`+const struct bt_field_class *+`
624
625 |`f`
626 |Trace IR field
627 |`+const struct bt_field *+`
628
629 |`P`
630 |Trace IR field path
631 |`+const struct bt_field_path *+`
632
633 |`E`
634 |Trace IR event class
635 |`+const struct bt_event_class *+`
636
637 |`e`
638 |Trace IR event
639 |`+const struct bt_event *+`
640
641 |`S`
642 |Trace IR stream class.
643 |`+const struct bt_stream_class *+`
644
645 |`s`
646 |Trace IR stream
647 |`+const struct bt_stream *+`
648
649 |`a`
650 |Trace IR packet
651 |`+const struct bt_packet *+`
652
653 |`T`
654 |Trace IR trace class
655 |`+const struct bt_trace_class *+`
656
657 |`t`
658 |Trace IR trace
659 |`+const struct bt_trace *+`
660
661 |`K`
662 |Trace IR clock class
663 |`+const struct bt_clock_class *+`
664
665 |`k`
666 |Trace IR clock snapshot
667 |`+const struct bt_clock_snapshot *+`
668
669 |`v`
670 |Value object
671 |`+const struct bt_value *+`
672
673 |`R`
674 |Integer range set
675 |`const struct bt_integer_range_set *`
676
677 |`n`
678 |Message
679 |`+const struct bt_message *+`
680
681 |`I`
682 |Message iterator class
683 |`struct bt_message_iterator_class *`
684
685 |`i`
686 |Message iterator
687 |`struct bt_message_iterator *`
688
689 |`C`
690 |Component class
691 |`struct bt_component_class *`
692
693 |`c`
694 |Component
695 |`+const struct bt_component *+`
696
697 |`p`
698 |Port
699 |`+const struct bt_port *+`
700
701 |`x`
702 |Connection
703 |`+const struct bt_connection *+`
704
705 |`g`
706 |Graph
707 |`+const struct bt_graph *+`
708
709 |`z`
710 |Interrupter
711 |`+struct bt_interrupter *+`
712
713 |`l`
714 |Plugin
715 |`+const struct bt_plugin *+`
716
717 |`r`
718 |Error cause
719 |`+const struct bt_error_cause *+`
720
721 |`o`
722 |Object pool
723 |`+const struct bt_object_pool *+`
724
725 |`O`
726 |Object
727 |`+const struct bt_object *+`
728 |===
729
730 Conversion specifier examples:
731
732 * `%!f`
733 * `%![my-event-]+e`
734 * `%!t`
735 * `%!+F`
736
737 The ``, `` string (comma and space) is printed between individual
738 fields, but **not after the last one**. Therefore, you must put this
739 separator in the format string between two conversion specifiers, for
740 example:
741
742 [source,c]
743 ----
744 BT_LIB_LOGW("Message: count=%u, %!E, %!+K", count, event_class, clock_class);
745 ----
746
747 Example with a custom prefix:
748
749 [source,c]
750 ----
751 BT_LIB_LOGI("Some message: %![ec-a-]e, %![ec-b-]+e", ec_a, ec_b);
752 ----
753
754 It is safe to pass `NULL` as any {bt2} object parameter: the macros
755 only print its null address.
756
757 WARNING: Build-time `printf()` format checks are disabled for the
758 `+BT_LIB_LOG*()+` macros because there are custom conversion specifiers,
759 so make sure to test your logging statements.
760
761 [[comp-logging-statements]]
762 ==== Component-specific logging statement macros
763
764 There are available logging macros for components. They prepend a prefix
765 including the component's name to the logging message.
766
767 See <<logging-instrument-c-file-compcls>> and
768 <<logging-instrument-h-file-compcls>> to learn how to be able to use the
769 following macros.
770
771 The component logging statement macros are named `+BT_COMP_LOG*()+`
772 instead of `+BT_LOG*()+`:
773
774 `+BT_COMP_LOGT("format string", ...)+`::
775 Component trace logging statement.
776
777 `+BT_COMP_LOGD("format string", ...)+`::
778 Component debug logging statement.
779
780 `+BT_COMP_LOGI("format string", ...)+`::
781 Component info logging statement.
782
783 `+BT_COMP_LOGW("format string", ...)+`::
784 Component warning logging statement.
785
786 `+BT_COMP_LOGE("format string", ...)+`::
787 Component error logging statement.
788
789 `+BT_COMP_LOGF("format string", ...)+`::
790 Component fatal logging statement.
791
792 `+BT_COMP_LOGT_STR("preformatted string")+`::
793 Component preformatted string trace logging statement.
794
795 `+BT_COMP_LOGD_STR("preformatted string")+`::
796 Component preformatted string debug logging statement.
797
798 `+BT_COMP_LOGI_STR("preformatted string")+`::
799 Component preformatted string info logging statement.
800
801 `+BT_COMP_LOGW_STR("preformatted string")+`::
802 Component preformatted string warning logging statement.
803
804 `+BT_COMP_LOGE_STR("preformatted string")+`::
805 Component preformatted string error logging statement.
806
807 `+BT_COMP_LOGF_STR("preformatted string")+`::
808 Component preformatted string fatal logging statement.
809
810 `+BT_COMP_LOGT_ERRNO("initial message", "format string", ...)+`::
811 Component `errno` string trace logging statement.
812
813 `+BT_COMP_LOGD_ERRNO("initial message", "format string", ...)+`::
814 Component `errno` string debug logging statement.
815
816 `+BT_COMP_LOGI_ERRNO("initial message", "format string", ...)+`::
817 Component `errno` string info logging statement.
818
819 `+BT_COMP_LOGW_ERRNO("initial message", "format string", ...)+`::
820 Component `errno` string warning logging statement.
821
822 `+BT_COMP_LOGE_ERRNO("initial message", "format string", ...)+`::
823 Component `errno` string error logging statement.
824
825 `+BT_COMP_LOGF_ERRNO("initial message", "format string", ...)+`::
826 Component `errno` string fatal logging statement.
827
828 `+BT_COMP_LOGT_MEM(data_ptr, data_size, "format string", ...)+`::
829 Component memory trace logging statement.
830
831 `+BT_COMP_LOGD_MEM(data_ptr, data_size, "format string", ...)+`::
832 Component memory debug logging statement.
833
834 `+BT_COMP_LOGI_MEM(data_ptr, data_size, "format string", ...)+`::
835 Component memory info logging statement.
836
837 `+BT_COMP_LOGW_MEM(data_ptr, data_size, "format string", ...)+`::
838 Component memory warning logging statement.
839
840 `+BT_COMP_LOGE_MEM(data_ptr, data_size, "format string", ...)+`::
841 Component memory error logging statement.
842
843 `+BT_COMP_LOGF_MEM(data_ptr, data_size, "format string", ...)+`::
844 Component memory fatal logging statement.
845
846 ==== Conditional logging
847
848 `+BT_LOG_IF(cond, statement)+`::
849 Execute `statement` only if `cond` is true.
850 +
851 Example:
852 +
853 --
854 [source,c]
855 ----
856 BT_LOG_IF(i < count / 2, BT_LOGD("Log this: i=%d", i));
857 ----
858 --
859
860 To check the <<build-time-log-level,build-time log level>>:
861
862 [source,c]
863 ----
864 #if BT_LOG_ENABLED_DEBUG
865 ...
866 #endif
867 ----
868
869 This tests if the _DEBUG_ level was enabled at build time. This means
870 that the current, <<run-time-log-level,run-time log level>> _could_ be
871 _DEBUG_, but it could also be higher. The rule of thumb is to use only
872 logging statements at the same level in a `BT_LOG_ENABLED_*` conditional
873 block.
874
875 The available definitions for build-time conditions are:
876
877 * `BT_LOG_ENABLED_TRACE`
878 * `BT_LOG_ENABLED_DEBUG`
879 * `BT_LOG_ENABLED_INFO`
880 * `BT_LOG_ENABLED_WARNING`
881 * `BT_LOG_ENABLED_ERROR`
882 * `BT_LOG_ENABLED_FATAL`
883
884 To check the current, <<run-time-log-level,run-time log level>>:
885
886 [source,c]
887 ----
888 if (BT_LOG_ON_DEBUG) {
889 ...
890 }
891 ----
892
893 This tests if the _DEBUG_ log level is dynamically turned on
894 (implies that it's also enabled at build time). This check could have a
895 noticeable impact on performance.
896
897 The available definitions for run-time conditions are:
898
899 * `BT_LOG_ON_TRACE`
900 * `BT_LOG_ON_DEBUG`
901 * `BT_LOG_ON_INFO`
902 * `BT_LOG_ON_WARNING`
903 * `BT_LOG_ON_ERROR`
904 * `BT_LOG_ON_FATAL`
905
906 Those macros check the module-specific log level symbol (defined by
907 `BT_LOG_OUTPUT_LEVEL`).
908
909 Never, ever write code which would be executed only to compute the
910 fields of a logging statement outside a conditional logging scope,
911 for example:
912
913 [source,c]
914 ----
915 int number = get_number_of_event_classes_with_property_x(...);
916 BT_LOGD("Bla bla: number=%d", number);
917 ----
918
919 Do this instead:
920
921 [source,c]
922 ----
923 if (BT_LOG_ON_DEBUG) {
924 int number = get_number_of_event_classes_with_property_x(...);
925 BT_LOGD("Bla bla: number=%d", number);
926 }
927 ----
928
929 Or even this:
930
931 [source,c]
932 ----
933 BT_LOGD("Bla bla: number=%d", get_number_of_event_classes_with_property_x(...));
934 ----
935
936 === Guides
937
938 [[logging-instrument-c-file-gen]]
939 ==== Instrument a {c-cpp} source file (generic)
940
941 To instrument a {c-cpp} source file (`.c`/`.cpp`):
942
943 . At the top of the file, before the first `#include` line (if any),
944 define your file's <<choose-a-logging-tag,logging tag>> name:
945 +
946 --
947 [source,c]
948 ----
949 #define BT_LOG_TAG "SUBSYS/MY-MODULE/MY-FILE"
950 ----
951 --
952
953 . Below the line above, define the source file's log level expression,
954 `BT_LOG_OUTPUT_LEVEL`. This expression is evaluated for each
955 <<gen-logging-statements,logging statement>> to know the current
956 <<run-time-log-level,run-time log level>>.
957 +
958 Examples:
959 +
960 [source,c]
961 ----
962 /* Global log level variable */
963 #define BT_LOG_OUTPUT_LEVEL module_global_log_level
964 ----
965 +
966 [source,c]
967 ----
968 /* Local log level variable; must exist where you use BT_LOG*() */
969 #define BT_LOG_OUTPUT_LEVEL log_level
970 ----
971 +
972 [source,c]
973 ----
974 /* Object's log level; `obj` must exist where you use BT_LOG*() */
975 #define BT_LOG_OUTPUT_LEVEL (obj->log_level)
976 ----
977
978 . Include `"logging/log.h"`:
979 +
980 [source,c]
981 ----
982 #include "logging/log.h"
983 ----
984
985 . In the file, instrument your code with the
986 <<gen-logging-statements,generic logging statement macros>>.
987
988 [[logging-instrument-h-file-gen]]
989 ==== Instrument a {c-cpp} header file (generic)
990
991 To instrument a {c-cpp} header file (`.h`/`.hpp`), if you have
992 `static inline` functions in it:
993
994 . Do not include `"logging/log.h"`!
995
996 . Do one of:
997
998 .. In the file, instrument your code with the
999 <<gen-logging-statements,generic logging statement macros>>, making
1000 each of them conditional to the existence of the macro you're using:
1001 +
1002 [source,c]
1003 ----
1004 static inline
1005 int some_function(int x)
1006 {
1007 /* ... */
1008
1009 #ifdef BT_LOGT
1010 BT_LOGT(...);
1011 #endif
1012
1013 /* ... */
1014
1015 #ifdef BT_LOGW_STR
1016 BT_LOGW_STR(...);
1017 #endif
1018
1019 /* ... */
1020 }
1021 ----
1022 +
1023 The {c-cpp} source files which include this header file determine if
1024 logging is enabled or not for them, and if so, what is their
1025 <<choose-a-logging-tag,logging tag>> and <<run-time-log-level,run-time
1026 log level>> expression.
1027
1028 .. Require that logging be enabled:
1029 +
1030 [source,c]
1031 ----
1032 /* Protection: this file uses BT_LOG*() macros directly */
1033 #ifndef BT_LOG_SUPPORTED
1034 # error Please include "logging/log.h" before including this file.
1035 #endif
1036 ----
1037 +
1038 Then, in the file, instrument your code with the
1039 <<gen-logging-statements,generic logging statement macros>>.
1040
1041 [[logging-instrument-c-file-lib]]
1042 ==== Instrument a library {c-cpp} source file
1043
1044 To instrument a library {c-cpp} source file (`.c`/`.cpp`):
1045
1046 . At the top of the file, before the first `#include` line (if any),
1047 define your file's <<choose-a-logging-tag,logging tag>> name (this
1048 tag must start with `LIB/`):
1049 +
1050 --
1051 [source,c]
1052 ----
1053 #define BT_LOG_TAG "LIB/THE-FILE"
1054 ----
1055 --
1056
1057 . Include `"lib/logging.h"`:
1058 +
1059 [source,c]
1060 ----
1061 #include "lib/logging.h"
1062 ----
1063
1064 . In the file, instrument your code with the
1065 <<lib-logging-statements,library logging statement macros>> or with
1066 the <<gen-logging-statements,generic logging statement macros>>.
1067
1068 [[logging-instrument-h-file-lib]]
1069 ==== Instrument a library {c-cpp} header file
1070
1071 To instrument a library {c-cpp} header file (`.h`/`.hpp`), if you have
1072 `static inline` functions in it:
1073
1074 . Do not include `"lib/logging.h"`!
1075
1076 . Require that library logging be enabled:
1077 +
1078 [source,c]
1079 ----
1080 /* Protection: this file uses BT_LIB_LOG*() macros directly */
1081 #ifndef BT_LIB_LOG_SUPPORTED
1082 # error Please include "lib/logging.h" before including this file.
1083 #endif
1084 ----
1085
1086 . In the file, instrument your code with the
1087 <<lib-logging-statements,library logging statement macros>> or with
1088 the <<gen-logging-statements,generic logging statement macros>>.
1089
1090 [[logging-instrument-c-file-compcls]]
1091 ==== Instrument a component class {c-cpp} source file
1092
1093 To instrument a component class {c-cpp} source file (`.c`/`.cpp`):
1094
1095 . At the top of the file, before the first `#include` line (if any),
1096 define your file's <<choose-a-logging-tag,logging tag>> name (this tag
1097 must start with `PLUGIN/` followed by the component class identifier):
1098 +
1099 --
1100 [source,c]
1101 ----
1102 #define BT_LOG_TAG "PLUGIN/SRC.MY-PLUGIN.MY-SRC"
1103 ----
1104 --
1105
1106 . Below the line above, define the source file's log level expression,
1107 `BT_LOG_OUTPUT_LEVEL`. This expression is evaluated for each
1108 <<comp-logging-statements,logging statement>> to know the current
1109 <<run-time-log-level,run-time log level>>.
1110 +
1111 For a component class file, it is usually a member of a local component
1112 private structure variable:
1113 +
1114 [source,c]
1115 ----
1116 #define BT_LOG_OUTPUT_LEVEL (my_comp->log_level)
1117 ----
1118
1119 . Below the line above, define `BT_COMP_LOG_SELF_COMP` to an expression
1120 which, evaluated in the context of the
1121 <<comp-logging-statements,logging statements>>, evaluates to the self
1122 component address (`+bt_self_component *+`) of the component.
1123 +
1124 This is usually a member of a local component private structure
1125 variable:
1126 +
1127 [source,c]
1128 ----
1129 #define BT_COMP_LOG_SELF_COMP (my_comp->self_comp)
1130 ----
1131
1132 . Include `"logging/comp-logging.h"`:
1133 +
1134 [source,c]
1135 ----
1136 #include "logging/comp-logging.h"
1137 ----
1138
1139 . In the component initialization method, make sure to set the
1140 component private structure's log level member to the initial
1141 component's log level:
1142 +
1143 [source,c]
1144 ----
1145 struct my_comp {
1146 bt_logging_level log_level;
1147 /* ... */
1148 };
1149
1150 bt_self_component_status my_comp_init(
1151 bt_self_component_source *self_comp_src,
1152 bt_value *params, void *init_method_data)
1153 {
1154 struct my_comp *my_comp = g_new0(struct my_comp, 1);
1155 bt_self_component *self_comp =
1156 bt_self_component_source_as_self_component(self_comp_src);
1157 const bt_component *comp = bt_self_component_as_component(self_comp);
1158
1159 BT_ASSERT(my_comp);
1160 my_comp->log_level = bt_component_get_logging_level(comp);
1161
1162 /* ... */
1163 }
1164 ----
1165
1166 . In the file, instrument your code with the
1167 <<comp-logging-statements,component logging statement macros>>.
1168
1169 [[logging-instrument-h-file-compcls]]
1170 ==== Instrument a component class {c-cpp} header file
1171
1172 To instrument a component class {c-cpp} header file (`.h`/`.hpp`), if
1173 you have `static inline` functions in it:
1174
1175 . Do not include `"logging/comp-logging.h"`!
1176
1177 . Require that component logging be enabled:
1178 +
1179 [source,c]
1180 ----
1181 /* Protection: this file uses BT_COMP_LOG*() macros directly */
1182 #ifndef BT_COMP_LOG_SUPPORTED
1183 # error Please include "logging/comp-logging.h" before including this file.
1184 #endif
1185 ----
1186
1187 . In the file, instrument your code with the
1188 <<comp-logging-statements,component logging statement macros>>.
1189
1190 [[choose-a-logging-tag]]
1191 ==== Choose a logging tag
1192
1193 Each logging-enabled {c-cpp} source file must define `BT_LOG_TAG` to a
1194 logging tag. A logging tag is a namespace to identify the logging
1195 messages of this specific source file.
1196
1197 In general, a logging tag name _must_ be only uppercase letters, digits,
1198 and the `-`, `.`, and `/` characters.
1199
1200 Use `/` to show the subsystem to source file hierarchy.
1201
1202 For the {bt2} library, start with `LIB/`.
1203
1204 For the CTF writer library, start with `CTF-WRITER/`.
1205
1206 For component classes, use:
1207
1208 [verse]
1209 `PLUGIN/__CCTYPE__.__PNAME__.__CCNAME__[/__FILE__]`
1210
1211 With:
1212
1213 `__CCTYPE__`::
1214 Component class's type (`SRC`, `FLT`, or `SINK`).
1215
1216 `__PNAME__`::
1217 Plugin's name.
1218
1219 `__CCNAME__`::
1220 Component class's name.
1221
1222 `__FILE__`::
1223 Additional information to specify the source file name or module.
1224
1225 For plugins (files common to many component classes), use:
1226
1227 [verse]
1228 `PLUGIN/__PNAME__[/__FILE__]`
1229
1230 With:
1231
1232 `__PNAME__`::
1233 Plugin's name.
1234
1235 `__FILE__`::
1236 Additional information to specify the source file name or module.
1237
1238 [[choose-a-log-level]]
1239 ==== Choose a log level
1240
1241 Choosing the appropriate level for your logging statement is very
1242 important.
1243
1244 [options="header,autowidth",cols="1,2,3a,4"]
1245 |===
1246 |Log level |Description |Use cases |Expected impact on performance
1247
1248 |_FATAL_
1249 |
1250 The program, library, or plugin cannot continue to work in this
1251 condition: it must be terminated immediately.
1252
1253 A _FATAL_-level logging statement should always be followed by
1254 `abort()`.
1255 |
1256 * Unexpected return values from system calls.
1257 * Logic error in internal code, for example an unexpected value in a
1258 `switch` statement.
1259 * Failed assertion (within `BT_ASSERT()`).
1260 * Unsatisfied library precondition (within `BT_ASSERT_PRE()` or
1261 `BT_ASSERT_PRE_DEV()`).
1262 * Unsatisfied library postcondition (within `BT_ASSERT_POST()` or
1263 `BT_ASSERT_POST_DEV()`).
1264 |Almost none: always enabled.
1265
1266 |_ERROR_
1267 |
1268 An important error which is somewhat not fatal, that is, the program,
1269 library, or plugin can continue to work after this, but you judge that
1270 it should be reported to the user.
1271
1272 Usually, the program cannot recover from such an error, but it can at
1273 least exit cleanly.
1274 |
1275 * Memory allocation errors.
1276 * Wrong component initialization parameters.
1277 * Corrupted, unrecoverable trace data.
1278 * Failed to perform an operation which should work considering the
1279 implementation and the satisfied preconditions. For example, the
1280 failure to create an empty object (no parameters): most probably
1281 failed internally because of an allocation error.
1282 * Almost any error in terminal elements: CLI and plugins.
1283 |Almost none: always enabled.
1284
1285 |_WARNING_
1286 |
1287 An error which still allows the execution to continue, but you judge
1288 that it should be reported to the user.
1289
1290 _WARNING_-level logging statements are for any error or weird action
1291 that is directly or indirectly caused by the user, often through some
1292 bad input data. For example, not having enough memory is considered
1293 beyond the user's control, so we always log memory errors with an
1294 _ERROR_ level (not _FATAL_ because we usually don't abort in this
1295 condition).
1296 |
1297 * Missing data within something that is expected to have it, but there's
1298 an alternative.
1299 * Invalid file, but recoverable/fixable.
1300 |Almost none: always enabled.
1301
1302 |_INFO_
1303 |
1304 Any useful information which a non-developer user would possibly
1305 understand.
1306
1307 Anything logged with this level must _not_ happen repetitively on the
1308 fast path, that is, nothing related to each message, for example. This
1309 level is used for sporadic and one-shot events.
1310 |
1311 * CLI or component configuration report.
1312 * Successful plugin, component, or message iterator initialization.
1313 * In the library: anything related to plugins, graphs, component
1314 classes, components, message iterators, connections, and ports which
1315 is not on the fast path.
1316 * Successful connection to or disconnection from another system.
1317 * An _optional_ subsystem cannot be loaded.
1318 * An _optional_ field/datum cannot be found.
1319 |
1320 Very little: always enabled.
1321
1322 |_DEBUG_
1323 |
1324 Something that only {bt2} developers would be interested into,
1325 which can occur on the fast path, but not more often than once per
1326 message.
1327
1328 The _DEBUG_ level is the default <<build-time-log-level,build-time log
1329 level>> as, since it's not _too_ verbose, the performance is similar to
1330 an _INFO_ build.
1331 |
1332 * Object construction and destruction.
1333 * Object recycling (except fields).
1334 * Object copying (except fields and values).
1335 * Object freezing (whatever the type, as freezing only occurs in
1336 developer mode).
1337 * Object interruption.
1338 * Calling user methods and logging the result.
1339 * Setting object properties (except fields and values).
1340 |
1341 Noticeable, but not as much as the _TRACE_ level: could be executed
1342 in production if you're going to need a thorough log for support
1343 tickets without having to rebuild the project.
1344
1345 |_TRACE_
1346 |
1347 Low-level debugging context information (anything that does not fit the
1348 other log levels). More appropriate for tracing in general.
1349 |
1350 * Reference count change.
1351 * Fast path, low level state machine's state change.
1352 * Get or set an object's property.
1353 * Object comparison's intermediate results.
1354 |Huge: not executed in production.
1355 |===
1356
1357 [IMPORTANT]
1358 --
1359 Make sure not to use a _WARNING_ (or higher) log level when the
1360 condition leading to the logging statement can occur under normal
1361 circumstances.
1362
1363 For example, a public function to get some object or
1364 property from an object by name or key that fails to find the value is
1365 not a warning scenario: the user could legitimately use this function to
1366 check if the name/key exists in the object. In this case, use the
1367 _TRACE_ level (or do not log at all).
1368 --
1369
1370 [[message]]
1371 ==== Write an appropriate message
1372
1373 Follow those rules when you write a logging statement's message:
1374
1375 * Use an English sentence which starts with a capital letter.
1376
1377 * Start the sentence with the appropriate verb tense depending on the
1378 context. For example:
1379 +
1380 --
1381 ** Beginning of operation (present continuous): _Creating ..._,
1382 _Copying ..._, _Serializing ..._, _Freezing ..._, _Destroying ..._
1383 ** End of operation (simple past): _Created ..._, _Successfully created ..._,
1384 _Failed to create ..._, _Set ..._ (simple past of _to set_ which is
1385 also _set_)
1386 --
1387 +
1388 For warning and error messages, you can start the message with _Cannot_
1389 or _Failed to_ followed by a verb if it's appropriate.
1390
1391 * Do not include the log level in the message itself. For example,
1392 do not start the message with _Error while_ or _Warning:_.
1393
1394 * Do not put newlines, tabs, or other special characters in the message,
1395 unless you want to log a string with such characters. Note that
1396 multiline logging messages can be hard to parse, analyze, and filter,
1397 however, so prefer multiple logging statements over a single statement
1398 with newlines.
1399
1400 * **If there are fields that your logging statement must record**,
1401 follow the message with `:` followed by a space, then with the list of
1402 fields (more about this below). If there are no fields, end the
1403 sentence with a period.
1404
1405 The statement's fields _must_ be a comma-separated list of
1406 `__name__=__value__` tokens. Keep `__name__` as simple as possible; use
1407 kebab case if possible. If `__value__` is a non-alphanumeric string, put
1408 it between double quotes (`"%s"` specifier). Always use the `PRId64` and
1409 `PRIu64` specifiers to log an `int64_t` or an `uint64_t` value. Use `%d`
1410 to log a boolean value.
1411
1412 Example:
1413
1414 "Cannot read stream data for indexing: path=\"%s\", name=\"%s\", "
1415 "stream-id=%" PRIu64 ", stream-fd=%d, "
1416 "index=%" PRIu64 ", status=%s, is-mapped=%d"
1417
1418 By following a standard format for the statement fields, it is easier to
1419 use tools like https://www.elastic.co/products/logstash[Logstash] or
1420 even https://www.splunk.com/[Splunk] to split fields and analyze logs.
1421
1422 Prefer the following suffixes in field names:
1423
1424 [options="header,autowidth"]
1425 |===
1426 |Field name suffix |Description |Format specifier
1427
1428 |`-addr` |Memory address |`%p`
1429 |`-fd` |File descriptor |`%d`
1430 |`-fp` |File stream (`+FILE *+`) |`%p`
1431 |`-id` |Object's ID |`%" PRIu64 "`
1432 |`-index` |Index |`%" PRIu64 "`
1433 |`-name` |Object's name |`\"%s\"`
1434 |===
1435
1436 === Output
1437
1438 The log is printed to the standard error stream. A log line contains the
1439 time, the process and thread IDs, the <<log-levels,log level>>, the
1440 <<choose-a-logging-tag,logging tag>>, the source's function name, file
1441 name and line number, and the <<message,message>>.
1442
1443 When {bt2} supports terminal color codes (depends on the
1444 `BABELTRACE_TERM_COLOR` environment variable's value and what the
1445 standard output and error streams are plugged into), _INFO_-level lines
1446 are blue, _WARNING_-level lines are yellow, and _ERROR_-level and
1447 _FATAL_-level lines are red.
1448
1449 Log line example:
1450
1451 ----
1452 05-11 00:58:03.691 23402 23402 D VALUES bt_value_destroy@values.c:498 Destroying value: addr=0xb9c3eb0
1453 ----
1454
1455 You can easily filter the log with `grep` or `ag`. For example, to keep
1456 only the _DEBUG_-level logging messages that the `FIELD-CLASS` module
1457 generates:
1458
1459 ----
1460 $ babeltrace2 --log-level=D /path/to/trace |& ag 'D FIELD-CLASS'
1461 ----
1462
1463 == Valgrind
1464
1465 To use Valgrind on an application (for example, the CLI or a test) which
1466 loads libbabeltrace2, use:
1467
1468 ----
1469 $ G_SLICE=always-malloc G_DEBUG=gc-friendly PYTHONMALLOC=malloc \
1470 LIBBABELTRACE2_NO_DLCLOSE=1 valgrind --leak-check=full app
1471 ----
1472
1473 `G_SLICE=always-malloc` and `G_DEBUG=gc-friendly` is for GLib and
1474 `PYTHONMALLOC=malloc` is for the Python interpreter, if it is used by
1475 the Python plugin provider (Valgrind will probably show a lot of errors
1476 which originate from the Python interpreter anyway).
1477
1478 `LIBBABELTRACE2_NO_DLCLOSE=1` makes libbabeltrace2 not close the shared
1479 libraries (plugins) which it loads. You need this to see the appropriate
1480 backtrace when Valgrind shows errors.
1481
1482 == Testing
1483
1484 [[test-env]]
1485 === Environment
1486
1487 Running `make check` in the build directory (regardless of whether the build is
1488 in-tree or out-of-tree) automatically sets up the appropriate environment for
1489 tests to run in, so nothing more is needed.
1490
1491 If building in-tree, you can run single tests from the tree directly:
1492
1493 ----
1494 $ ./tests/plugins/sink.text.pretty/test_enum
1495 ----
1496
1497 If building out-of-tree, you can get the appropriate environment by sourcing
1498 the `tests/utils/env.sh` file residing in the build directory against which you
1499 want to run tests.
1500
1501 ----
1502 $ source /path/to/my/build/tests/utils/env.sh
1503 $ ./tests/plugins/sink.text.pretty/test_enum
1504 ----
1505
1506 ==== Python
1507
1508 You can use the `tests/utils/run_python_bt2` script to run any command
1509 within an environment making the build's `bt2` Python package available.
1510
1511 `run_python_bt2` uses <<test-env,`utils.sh`>> which needs to know the
1512 build directory, so make sure you set the `BT_TESTS_BUILDDIR`
1513 environment variable correctly _if you build out of tree_, for example:
1514
1515 ----
1516 $ export BT_TESTS_BUILDDIR=/path/to/build/babeltrace/tests
1517 ----
1518
1519 You can run any command which needs the `bt2` Python package through
1520 `run_python_bt2`, for example:
1521
1522 ----
1523 $ ./tests/utils/run_python_bt2 ipython3
1524 ----
1525
1526 === Report format
1527
1528 All test scripts output the test results following the
1529 https://testanything.org/[Test Anything Protocol] (TAP) format.
1530
1531 The TAP format has two mechanisms to print additional information about
1532 a test:
1533
1534 * Print a line starting with `#` to the standard output.
1535 +
1536 This is usually done with the `diag()` C function or the `diag` shell
1537 function.
1538
1539 * Print to the standard error.
1540
1541 === Python bindings
1542
1543 The `bt2` Python package tests are located in
1544 `tests/bindings/python/bt2`.
1545
1546 ==== Python test runner
1547
1548 `tests/utils/python/testrunner.py` is {bt2}'s Python test runner
1549 which loads Python files containing unit tests, finds all the test
1550 cases, and runs the tests, producing a TAP report.
1551
1552 You can see the test runner command's help with:
1553
1554 ----
1555 $ python3 ./tests/utils/python/testrunner.py --help
1556 ----
1557
1558 By default, the test runner reports failing tests (TAP's `not{nbsp}ok`
1559 line), but continues to run other tests. You can use the `--failfast`
1560 option to make the test runner fail as soon as a test fails.
1561
1562 ==== Guides
1563
1564 To run all the `bt2` Python package tests:
1565
1566 * Run:
1567 +
1568 ----
1569 $ ./tests/utils/run_python_bt2 ./tests/bindings/python/bt2/test_python_bt2
1570 ----
1571 +
1572 or:
1573 +
1574 ----
1575 $ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
1576 ./tests/bindings/python/bt2/ -p '*.py'
1577 ----
1578
1579 To run **all the tests** in a test module (for example,
1580 `test_value.py`):
1581
1582 * Run:
1583 +
1584 ----
1585 $ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
1586 ./tests/bindings/python/bt2 -t test_value
1587 ----
1588
1589 To run a **specific test case** (for example, `RealValueTestCase` within
1590 `test_value.py`):
1591
1592 * Run:
1593 +
1594 ----
1595 $ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
1596 ./tests/bindings/python/bt2/ -t test_value.RealValueTestCase
1597 ----
1598
1599 To run a **specific test** (for example,
1600 `RealValueTestCase.test_assign_pos_int` within `test_value.py`):
1601
1602 * Run:
1603 +
1604 ----
1605 $ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
1606 ./tests/bindings/python/bt2/ -t test_value.RealValueTestCase.test_assign_pos_int
1607 ----
1608
1609 == {cpp} usage
1610
1611 Some parts of {bt2} are written in {cpp}.
1612
1613 This section shows what's important to know about {cpp} to contribute
1614 to {bt2}.
1615
1616 [IMPORTANT]
1617 ====
1618 {bt2} only has {cpp} sources for _internal_ code.
1619
1620 In other words, libbabeltrace2 _must_ expose a pure C99 API to preserve
1621 ABI compatibility over time.
1622 ====
1623
1624 === Standard and dependencies
1625
1626 The {bt2} project is configured to use the {cpp11} standard.
1627
1628 {cpp11} makes it possible to build {bt2} with a broad range of
1629 compilers, from GCC{nbsp}4.8 and Clang{nbsp}3.3.
1630
1631 === Automake/Libtool requirements
1632
1633 To add a {cpp} source file to a part of the project, use the `.cpp`
1634 extension and add it to the list of source files in `Makefile.am` as
1635 usual.
1636
1637 If a program or a shared library has a direct {cpp} source file, then
1638 Libtool uses the {cpp} linker to create the result, dynamically
1639 linking important runtime libraries such as libstdc++ and libgcc_s.
1640
1641 Because a Libtool _convenience library_ is just an archive (`.a`), it's
1642 _not_ dynamically linked to runtime libraries, even if one of its direct
1643 sources is a {cpp} file. This means that for each program or shared
1644 library named `my_target` in `Makefile.am` which is linked to a
1645 convenience library having {cpp} sources (recursively), you _must_ do
1646 one of:
1647
1648 * Have at least one direct {cpp} source file in the
1649 `+*_my_target_SOURCES+` list.
1650
1651 * Add:
1652 +
1653 ----
1654 nodist_EXTRA_my_target_SOURCES = dummy.cpp
1655 ----
1656 +
1657 See
1658 https://www.gnu.org/software/automake/manual/automake.html#Libtool-Convenience-Libraries[Libtool
1659 Convenience Libraries] to learn more.
1660
1661 For a given program or library, you _cannot_ have a C{nbsp}file and a
1662 {cpp}{nbsp}file having the same name, for example `list.c` and
1663 `list.cpp`.
1664
1665 === Coding style
1666
1667 ==== Whitespaces, indentation, and line breaks
1668
1669 All the project's {cpp} files follow the
1670 https://clang.llvm.org/docs/ClangFormat.html[clang-format]
1671 https://clang.llvm.org/docs/ClangFormatStyleOptions.html[style] of the
1672 `.clang-format` file for whitespaces, indentation, and line breaks.
1673
1674 You _must_ format modified and new {cpp} files with clang-format before
1675 you create a contribution patch.
1676
1677 You need clang-format{nbsp}15 to use the project's `.clang-format` file.
1678
1679 To automatically format all the project's {cpp} files, run:
1680
1681 ----
1682 $ ./tools/format-cpp
1683 ----
1684
1685 Use the `FORMATTER` environment variable to override the default
1686 formatter (`clang-format{nbsp}-i`):
1687
1688 ----
1689 $ FORMATTER='clang-format-10 -i' ./tools/format-cpp
1690 ----
1691
1692 ==== Naming
1693
1694 * Use camel case with a lowercase first letter for:
1695 ** Variable names: `size`, `objSize`.
1696 ** Function/method names: `size()`, `formatAndPrint()`.
1697
1698 * Use camel case with an uppercase first letter for:
1699 ** Types: `Pistachio`, `NutManager`.
1700 ** Template parameters: `PlanetT`, `TotalSize`.
1701
1702 * Use snake case with uppercase letters for:
1703 ** Definition/macro names: `MARK_AS_UNUSED()`, `SOME_FEATURE_EXISTS`.
1704 ** Enumerators: `Type::SIGNED_INT`, `Scope::FUNCTION`.
1705
1706 * Use only lowercase letters and digits for namespaces: `mylib`, `bt2`.
1707
1708 * Use the suffix `T` for type template parameters:
1709 +
1710 [source,cpp]
1711 ----
1712 template <typename NameT, typename ItemT>
1713 ----
1714
1715 * Name a template parameter pack `Args`.
1716 +
1717 [source,cpp]
1718 ----
1719 template <typename NameT, typename... Args>
1720 ----
1721
1722 * Use an underscore prefix for private and protected methods and member
1723 type names: `_tryConnect()`, `_NodeType`.
1724
1725 * Use the prefix `_m` for private and protected member variable names:
1726 `_mLogger`, `_mSize`, `_mFieldClass`.
1727
1728 * Name setters and getters like the property name, without `set` and
1729 `get` prefixes.
1730
1731 * Use the `is` or `has` prefix, if possible, to name the functions which
1732 return `bool`.
1733
1734 === Coding convention
1735
1736 In general, the project's contributors make an effort to follow,
1737 for {cpp11} code:
1738
1739 * The
1740 https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md[{cpp} Core Guidelines].
1741
1742 * Scott Meyers's
1743 "`https://www.oreilly.com/library/view/effective-modern-c/9781491908419/[Effective Modern {cpp}]`".
1744
1745 Here are a few important reminders:
1746
1747 * Namespace your code.
1748
1749 * Create one header/source file pair per class when possible.
1750 +
1751 For a class named `MyClass`, name the corresponding files `my-class.hpp`
1752 and `my-class.cpp`.
1753
1754 * When defining a class, put constructors as the first methods, whatever
1755 their access (public/protected/private), then the destructor, and then
1756 the rest.
1757
1758 * Declare variables as close to where they are used as possible.
1759
1760 * Use `auto` when possible.
1761
1762 * Use `const` as much as possible, even for pointer
1763 (`+const char* const+`) and numeric values (`const unsigned int`)
1764 which never need to change.
1765
1766 * Implement simple setters, getters, and one-liners in header files and
1767 everything else that's not a template in source files.
1768
1769 * Make methods `const noexcept` or `const` as much as possible.
1770
1771 * Make constructors `explicit` unless you really need an implicit
1772 constructor (which is rare).
1773
1774 * Use `std::unique_ptr` to manage memory when possible.
1775 +
1776 However, use references (`+*my_unique_ptr+`) and raw pointers
1777 (`+my_unique_ptr.get()+`) when not transferring ownership.
1778
1779 * Use `nullptr`, not `NULL` nor 0.
1780
1781 * Return by value (rvalue) instead of by output parameter (non-const
1782 lvalue reference), even complex objects, unless you can prove that the
1783 performance is improved when returning by parameter.
1784
1785 * For a function parameter or a return value of which the type needs to
1786 be a reference or pointer, use:
1787 +
1788 If the value is mandatory:::
1789 A reference.
1790 If the value is optional:::
1791 A raw pointer.
1792
1793 * Don't use `+std::move()+` when you already have an rvalue, which
1794 means:
1795 ** Don't write `+return std::move(...);+` as this can interfere with
1796 RVO.
1797 ** Don't use `+std::move()+` with a function call
1798 (`+std::move(func())+`).
1799
1800 * For each possible move/copy constructor or assignment operator, do one
1801 of:
1802 ** Write a custom one.
1803 ** Mark it as defaulted (`default`)
1804 ** Mark it as deleted (`delete`).
1805
1806 * Use scoped enumerations (`+enum class+`).
1807
1808 * Mark classes known to be final with the `final` keyword.
1809
1810 * Use type aliases (`using`), not type definitions (`typedef`).
1811
1812 * Use anonymous namespaces for local functions instead of `static`.
1813
1814 * Don't pollute the global namespace:
1815 ** Don't use `using namespace xyz` anywhere.
1816 ** Use only namespace aliases in source files (`.cpp`), trying to
1817 use them in the smallest possible scope (function, or even smaller).
1818
1819 * Return a structure with named members instead of a generic container
1820 such as `std::pair` or `std::tuple`.
1821
1822 * When a class inherits a base class with virtual methods, use the
1823 `override` keyword to mark overridden virtual methods, and do not use
1824 the `virtual` keyword again.
1825
1826 * Define overloaded operators only if their meaning is obvious,
1827 unsurprising, and consistent with the corresponding built-in
1828 operators.
1829 +
1830 For example, use `+|+` as a bitwise- or logical-or, not as a shell-style
1831 pipe.
1832
1833 * Use RAII wrappers when managing system resources or interacting with
1834 C{nbsp}libraries.
1835 +
1836 In other words, don't rely on ``goto``s and error labels to clean up as
1837 you would do in{nbsp}C.
1838 +
1839 Use the RAII, Luke.
1840
1841 * Throw an exception when there's an unexpected, exceptional condition,
1842 https://isocpp.org/wiki/faq/exceptions#ctors-can-throw[including from
1843 a constructor], instead of returning a status code.
1844
1845 * Accept a by-value parameter and move it (when it's moveable) when you
1846 intend to copy it anyway.
1847 +
1848 You can do this with most STL containers.
1849 +
1850 Example:
1851 +
1852 [source,cpp]
1853 ----
1854 void Obj::doSomething(std::string str)
1855 {
1856 _mName = std::move(str);
1857 // ...
1858 }
1859 ----
1860
1861 .`baby.hpp`
1862 ====
1863 This example shows a {cpp} header which follows the {bt2} {cpp} coding
1864 convention.
1865
1866 [source,cpp]
1867 ----
1868 /*
1869 * SPDX-License-Identifier: MIT
1870 *
1871 * Copyright 2020 Harry Burnett <hburnett@reese.choco>
1872 */
1873
1874 #ifndef BABELTRACE_BABY_HPP
1875 #define BABELTRACE_BABY_HPP
1876
1877 #include <string>
1878 #include <unordered_set>
1879 #include <utility>
1880
1881 namespace life {
1882
1883 class Toy;
1884
1885 /*
1886 * A baby is a little human.
1887 */
1888 class Baby : public Human
1889 {
1890 public:
1891 using Toys = std::unordered_set<Toy>;
1892
1893 enum class Gender
1894 {
1895 MALE,
1896 FEMALE,
1897 UNKNOWN,
1898 };
1899
1900 Baby() = default;
1901 explicit Baby(const Toys& toys);
1902 Baby(const Baby&) = delete;
1903 Baby(Baby&&) = delete;
1904 Baby& operator=(const Baby&) = delete;
1905 Baby& operator=(Baby&&) = delete;
1906
1907 protected:
1908 explicit Baby(Gender initialGender = Gender::UNKNOWN);
1909
1910 public:
1911 /*
1912 * Eats `weight` grams of food.
1913 */
1914 void eat(unsigned long weight);
1915
1916 /*
1917 * Sleeps for `duration` seconds.
1918 */
1919 void sleep(double duration);
1920
1921 /*
1922 * Sets this baby's name to `name`.
1923 */
1924 void name(std::string name)
1925 {
1926 _mName = std::move(name);
1927 }
1928
1929 /*
1930 * This baby's name.
1931 */
1932 const std::string& name() const noexcept
1933 {
1934 return _mName;
1935 }
1936
1937 protected:
1938 void _addTeeth(unsigned long index);
1939 void _grow(double size) override;
1940
1941 private:
1942 std::string _mName {"Paul"};
1943 Toys _mToys;
1944 };
1945
1946 } // namespace life
1947
1948 #endif // BABELTRACE_BABY_HPP
1949 ----
1950 ====
This page took 0.068057 seconds and 4 git commands to generate.