Setting up QNX helpers logging

Updated: April 19, 2023

QNX helpers logging provides default settings and configuration that initialize slog2.

Instead of implementing initialization for slog2 for each library individually, a developer can implement slog2 for any library that uses it by specifying a QNX helpers logging context.

A library or application normally has a single logging context that identifies it (by name) in the logs. The context name is used as a prefix when the context is used for logging and to match the context when it is specified by name in the API.

Creating a logging context

The simplest way to create a logging context with a given name for use with the QNX helpers logging interface is to use the QH_LOG_DEFAULT_CONTEXT_INIT() macro and define QH_LOG_USER_CONTEXT_NAME to hold the context name. Although QH_LOG_USER_CONTEXT_NAME is typically defined in the project's makefiles (so that it applies to the whole project), you can also define it in a file prior to including log.h and then call QH_LOG_DEFAULT_CONTEXT_INIT(). When you define it in a file, the context only applies for the specific file.

QH_LOG_DEFAULT_CONTEXT_INIT() is called only once in a source file throughout the entire project, at file scope, without a semicolon at the end.

You must initialize the context using the QH_LOG_DEFAULT_CONTEXT_INIT() macro to use the qh_log(), qh_log_noloc(), qh_log_loc() and QH_LOG_CHECK() macros with the context because all those functions make use of the default context variable (QH_LOG_USER_CONTEXT_VAR).

Context pointer

If the QH_LOG_DEFAULT_CONTEXT_INIT() macro is not used to define the project context, then you must declare a context pointer as extern and hide it to prevent it from being globally seen by other loaded modules (for an example, see the declaration of QH_LOG_USER_CONTEXT_VAR in log.h). Alternatively, you can use a static variable at file scope in a source file if logging calls are only made from that file.

You can also use qh_log_context_create() to create a logging context, instead of using the QH_LOG_DEFAULT_CONTEXT_INIT() macro.

Makefile and source code entries

Because the details of a logging context are totally abstracted when you use the QH_LOG_DEFAULT_CONTEXT_INIT() macro, an application can initialize a logging context by simply including the following entries in the makefiles and source code.

Add the following line to the makefiles:
CCFLAGS += -DQH_LOG_USER_CONTEXT_NAME="\"$(NAME)\"" 
Add the following lines to a single source file (non-header):
#include <qh/log.h>
...
QH_LOG_DEFAULT_CONTEXT_INIT()
...
... 

Logging context names

The context names all, default, and qh are reserved. The name qh is used internally by QNX helpers. The names all and default are used in QNX helpers logging configuration (see Controlling QNX helpers logging). If the context name matches a reserved name, its first character is replaced by an underscore.

The name can be composed of any alphanumeric characters and any characters from the set "#()+-.<>[]_" (excluding the double quotes). Any other character is converted to an underscore.

The maximum length (including null-termination) of the name is 32 characters (longer names are truncated) and it cannot have zero length. Keep this requirement in mind when you use the qh_log_get_*_by_name() functions, which use the normalized name.

Use qh_log_context_normalize_name() to either prepare a context's name before you create it or to get the name that the creation process derived from the input name.

Although you can call this function more than once with the same context pointer, if a context at that address exists already, the name in the second call is ignored.