lib/ctf-ir/utils.c: lazy-initialize the hash table of reserved keywords
[babeltrace.git] / doc / logging-guide.adoc
index 2c5ce39caf9997d8923bbcb05b973ad3e2fcdb0f..cfd099f94e7ef94b9e3241f73e801cdbda5bb1e4 100644 (file)
@@ -1,6 +1,6 @@
 = Babeltrace logging guide
 Philippe Proulx
-7 May 2017
+31 May 2017
 :toc:
 :toclevels: 5
 
@@ -30,7 +30,7 @@ you and other developers understand what's happening at run-time.
 
 The Babeltrace logging API is internal: it is not exposed to the users
 of the library, only to their developers. The only thing that a library
-user can control is the current log level of the library with
+user can control is the current log level of the library itself with
 `bt_logging_set_global_level()` and the initial library's log level with
 the `BABELTRACE_LOGGING_GLOBAL_LEVEL` environment variable.
 
@@ -156,6 +156,7 @@ log level of your subproject or module, and that it's set to _NONE_
 by default.
 
 
+[[logging-statements]]
 === Logging statement macros
 
 The Babeltrace logging statement macros work just like `printf()` and
@@ -306,226 +307,185 @@ BT_LOGD("Bla bla: number=%d", get_number_of_event_classes_with_property_x(...));
 ----
 
 
-[[tag]]
-== Tag
+[[how-to]]
+=== Instrument a module
 
-Before including `<babeltrace/logging-internal.h>` (or
-`<babeltrace/lib-logging-internal.h>`) in your C source file, define
-`BT_LOG_TAG` to a name which represents your module. The tag name _must_
-be only uppercase letters/digits and the hyphen (`-`) character.
-
-For example:
+Follow those steps to make your module loggable:
 
+. In your module's root directory, create a `logging.c` file with
+  this content:
++
+--
 [source,c]
 ----
-#define BT_LOG_TAG "EVENT-CLASS"
+/*
+ * Copyright (c) 2017 EfficiOS Inc. <http://efficios.com/>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL my_module_log_level
 #include <babeltrace/logging-internal.h>
-----
-
-A tag is conceptually similar to a logger name.
-
-
-=== Babeltrace tags
-
-==== CTF IR (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Attributes |`ATTRS`
-|Clock class and values |`CLOCK-CLASS`
-|Event class |`EVENT-CLASS`
-|Event |`EVENT`
-|Field path |`FIELD-PATH`
-|Field types |`FIELD-TYPES`
-|Fields |`FIELDS`
-|Packet |`PACKET`
-|Resolver |`RESOLVE`
-|Stream class |`STREAM-CLASS`
-|Stream |`STREAM`
-|Trace |`TRACE`
-|Validation |`VALIDATION`
-|Visitor |`VISITOR`
-|===
-
-
-==== CTF writer (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Clock |`CTF-WRITER-CLOCK`
-|CTF writer |`CTF-WRITER`
-|Serialization |`CTF-WRITER-SER`
-|===
-
-
-==== Graph (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Clock class priority map |`CC-PRIO-MAP`
-|Component (common) |`COMP`
-|Component class |`COMP-CLASS`
-|Connection |`CONNECTION`
-|Filter component |`COMP-FILTER`
-|Graph |`GRAPH`
-|Notification iterator |`NOTIF-ITER`
-|Port |`PORT`
-|Sink component |`COMP-SINK`
-|Source component |`COMP-SOURCE`
-|===
-
-==== Notifications (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Event notification |`NOTIF-EVENT`
-|Inacitivity notification |`NOTIF-INACTIVITY`
-|Notification |`NOTIF`
-|Packet notification |`NOTIF-PACKET`
-|Stream notification |`NOTIF-STREAM`
-|===
-
-
-==== Plugin (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Plugin |`PLUGIN`
-|Python plugin provider |`PLUGIN-PY`
-|Shared object plugin provider |`PLUGIN-SO`
-|===
-
-
-==== Values (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Values |`VALUES`
-|===
-
-
-==== Reference counting (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Reference counting |`REF`
-|===
-
-
-==== Common (library)
-
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Common |`COMMON`
-|===
 
+BT_LOG_INIT_LOG_LEVEL(my_module_log_level, "BABELTRACE_MY_MODULE_LOG_LEVEL");
+----
+--
++
+Replace `my_module_log_level` with the name of the symbol which holds
+the log level for your module (should be unique amongst all the log level
+symbols of the project). Replace `BABELTRACE_MY_MODULE_LOG_LEVEL` with
+the name of the environment variable from which to initialize your
+module's log level at construction time. `BT_LOG_INIT_LOG_LEVEL()`
+defines both the hidden log level symbol and a constructor which reads
+the environment variable and sets the log level symbol accordingly.
+
+. In your module's root directory, create a `logging.h` file with
+  this content:
++
+--
+[source,c]
+----
+#ifndef MY_MODULE_LOGGING_H
+#define MY_MODULE_LOGGING_H
+
+/*
+ * Copyright (c) 2017 EfficiOS Inc. <http://efficios.com/>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL my_module_log_level
+#include <babeltrace/logging-internal.h>
 
-==== CLI
+BT_LOG_LEVEL_EXTERN_SYMBOL(my_module_log_level);
 
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|CLI (main) |`CLI`
-|CLI configuration (common) |`CLI-CFG`
-|CLI configuration from CLI arguments |`CLI-CFG-ARGS`
-|CLI connection configuration from CLI arguments |`CLI-CFG-ARGS-CONNECT`
-|===
+#endif /* MY_MODULE_LOGGING_H */
+----
+--
++
+Again, replace `my_module_log_level` with the name of your module's
+log level symbol.
 
