X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=doc%2Flogging-guide.adoc;h=cfd099f94e7ef94b9e3241f73e801cdbda5bb1e4;hb=7e29d48b07ad8ff525b1be3768bc05be5748bce5;hp=2c5ce39caf9997d8923bbcb05b973ad3e2fcdb0f;hpb=6c1b33a842742167c834df1606ca583e71ba8cb1;p=babeltrace.git diff --git a/doc/logging-guide.adoc b/doc/logging-guide.adoc index 2c5ce39c..cfd099f9 100644 --- a/doc/logging-guide.adoc +++ b/doc/logging-guide.adoc @@ -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 `` (or -``) 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. + * + * 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 ----- - -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. + * + * 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 -==== 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 <> for +a list of standard tags. + +. Use the <> 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 <> 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 <>, the <>, +time, the process and thread IDs, the <>, the tag name, the source's function name, file name and line number, and the <>.