+. Include the `logging.c` and `logging.h` in the `_SOURCES` variable
+  of your module's object in your module's root `Makefile.am`.
 
-==== libctfcopytrace (plugin convenience library)
+To instrument a C source file (`.c`):
 
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
+. At the top of the file, before the first `#include` line (if any),
+  define your file's tag name and include the local `logging.h`:
++
+--
+[source,c]
+----
+#define BT_LOG_TAG "MY-MODULE-MY-FILE"
+#include "logging.h"
+----
+--
++
+A logging tag name is a namespace for a specific source file. Its name
+is part of every log message generated by the statements of the file. A
+logging tag name _must_ be only uppercase letters, digits, and the
+hyphen (`-`) character. See <<tags,Choose a tag>> for
+a list of standard tags.
+
+. Use the <<logging-statements,logging statement macros>> in the file's
+  functions to instrument it.
+
+To instrument a C header file (`.h`), if you have `static inline`
+functions in it:
+
+. Do not include any logging header.
+. Use the <<logging-statements,logging statement macros>> in the file's
+  functions to instrument it, making each of them conditional to the
+  existence of the macro you're using:
++
+--
+[source,c]
+----
+static inline
+void some_function(void)
+{
+    /* ... */
 
-|Clock fields |`LIBCTFCOPYTRACE-CLOCK-FIELDS`
-|libctfcopytrace |`LIBCTFCOPYTRACE`
-|===
+#ifdef BT_LOGV
+    BT_LOGV(...);
+#endif
 
+    /* ... */
 
-==== `ctf` plugin
+#ifdef BT_LOGW_STR
+    BT_LOGW_STR(...);
+#endif
 
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Plugin (main) |`PLUGIN-CTF`
-|Common: BTR |`PLUGIN-CTF-BTR`
-|Common: CTF IR generation metadata visitor |`PLUGIN-CTF-METADATA-IR-VISITOR`
-|Common: Metadata decoder |`PLUGIN-CTF-METADATA-DECODER`
-|Common: Metadata lexer |`PLUGIN-CTF-METADATA-LEXER`
-|Common: Metadata parser |`PLUGIN-CTF-METADATA-PARSER`
-|Common: Notification iterator |`PLUGIN-CTF-NOTIF-ITER`
-|`fs` sink (main) |`PLUGIN-CTF-FS-SINK`
-|`fs` sink: write |`PLUGIN-CTF-FS-SINK-WRITE`
-|`fs` source (main) |`PLUGIN-CTF-FS-SRC`
-|`fs` source: data stream |`PLUGIN-CTF-FS-SRC-DS`
-|`fs` source: file |`PLUGIN-CTF-FS-SRC-FILE`
-|`fs` source: metadata |`PLUGIN-CTF-FS-SRC-METADATA`
-|`lttng-live` source (main) |`PLUGIN-CTF-LTTNG-LIVE`
-|`lttng-live` source: data stream |`PLUGIN-CTF-LTTNG-LIVE-DS`
-|`lttng-live` source: metadata |`PLUGIN-CTF-LTTNG-LIVE-METADATA`
-|`lttng-live` source: viewer connection |`PLUGIN-CTF-LTTNG-LIVE-VIEWER`
-|===
+    /* ... */
+}
+----
+--
++
+The C source files which include this header file determine if logging
+is enabled or not for them (if the source file is instrumented itself),
+and the tag of the included header's logging statement is the same as
+the C source file.
 
 
-==== `lttng-utils` plugin
+[[tags]]
+=== Choose a tag
 
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Plugin (main) |`PLUGIN-LTTNG-UTILS`
-|`debug-info` filter (main) |`PLUGIN-LTTNG-UTILS-DBG-INFO`
-|`debug-info` filter: binary info |`PLUGIN-LTTNG-UTILS-DBG-INFO-BIN-INFO`
-|`debug-info` filter: copy |`PLUGIN-LTTNG-UTILS-DBG-INFO-COPY`
-|`debug-info` filter: CRC32 |`PLUGIN-LTTNG-UTILS-DBG-INFO-CRC32`
-|`debug-info` filter: DWARF |`PLUGIN-LTTNG-UTILS-DBG-INFO-DWARF`
-|===
+For plugins, the format of the tag name for a given source file _must_
+be:
 
+[verse]
+PLUGIN-__PNAME__-__CCNAME__-__CCTYPE__[-__FILE__]
 
-==== `text` plugin
+__PNAME__::
+    Plugin's name.
 
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
+__CCNAME__::
+    Component class's name.
 
-|Plugin (main) |`PLUGIN-TEXT`
-|`pretty` filter (main) |`PLUGIN-TEXT-PRETTY`
-|`pretty` filter: print |`PLUGIN-TEXT-PRETTY-PRINT`
-|===
+__CCTYPE__::
+    Component class's type (`SRC`, `FLT`, or `SINK`).
 
+__FILE__::
+    Additional information to specify the source file name or module.
 
-==== `utils` plugin
+Examples:
 
-[options="header,autowidth"]
-|===
-|Subsystem/object |Tag name
-
-|Plugin (main) |`PLUGIN-UTILS`
-|`dummy` sink (main) |`PLUGIN-UTILS-DUMMY`
-|`muxer` filter (main) |`PLUGIN-UTILS-MUXER`
-|`trimmer` filter (main) |`PLUGIN-UTILS-TRIMMER`
-|`trimmer` filter: copy |`PLUGIN-UTILS-TRIMMER-COPY`
-|`trimmer` filter: iterator |`PLUGIN-UTILS-TRIMMER-ITER`
-|===
+* `PLUGIN-CTF-LTTNG-LIVE-SRC`
+* `PLUGIN-CTF-LTTNG-LIVE-SRC-VIEWER`
+* `PLUGIN-UTILS-MUXER-FLT`
 
 
 [[level]]
@@ -543,11 +503,11 @@ important.
 condition: it must be terminated immediately.
 
 A _FATAL_-level logging statement should always be followed by
-`abort()` or `assert(false)`.
+`abort()`.
 |
 * Unexpected return values from system calls.
-* Logic error in internal code, for example an unknown value in a
-  `switch` statement which should only deal with .
+* Logic error in internal code, for example an unexpected value in a
+  `switch` statement.
 |Almost none: should be executed in production.
 
 |_ERROR_
@@ -563,6 +523,7 @@ least exit cleanly.
   implementation and the satisfied preconditions. For example, the
   failure to create an empty object (no parameters): most probably
   failed internally because of an allocation error.
+* Almost any error in terminal elements: CLI and plugins.
 |Almost none: should be executed in production.
 
 |_WARN_
@@ -570,7 +531,12 @@ least exit cleanly.
 
 _WARN_-level logging statements are for any error or weird action that
 is directly or indirectly caused by the user. For example, not having
-enough memory is beyond user control.
+enough memory is considered beyond the user's control, so we always
+log memory errors with an _ERROR_ level (not _FATAL_ because we usually
+don't abort in this condition).
+
+Almost all the library's errors are logged as warnings because they are
+caused by the user.
 |
 * Not honoring a public function's preconditions (NULL parameters,
   index out of bounds, etc.).
@@ -586,7 +552,7 @@ class.
 |
 * Successful loading of a plugin (with name, version, etc.).
 * Successful connection to or disconnection from another system.
-* An optional subsystem cannot be loaded.
+* An _optional_ subsystem cannot be loaded.
 |Very little: can be executed in production if
 _INFO_ level information is desired.
 
@@ -692,7 +658,7 @@ Prefer the following suffixes in field names:
 == Output
 
 The log is printed to the standard error stream. A log line contains the
-time, the process and thread IDs, the <<level,log level>>, the <<tag,tag>>,
+time, the process and thread IDs, the <<level,log level>>, the tag name,
 the source's function name, file name and line number, and the
 <<message,message>>.
 
This page took 0.029223 seconds and 4 git commands to generate.