Logging

The logging API provides a common interface to process messages issued by developers. Messages are passed through a frontend and are then processed by active backends. Custom frontend and backends can be used if needed. Default configuration uses built-in frontend and UART backend.

Summary of the logging features:

  • Deferred logging reduces the time needed to log a message by shifting time consuming operations to a known context instead of processing and sending the log message when called.

  • Multiple backends supported (up to 9 backends).

  • Custom frontend supported.

  • Compile time filtering on module level.

  • Run time filtering independent for each backend.

  • Additional run time filtering on module instance level.

  • Timestamping with user provided function.

  • Dedicated API for dumping data.

  • Dedicated API for handling transient strings.

  • Panic support - in panic mode logging switches to blocking, synchronous processing.

  • Printk support - printk message can be redirected to the logging.

  • Design ready for multi-domain/multi-processor system.

Logging v2 introduces following changes:

  • Option to use 64 bit timestamp

  • Support for logging floating point variables

  • Support for logging variables extending size of a machine word (64 bit values on 32 bit architectures)

  • Remove the need for special treatment of %s format specifier

  • Extend API for dumping data to accept formatted string

  • Improve memory utilization. More log messages fit in the logging buffer in deferred mode.

  • Log message is no longer fragmented. It is self-contained block of memory which simplifies out of domain handling (e.g. offline processing)

  • Improved performance when logging from user space

  • Improved performance when logging to full buffer and message are dropped.

  • Slightly degrade performance in normal circumstances due to the fact that allocation from ring buffer is more complex than from memslab.

  • No change in logging API

  • Logging backend API exteded with function for processing v2 messages.

Logging API is highly configurable at compile time as well as at run time. Using Kconfig options (see Global Kconfig Options) logs can be gradually removed from compilation to reduce image size and execution time when logs are not needed. During compilation logs can be filtered out on module basis and severity level.

Logs can also be compiled in but filtered on run time using dedicate API. Run time filtering is independent for each backend and each source of log messages. Source of log messages can be a module or specific instance of the module.

There are four severity levels available in the system: error, warning, info and debug. For each severity level the logging API (include/logging/log.h) has set of dedicated macros. Logger API also has macros for logging data.

For each level following set of macros are available:

  • LOG_X for standard printf-like messages, e.g. LOG_ERR.

  • LOG_HEXDUMP_X for dumping data, e.g. LOG_HEXDUMP_WRN.

  • LOG_INST_X for standard printf-like message associated with the particular instance, e.g. LOG_INST_INF.

  • LOG_INST_HEXDUMP_X for dumping data associated with the particular instance, e.g. LOG_HEXDUMP_INST_DBG

There are two configuration categories: configurations per module and global configuration. When logging is enabled globally, it works for modules. However, modules can disable logging locally. Every module can specify its own logging level. The module must define the LOG_LEVEL macro before using the API. Unless a global override is set, the module logging level will be honored. The global override can only increase the logging level. It cannot be used to lower module logging levels that were previously set higher. It is also possible to globally limit logs by providing maximal severity level present in the system, where maximal means lowest severity (e.g. if maximal level in the system is set to info, it means that errors, warnings and info levels are present but debug messages are excluded).

Each module which is using the logging must specify its unique name and register itself to the logging. If module consists of more than one file, registration is performed in one file but each file must define a module name.

Logger’s default frontend is designed to be thread safe and minimizes time needed to log the message. Time consuming operations like string formatting or access to the transport are not performed by default when logging API is called. When logging API is called a message is created and added to the list. Dedicated, configurable buffer for pool of log messages is used. There are 2 types of messages: standard and hexdump. Each message contain source ID (module or instance ID and domain ID which might be used for multiprocessor systems), timestamp and severity level. Standard message contains pointer to the string and arguments. Hexdump message contains copied data and string.

Global Kconfig Options

These options can be found in the following path subsys/logging/Kconfig.

CONFIG_LOG: Global switch, turns on/off the logging.

Mode of operations:

CONFIG_LOG_MODE_DEFERRED: Deferred mode.

CONFIG_LOG2_MODE_DEFERRED: Deferred mode v2.

CONFIG_LOG_MODE_IMMEDIATE: Immediate (synchronous) mode.

CONFIG_LOG2_MODE_IMMEDIATE: Immediate (synchronous) mode v2.

CONFIG_LOG_MODE_MINIMAL: Minimal footprint mode.

Filtering options:

CONFIG_LOG_RUNTIME_FILTERING: Enables runtime reconfiguration of the filtering.

CONFIG_LOG_DEFAULT_LEVEL: Default level, sets the logging level used by modules that are not setting their own logging level.

CONFIG_LOG_OVERRIDE_LEVEL: It overrides module logging level when it is not set or set lower than the override value.

CONFIG_LOG_MAX_LEVEL: Maximal (lowest severity) level which is compiled in.

Processing options:

CONFIG_LOG_MODE_OVERFLOW: When new message cannot be allocated, oldest one are discarded.

CONFIG_LOG_BLOCK_IN_THREAD: If enabled and new log message cannot be allocated thread context will block for up to CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS or until log message is allocated.

CONFIG_LOG_PRINTK: Redirect printk calls to the logging.

CONFIG_LOG_PRINTK_MAX_STRING_LENGTH: Maximal string length that can be processed by printk. Longer strings are trimmed.

CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD: When number of buffered log messages reaches the threshold dedicated thread (see log_thread_set()) is waken up. If CONFIG_LOG_PROCESS_THREAD is enabled then this threshold is used by the internal thread.

CONFIG_LOG_PROCESS_THREAD: When enabled, logging thread is created which handles log processing.

CONFIG_LOG_PROCESS_THREAD_STARTUP_DELAY_MS: Delay in milliseconds after which logging thread is started.

CONFIG_LOG_BUFFER_SIZE: Number of bytes dedicated for the message pool. Single message capable of storing standard log with up to 3 arguments or hexdump message with 12 bytes of data take 32 bytes. In v2 it indicates buffer size dedicated for circular packet buffer.

CONFIG_LOG_DETECT_MISSED_STRDUP: Enable detection of missed transient strings handling.

CONFIG_LOG_STRDUP_MAX_STRING: Longest string that can be duplicated using log_strdup().

CONFIG_LOG_STRDUP_BUF_COUNT: Number of buffers in the pool used by log_strdup().

CONFIG_LOG_DOMAIN_ID: Domain ID. Valid in multi-domain systems.

CONFIG_LOG_FRONTEND: Redirect logs to a custom frontend.

CONFIG_LOG_TIMESTAMP_64BIT: 64 bit timestamp.

Formatting options:

CONFIG_LOG_FUNC_NAME_PREFIX_ERR: Prepend standard ERROR log messages with function name. Hexdump messages are not prepended.

CONFIG_LOG_FUNC_NAME_PREFIX_WRN: Prepend standard WARNING log messages with function name. Hexdump messages are not prepended.

CONFIG_LOG_FUNC_NAME_PREFIX_INF: Prepend standard INFO log messages with function name. Hexdump messages are not prepended.

CONFIG_LOG_FUNC_NAME_PREFIX_DBG: Prepend standard DEBUG log messages with function name. Hexdump messages are not prepended.

CONFIG_LOG_BACKEND_SHOW_COLOR: Enables coloring of errors (red) and warnings (yellow).

CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP: If enabled timestamp is formatted to hh:mm:ss:mmm,uuu. Otherwise is printed in raw format.

Backend options:

CONFIG_LOG_BACKEND_UART: Enabled build-in UART backend.

Usage

Logging in a module

In order to use logging in the module, a unique name of a module must be specified and module must be registered using LOG_MODULE_REGISTER. Optionally, a compile time log level for the module can be specified as the second parameter. Default log level (CONFIG_LOG_DEFAULT_LEVEL) is used if custom log level is not provided.

#include <logging/log.h>
LOG_MODULE_REGISTER(foo, CONFIG_FOO_LOG_LEVEL);

If the module consists of multiple files, then LOG_MODULE_REGISTER() should appear in exactly one of them. Each other file should use LOG_MODULE_DECLARE to declare its membership in the module. Optionally, a compile time log level for the module can be specified as the second parameter. Default log level (CONFIG_LOG_DEFAULT_LEVEL) is used if custom log level is not provided.

#include <logging/log.h>
/* In all files comprising the module but one */
LOG_MODULE_DECLARE(foo, CONFIG_FOO_LOG_LEVEL);

In order to use logging API in a function implemented in a header file LOG_MODULE_DECLARE macro must be used in the function body before logging API is called. Optionally, a compile time log level for the module can be specified as the second parameter. Default log level (CONFIG_LOG_DEFAULT_LEVEL) is used if custom log level is not provided.

#include <logging/log.h>

static inline void foo(void)
{
     LOG_MODULE_DECLARE(foo, CONFIG_FOO_LOG_LEVEL);

     LOG_INF("foo");
}

Dedicated Kconfig template (subsys/logging/Kconfig.template.log_config) can be used to create local log level configuration.

Example below presents usage of the template. As a result CONFIG_FOO_LOG_LEVEL will be generated:

module = FOO
module-str = foo
source "subsys/logging/Kconfig.template.log_config"

Logging in a module instance

In case of modules which are multi-instance and instances are widely used across the system enabling logs will lead to flooding. Logger provide the tools which can be used to provide filtering on instance level rather than module level. In that case logging can be enabled for particular instance.

In order to use instance level filtering following steps must be performed:

  • a pointer to specific logging structure is declared in instance structure. LOG_INSTANCE_PTR_DECLARE is used for that.

#include <logging/log_instance.h>

struct foo_object {
     LOG_INSTANCE_PTR_DECLARE(log);
     uint32_t id;
}
  • module must provide macro for instantiation. In that macro, logging instance is registered and log instance pointer is initialized in the object structure.

#define FOO_OBJECT_DEFINE(_name)                             \
     LOG_INSTANCE_REGISTER(foo, _name, CONFIG_FOO_LOG_LEVEL) \
     struct foo_object _name = {                             \
             LOG_INSTANCE_PTR_INIT(log, foo, _name)          \
     }

Note that when logging is disabled logging instance and pointer to that instance are not created.

In order to use the instance logging API in a source file, a compile-time log level must be set using LOG_LEVEL_SET.

LOG_LEVEL_SET(CONFIG_FOO_LOG_LEVEL);

void foo_init(foo_object *f)
{
     LOG_INST_INF(f->log, "Initialized.");
}

In order to use the instance logging API in a header file, a compile-time log level must be set using LOG_LEVEL_SET.

static inline void foo_init(foo_object *f)
{
     LOG_LEVEL_SET(CONFIG_FOO_LOG_LEVEL);

     LOG_INST_INF(f->log, "Initialized.");
}

Controlling the logging

Logging can be controlled using API defined in include/logging/log_ctrl.h. Logger must be initialized before it can be used. Optionally, user can provide function which returns timestamp value. If not provided, k_cycle_get_32 is used for timestamping. log_process() function is used to trigger processing of one log message (if pending). Function returns true if there is more messages pending.

Following snippet shows how logging can be processed in simple forever loop.

#include <log_ctrl.h>

void main(void)
{
     log_init();

     while (1) {
             if (log_process() == false) {
                     /* sleep */
             }
     }
}

If logs are processed from a thread then it is possible to enable a feature which will wake up processing thread when certain amount of log messages are buffered (see CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD). It is also possible to enable internal logging thread (see CONFIG_LOG_PROCESS_THREAD). In that case, logging thread is initialized and log messages are processed implicitly.

Logging panic

In case of error condition system usually can no longer rely on scheduler or interrupts. In that situation deferred log message processing is not an option. Logger controlling API provides a function for entering into panic mode (log_panic()) which should be called in such situation.

When log_panic() is called, _panic_ notification is sent to all active backends. Once all backends are notified, all buffered messages are flushed. Since that moment all logs are processed in a blocking way.

Architecture

Logging consists of 3 main parts:

  • Frontend

  • Core

  • Backends

Log message is generated by a source of logging which can be a module or instance of a module.

Default Frontend

Default frontend is engaged when logging API is called in a source of logging (e.g. LOG_INF) and is responsible for filtering a message (compile and run time), allocating buffer for the message, creating the message and committing that message. Since logging API can be called in an interrupt, frontend is optimized to log the message as fast as possible.

Log message v1

Each log message consists of one or more fixed size chunks allocated from the pool of fixed size buffers (Memory Slabs). Message head chunk contains log entry details like: source ID, timestamp, severity level and the data (string pointer and arguments or raw data). Message contains also a reference counter which indicates how many users still uses this message. It is used to return message to the pool once last user indicates that it can be freed. If more than 3 arguments or 12 bytes of raw data is used in the log then log message is formed from multiple chunks which are linked together. When message body is filled it is put into the list. When log processing is triggered, a message is removed from the list of pending messages. If runtime filtering is disabled, the message is passed to all active backends, otherwise the message is passed to only those backends that have requested messages from that particular source (based on the source ID in the message), and severity level. Once all backends are iterated, the message is considered processed, but the message may still be in use by a backend. Because message is allocated from a pool, it is not mandatory to sequentially free messages. Processing by the backends is asynchronous and memory is freed when last user indicates that message can be freed. It also means that improper backend implementation may lead to pool drought.

Log message v2

Log message v2 contains message descriptor (source, domain and level), timestamp, formatted string details (see Cbprintf Packaging) and optional data. Log messages v2 are stored in a continuous block of memory (contrary to v1). Memory is allocated from a circular packet buffer (Multi Producer Single Consumer Packet Buffer). It has few consequences:

  • Each message is self-contained, continuous block of memory thus it is suited for copying the message (e.g. for offline processing).

  • Memory is better utilized because fixed size chunks are not used.

  • Messages must be sequentially freed. Backend processing is synchronous. Backend can make a copy for deferred processing.

Log message has following format:

Message Header

2 bits: MPSC packet buffer header

1 bit: Trace/Log message flag

3 bits: Domain ID

3 bits: Level

10 bits: Cbprintf Package Length

12 bits: Data length

1 bit: Reserved

pointer: Pointer to the source descriptor 1

32 or 64 bits: Timestamp 1

Optional padding 2

Cbprintf

package
(optional)

Header

Arguments

Appended strings

Hexdump data (optional)

Alignment padding (optional)

Footnotes

1(1,2)

Depending on the platform and the timestamp size fields may be swapped.

2

It may be required for cbprintf package alignment

Log message allocation

It may happen that frontend cannot allocate a message. It happens if system is generating more log messages than it can process in certain time frame. There are two strategies to handle that case:

  • No overflow - new log is dropped if space for a message cannot be allocated.

  • Overflow - oldest pending messages are freed, until new message can be allocated. Enabled by CONFIG_LOG_MODE_OVERFLOW. Note that it degrades performance thus it is recommended to adjust buffer size and amount of enabled logs to limit dropping.

Run-time filtering

If run-time filtering is enabled, then for each source of logging a filter structure in RAM is declared. Such filter is using 32 bits divided into ten 3 bit slots. Except slot 0, each slot stores current filter for one backend in the system. Slot 0 (bits 0-2) is used to aggregate maximal filter setting for given source of logging. Aggregate slot determines if log message is created for given entry since it indicates if there is at least one backend expecting that log entry. Backend slots are examined when message is processed by the core to determine if message is accepted by the given backend. Contrary to compile time filtering, binary footprint is increased because logs are compiled in.

In the example below backend 1 is set to receive errors (slot 1) and backend 2 up to info level (slot 2). Slots 3-9 are not used. Aggregated filter (slot 0) is set to info level and up to this level message from that particular source will be buffered.

slot 0

slot 1

slot 2

slot 3

slot 9

INF

ERR

INF

OFF

OFF

Custom Frontend

Custom frontend is enabled using CONFIG_LOG_FRONTEND. Logs are redirected to functions declared in include/logging/log_frontend.h. This may be required in very time-sensitive cases, but most of the logging features cannot be used then, which includes default frontend, core and all backends features.

Logging strings

Logging v1

Since log message contains only the value of the argument, when %s is used only the address of a string is stored. Because a string variable argument could be transient, allocated on the stack, or modifiable, logger provides a mechanism and a dedicated buffer pool to hold copies of strings. The buffer size and count is configurable (see CONFIG_LOG_STRDUP_MAX_STRING and CONFIG_LOG_STRDUP_BUF_COUNT).

If a string argument is transient, the user must call log_strdup() to duplicate the passed string into a buffer from the pool. See the examples below. If a strdup buffer cannot be allocated, a warning message is logged and an error code returned indicating CONFIG_LOG_STRDUP_BUF_COUNT should be increased. Buffers are freed together with the log message.

char local_str[] = "abc";

LOG_INF("logging transient string: %s", log_strdup(local_str));
local_str[0] = '\0'; /* String can be modified, logger will use duplicate."

When CONFIG_LOG_DETECT_MISSED_STRDUP is enabled logger will scan each log message and report if string format specifier is found and string address is not in read only memory section or does not belong to memory pool dedicated to string duplicates. It indictes that log_strdup() is missing in a call to log a message, such as LOG_INF.

Logging v2

String arguments are handled by Cbprintf Packaging thus no special action is required.

Logging backends

Logging backends are registered using LOG_BACKEND_DEFINE. The macro creates an instance in the dedicated memory section. Backends can be dynamically enabled (log_backend_enable()) and disabled. When Run-time filtering is enabled, log_filter_set() can be used to dynamically change filtering of a module logs for given backend. Module is identified by source ID and domain ID. Source ID can be retrieved if source name is known by iterating through all registered sources.

Logging supports up to 9 concurrent backends. Log message is passed to the each backend in processing phase. Additionally, backend is notfied when logging enter panic mode with log_backend_panic(). On that call backend should switch to synchronous, interrupt-less operation or shut down itself if that is not supported. Occasionally, logging may inform backend about number of dropped messages with log_backend_dropped(). Message processing API is version specific.

Logging v1

Logging backend interface contains following functions for processing:

The log message contains a reference counter tracking how many backends are processing the message. On receiving a message backend must claim it by calling log_msg_get() on that message which increments a reference counter. Once message is processed, backend puts back the message (log_msg_put()) decrementing a reference counter. On last log_msg_put(), when reference counter reaches 0, message is returned to the pool. It is up to the backend how message is processed.

Note

The message pool can be starved if a backend does not call log_msg_put() when it is done processing a message. The logging core has no means to force messages back to the pool if they’re still marked as in use (with a non-zero reference counter).

#include <log_backend.h>

void put(const struct log_backend *const backend,
         struct log_msg *msg)
{
     log_msg_get(msg);

     /* message processing */

     log_msg_put(msg);
}

Logging v2

log_backend_msg2_process() is used for processing message. It is common for standard and hexdump messages because log message v2 hold string with arguments and data. It is also common for deferred and immediate logging.

Message formatting

Logging provides set of function that can be used by the backend to format a message. Helper functions are available in include/logging/log_output.h.

Example message formatted using log_output_msg_process() or log_output_msg2_process().

[00:00:00.000,274] <info> sample_instance.inst1: logging message

Dictionary-based Logging

Dictionary-based logging, instead of human readable texts, outputs the log messages in binary format. This binary format encodes arguments to formatted strings in their native storage formats which can be more compact than their text equivalents. For statically defined strings (including the format strings and any string arguments), references to the ELF file are encoded instead of the whole strings. A dictionary created at build time contains the mappings between these references and the actual strings. This allows the offline parser to obtain the strings from the dictionary to parse the log messages. This binary format allows a more compact representation of log messages in certain scenarios. However, this requires the use of an offline parser and is not as intuitive to use as text-based log messages.

Note that long double is not supported by Python’s struct module. Therefore, log messages with long double will not display the correct values.

Configuration

Here are kconfig options related to dictionary-based logging:

Usage

When dictionary-based logging is enabled via enabling related logging backends, a JSON database file, named log_dictionary.json, will be created in the build directory. This database file contains information for the parser to correctly parse the log data. Note that this database file only works with the same build, and cannot be used for any other builds.

To use the log parser:

./scripts/logging/dictionary/log_parser.py <build dir>/log_dictionary.json <log data file>

The parser takes two required arguments, where the first one is the full path to the JSON database file, and the second part is the file containing log data. Add an optional argument --hex to the end if the log data file contains hexadecimal characters (e.g. when CONFIG_LOG_BACKEND_UART_OUTPUT_DICTIONARY_HEX=y). This tells the parser to convert the hexadecimal characters to binary before parsing.

Please refer to Dictionary-based Logging Sample on how to use the log parser.

Limitations and recommendations

Logging v1

The are following limitations:

  • Strings as arguments (%s) require special treatment (see Logging strings).

  • Logging double and float variables is not possible because arguments are word size.

  • Variables larger than word size cannot be logged.

  • Number of arguments in the string is limited to 15.

Logging v2

Solves major limitations of v1. However, in order to get most of the logging capabilities following recommendations shall be followed:

  • Enable CONFIG_LOG_SPEED to slightly speed up deferred logging at the cost of slight increase in memory footprint.

  • Compiler with C11 _Generic keyword support is recommended. Logging performance is significantly degraded without it. See Cbprintf Packaging.

  • When _Generic is supported, during compilation it is determined which packaging method shall be used: static or runtime. It is done by searching for any string pointers in the argument list. If string pointer is used with format specifier other than string, e.g. %p, it is recommended to cast it to void *.

LOG_WRN("%s", str);
LOG_WRN("%p", (void *)str);

Benchmark

Benchmark numbers from tests/subsys/logging/log_benchmark performed on qemu_x86. It is a rough comparison to give general overview. Overall, logging v2 improves in most a the areas with the biggest improvement in logging from userspace. It is at the cost of larger memory footprint for a log message.

Feature

v1

v2

Summary

Kernel logging

7us

7us 3/11us

No significant change

User logging

86us

13us

Strongly improved

kernel logging with overwrite

23us

10us 3/15us

Improved

Logging transient string

16us

42us

Degraded

Logging transient string from user

111us

50us

Improved

Memory utilization 4

416

518

Slightly improved

Memory footprint (test) 5

3.2k

2k

Improved

Memory footprint (application) 6

6.2k

3.5k

Improved

Message footprint 7

15 bytes

47 3/32 bytes

Degraded

Benchmark details

3(1,2,3)

CONFIG_LOG_SPEED enabled.

4

Number of log messages with various number of arguments that fits in 2048 bytes dedicated for logging.

5

Logging subsystem memory footprint in tests/subsys/logging/log_benchmark where filtering and formatting features are not used.

6

Logging subsystem memory footprint in samples/subsys/logging/logger.

7

Avarage size of a log message (excluding string) with 2 arguments on Cortex M3

API Reference

Logger API

group log_api

Logger API.

Defines

LOG_ERR(...)

Writes an ERROR level message to the log.

It’s meant to report severe errors, such as those from which it’s not possible to recover.

Parameters
  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_WRN(...)

Writes a WARNING level message to the log.

It’s meant to register messages related to unusual situations that are not necessarily errors.

Parameters
  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_INF(...)

Writes an INFO level message to the log.

It’s meant to write generic user oriented messages.

Parameters
  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_DBG(...)

Writes a DEBUG level message to the log.

It’s meant to write developer oriented information.

Parameters
  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_PRINTK(...)

Unconditionally print raw log message.

The result is same as if printk was used but it goes through logging infrastructure thus utilizes logging mode, e.g. deferred mode.

Parameters
  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_INST_ERR(_log_inst, ...)

Writes an ERROR level message associated with the instance to the log.

Message is associated with specific instance of the module which has independent filtering settings (if runtime filtering is enabled) and message prefix (<module_name>.<instance_name>). It’s meant to report severe errors, such as those from which it’s not possible to recover.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_INST_WRN(_log_inst, ...)

Writes a WARNING level message associated with the instance to the log.

Message is associated with specific instance of the module which has independent filtering settings (if runtime filtering is enabled) and message prefix (<module_name>.<instance_name>). It’s meant to register messages related to unusual situations that are not necessarily errors.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_INST_INF(_log_inst, ...)

Writes an INFO level message associated with the instance to the log.

Message is associated with specific instance of the module which has independent filtering settings (if runtime filtering is enabled) and message prefix (<module_name>.<instance_name>). It’s meant to write generic user oriented messages.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_INST_DBG(_log_inst, ...)

Writes a DEBUG level message associated with the instance to the log.

Message is associated with specific instance of the module which has independent filtering settings (if runtime filtering is enabled) and message prefix (<module_name>.<instance_name>). It’s meant to write developer oriented information.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • ... – A string optionally containing printk valid conversion specifier, followed by as many values as specifiers.

LOG_HEXDUMP_ERR(_data, _length, _str)

Writes an ERROR level hexdump message to the log.

It’s meant to report severe errors, such as those from which it’s not possible to recover.

Parameters
  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_HEXDUMP_WRN(_data, _length, _str)

Writes a WARNING level message to the log.

It’s meant to register messages related to unusual situations that are not necessarily errors.

Parameters
  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_HEXDUMP_INF(_data, _length, _str)

Writes an INFO level message to the log.

It’s meant to write generic user oriented messages.

Parameters
  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_HEXDUMP_DBG(_data, _length, _str)

Writes a DEBUG level message to the log.

It’s meant to write developer oriented information.

Parameters
  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_INST_HEXDUMP_ERR(_log_inst, _data, _length, _str)

Writes an ERROR hexdump message associated with the instance to the log.

Message is associated with specific instance of the module which has independent filtering settings (if runtime filtering is enabled) and message prefix (<module_name>.<instance_name>). It’s meant to report severe errors, such as those from which it’s not possible to recover.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_INST_HEXDUMP_WRN(_log_inst, _data, _length, _str)

Writes a WARNING level hexdump message associated with the instance to the log.

It’s meant to register messages related to unusual situations that are not necessarily errors.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_INST_HEXDUMP_INF(_log_inst, _data, _length, _str)

Writes an INFO level hexdump message associated with the instance to the log.

It’s meant to write generic user oriented messages.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_INST_HEXDUMP_DBG(_log_inst, _data, _length, _str)

Writes a DEBUG level hexdump message associated with the instance to the log.

It’s meant to write developer oriented information.

Parameters
  • _log_inst – Pointer to the log structure associated with the instance.

  • _data – Pointer to the data to be logged.

  • _length – Length of data (in bytes).

  • _str – Persistent, raw string.

LOG_MODULE_REGISTER(...)

Create module-specific state and register the module with Logger.

This macro normally must be used after including <logging/log.h> to complete the initialization of the module.

Module registration can be skipped in two cases:

  • The module consists of more than one file, and another file invokes this macro. (LOG_MODULE_DECLARE() should be used instead in all of the module’s other files.)

  • Instance logging is used and there is no need to create module entry. In that case LOG_LEVEL_SET() should be used to set log level used within the file.

Macro accepts one or two parameters:

  • module name

  • optional log level. If not provided then default log level is used in the file.

Example usage:

See

LOG_MODULE_DECLARE

Note

The module’s state is defined, and the module is registered, only if LOG_LEVEL for the current source file is non-zero or it is not defined and CONFIG_LOG_DEFAULT_LEVEL is non-zero. In other cases, this macro has no effect.

LOG_MODULE_DECLARE(...)

Macro for declaring a log module (not registering it).

Modules which are split up over multiple files must have exactly one file use LOG_MODULE_REGISTER() to create module-specific state and register the module with the logger core.

The other files in the module should use this macro instead to declare that same state. (Otherwise, LOG_INF() etc. will not be able to refer to module-specific state variables.)

Macro accepts one or two parameters:

  • module name

  • optional log level. If not provided then default log level is used in the file.

Example usage:

See

LOG_MODULE_REGISTER

Note

The module’s state is declared only if LOG_LEVEL for the current source file is non-zero or it is not defined and CONFIG_LOG_DEFAULT_LEVEL is non-zero. In other cases, this macro has no effect.

LOG_LEVEL_SET(level)

Macro for setting log level in the file or function where instance logging API is used.

Parameters
  • level – Level used in file or in function.

Functions

static inline void log_printk(const char *fmt, va_list ap)
static inline char *log_strdup(const char *str)

Logger control

group log_ctrl

Logger control API.

Defines

LOG_CORE_INIT()
LOG_INIT()
LOG_PANIC()
LOG_PROCESS()

Typedefs

typedef log_timestamp_t (*log_timestamp_get_t)(void)

Functions

void log_core_init(void)

Function system initialization of the logger.

Function is called during start up to allow logging before user can explicitly initialize the logger.

void log_init(void)

Function for user initialization of the logger.

void log_thread_set(k_tid_t process_tid)

Function for providing thread which is processing logs.

See CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD.

Note

Function has asserts and has no effect when CONFIG_LOG_PROCESS_THREAD is set.

Parameters
  • process_tid – Process thread id. Used to wake up the thread.

int log_set_timestamp_func(log_timestamp_get_t timestamp_getter, uint32_t freq)

Function for providing timestamp function.

Parameters
  • timestamp_getter – Timestamp function.

  • freq – Timestamping frequency.

Returns

0 on success or error.

void log_panic(void)

Switch the logger subsystem to the panic mode.

Returns immediately if the logger is already in the panic mode.

On panic the logger subsystem informs all backends about panic mode. Backends must switch to blocking mode or halt. All pending logs are flushed after switching to panic mode. In panic mode, all log messages must be processed in the context of the call.

bool log_process(bool bypass)

Process one pending log message.

Parameters
  • bypass – If true message is released without being processed.

Returns

  • true – There is more messages pending to be processed.

  • false – No messages pending.

uint32_t log_buffered_cnt(void)

Return number of buffered log messages.

Returns

Number of currently buffered log messages.

uint32_t log_src_cnt_get(uint32_t domain_id)

Get number of independent logger sources (modules and instances)

Parameters
  • domain_id – Domain ID.

Returns

Number of sources.

const char *log_source_name_get(uint32_t domain_id, uint32_t source_id)

Get name of the source (module or instance).

Parameters
  • domain_id – Domain ID.

  • source_id – Source ID.

Returns

Source name or NULL if invalid arguments.

const char *log_domain_name_get(uint32_t domain_id)

Get name of the domain.

Parameters
  • domain_id – Domain ID.

Returns

Domain name.

uint32_t log_filter_get(struct log_backend const *const backend, uint32_t domain_id, int16_t source_id, bool runtime)

Get source filter for the provided backend.

Parameters
  • backend – Backend instance.

  • domain_id – ID of the domain.

  • source_id – Source (module or instance) ID.

  • runtime – True for runtime filter or false for compiled in.

Returns

Severity level.

uint32_t log_filter_set(struct log_backend const *const backend, uint32_t domain_id, int16_t source_id, uint32_t level)

Set filter on given source for the provided backend.

Parameters
  • backend – Backend instance. NULL for all backends.

  • domain_id – ID of the domain.

  • source_id – Source (module or instance) ID.

  • level – Severity level.

Returns

Actual level set which may be limited by compiled level. If filter was set for all backends then maximal level that was set is returned.

void log_backend_enable(struct log_backend const *const backend, void *ctx, uint32_t level)

Enable backend with initial maximum filtering level.

Parameters
  • backend – Backend instance.

  • ctx – User context.

  • level – Severity level.

void log_backend_disable(struct log_backend const *const backend)

Disable backend.

Parameters
  • backend – Backend instance.

Log message

group log_msg

Log message API.

Defines

LOG_MAX_NARGS

Maximum number of arguments in the standard log entry.

It is limited by 4 bit nargs field in the log message.

LOG_MSG_NARGS_SINGLE_CHUNK

Number of arguments in the log entry which fits in one chunk.

LOG_MSG_NARGS_HEAD_CHUNK

Number of arguments in the head of extended standard log message..

LOG_MSG_HEXDUMP_BYTES_SINGLE_CHUNK

Maximal amount of bytes in the hexdump entry which fits in one chunk.

LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK

Number of bytes in the first chunk of hexdump message if message consists of more than one chunk.

HEXDUMP_BYTES_CONT_MSG

Number of bytes that can be stored in chunks following head chunk in hexdump log message.

ARGS_CONT_MSG
LOG_MSG_TYPE_STD

Flag indicating standard log message.

LOG_MSG_TYPE_HEXDUMP

Flag indicating hexdump log message.

COMMON_PARAM_HDR()

Common part of log message header.

LOG_MSG_HEXDUMP_LENGTH_BITS

Number of bits used for storing length of hexdump log message.

LOG_MSG_HEXDUMP_MAX_LENGTH

Maximum length of log hexdump message.

Typedefs

typedef unsigned long log_arg_t

Log argument type.

Should preferably be equivalent to a native word size.

Functions

void log_msg_pool_init(void)

Function for initialization of the log message pool.

void log_msg_get(struct log_msg *msg)

Function for indicating that message is in use.

Message can be used (read) by multiple users. Internal reference counter is atomically increased. See log_msg_put.

Parameters
  • msg – Message.

void log_msg_put(struct log_msg *msg)

Function for indicating that message is no longer in use.

Internal reference counter is atomically decreased. If reference counter equals 0 message is freed.

Parameters
  • msg – Message.

static inline uint32_t log_msg_domain_id_get(struct log_msg *msg)

Get domain ID of the message.

Parameters
  • msg – Message

Returns

Domain ID.

static inline uint32_t log_msg_source_id_get(struct log_msg *msg)

Get source ID (module or instance) of the message.

Parameters
  • msg – Message

Returns

Source ID.

static inline uint32_t log_msg_level_get(struct log_msg *msg)

Get severity level of the message.

Parameters
  • msg – Message

Returns

Severity message.

static inline uint32_t log_msg_timestamp_get(struct log_msg *msg)

Get timestamp of the message.

Parameters
  • msg – Message

Returns

Timestamp value.

static inline bool log_msg_is_std(struct log_msg *msg)

Check if message is of standard type.

Parameters
  • msg – Message

Returns

  • true – Standard message.

  • false – Hexdump message.

uint32_t log_msg_nargs_get(struct log_msg *msg)

Returns number of arguments in standard log message.

Parameters
  • msg – Standard log message.

Returns

Number of arguments.

log_arg_t log_msg_arg_get(struct log_msg *msg, uint32_t arg_idx)

Gets argument from standard log message.

Parameters
  • msg – Standard log message.

  • arg_idx – Argument index.

Returns

Argument value or 0 if arg_idx exceeds number of arguments in the message.

const char *log_msg_str_get(struct log_msg *msg)

Gets pointer to the unformatted string from standard log message.

Parameters
  • msg – Standard log message.

Returns

Pointer to the string.

struct log_msg *log_msg_hexdump_create(const char *str, const uint8_t *data, uint32_t length)

Allocates chunks for hexdump message and copies the data.

Function resets header and sets following fields:

  • message type

  • length

Note

Allocation and partial filling is combined for performance reasons.

Parameters
  • str – String.

  • data – Data.

  • length – Data length.

Returns

Pointer to allocated head of the message or NULL

void log_msg_hexdump_data_put(struct log_msg *msg, uint8_t *data, size_t *length, size_t offset)

Put data into hexdump log message.

Parameters
  • msg[in] Message.

  • data[in] Data to be copied.

  • length[inout] Input: requested amount. Output: actual amount.

  • offset[in] Offset.

void log_msg_hexdump_data_get(struct log_msg *msg, uint8_t *data, size_t *length, size_t offset)

Get data from hexdump log message.

Parameters
  • msg[in] Message.

  • data[in] Buffer for data.

  • length[inout] Input: requested amount. Output: actual amount.

  • offset[in] Offset.

union log_msg_chunk *log_msg_no_space_handle(void)
union log_msg_chunk *log_msg_chunk_alloc(void)

Allocate single chunk from the pool.

Returns

Pointer to the allocated chunk or NULL if failed to allocate.

static inline struct log_msg *log_msg_create_0(const char *str)

Create standard log message with no arguments.

Function resets header and sets following fields:

  • message type

  • string pointer

Returns

Pointer to allocated head of the message or NULL.

static inline struct log_msg *log_msg_create_1(const char *str, log_arg_t arg1)

Create standard log message with one argument.

Function resets header and sets following fields:

  • message type

  • string pointer

  • number of arguments

  • argument

Parameters
  • str – String.

  • arg1 – Argument.

Returns

Pointer to allocated head of the message or NULL.

static inline struct log_msg *log_msg_create_2(const char *str, log_arg_t arg1, log_arg_t arg2)

Create standard log message with two arguments.

Function resets header and sets following fields:

  • message type

  • string pointer

  • number of arguments

  • arguments

Parameters
  • str – String.

  • arg1 – Argument 1.

  • arg2 – Argument 2.

Returns

Pointer to allocated head of the message or NULL.

static inline struct log_msg *log_msg_create_3(const char *str, log_arg_t arg1, log_arg_t arg2, log_arg_t arg3)

Create standard log message with three arguments.

Function resets header and sets following fields:

  • message type

  • string pointer

  • number of arguments

  • arguments

Parameters
  • str – String.

  • arg1 – Argument 1.

  • arg2 – Argument 2.

  • arg3 – Argument 3.

Returns

Pointer to allocated head of the message or NULL.

struct log_msg *log_msg_create_n(const char *str, log_arg_t *args, uint32_t nargs)

Create standard log message with variable number of arguments.

Function resets header and sets following fields:

  • message type

  • string pointer

  • number of arguments

  • arguments

Parameters
  • str – String.

  • args – Array with arguments.

  • nargs – Number of arguments.

Returns

Pointer to allocated head of the message or NULL.

uint32_t log_msg_mem_get_free(void)

Get number of free blocks from the log mem pool.

uint32_t log_msg_mem_get_used(void)

Get number of used blocks from the log mem pool.

uint32_t log_msg_mem_get_max_used(void)

Get max used blocks from the log mem pool.

struct log_msg_ids
#include <log_msg.h>

Part of log message header identifying source and level.

Public Members

uint16_t level

Severity.

uint16_t domain_id

Originating domain.

uint16_t source_id

Source ID.

struct log_msg_generic_hdr
#include <log_msg.h>

Part of log message header common to standard and hexdump log message.

struct log_msg_std_hdr
#include <log_msg.h>

Part of log message header specific to standard log message.

struct log_msg_hexdump_hdr
#include <log_msg.h>

Part of log message header specific to hexdump log message.

struct log_msg_hdr
#include <log_msg.h>

Log message header structure

Public Members

atomic_t ref_cnt

Reference counter for tracking message users.

struct log_msg_ids ids

Identification part of the message.

uint32_t timestamp

Timestamp.

union log_msg_hdr_params
#include <log_msg.h>

Public Members

struct log_msg_generic_hdr generic
struct log_msg_std_hdr std
struct log_msg_hexdump_hdr hexdump
uint16_t raw
union log_msg_head_data
#include <log_msg.h>

Data part of log message.

Public Members

log_arg_t args[3U]
uint8_t bytes[(3U * sizeof(log_arg_t))]
struct log_msg_ext_head_data
#include <log_msg.h>

Data part of extended log message.

union log_msg_ext_head_data_data
#include <log_msg.h>

Public Members

log_arg_t args[(3U - (sizeof(void*) / sizeof(log_arg_t)))]
uint8_t bytes[((3U * sizeof(log_arg_t)) - sizeof(void*))]
struct log_msg
#include <log_msg.h>

Log message structure.

Public Members

struct log_msg *next

Used by logger core list.

struct log_msg_hdr hdr

Message header.

union log_msg.log_msg_data payload

Message data.

union log_msg_data
#include <log_msg.h>

Public Members

union log_msg_head_data single
struct log_msg_ext_head_data ext
struct log_msg_cont
#include <log_msg.h>

Chunks following message head when message is extended.

Public Members

struct log_msg_cont *next

Pointer to the next chunk.

union log_msg_cont_data
#include <log_msg.h>

Public Members

log_arg_t args[((sizeof(struct log_msg) - sizeof(void*)) / sizeof(log_arg_t))]
uint8_t bytes[(sizeof(struct log_msg) - sizeof(void*))]
union log_msg_chunk
#include <log_msg.h>

Log message.

Public Members

struct log_msg head
struct log_msg_cont cont

Logger backend interface

group log_backend

Logger backend interface.

Defines

LOG_BACKEND_DEFINE(_name, _api, _autostart, ...)

Macro for creating a logger backend instance.

Parameters
  • _name – Name of the backend instance.

  • _api – Logger backend API.

  • _autostart – If true backend is initialized and activated together with the logger subsystem.

  • ... – Optional context.

Functions

static inline void log_backend_put(const struct log_backend *const backend, struct log_msg *msg)

Put message with log entry to the backend.

Parameters
  • backend[in] Pointer to the backend instance.

  • msg[in] Pointer to message with log entry.

static inline void log_backend_msg2_process(const struct log_backend *const backend, union log_msg2_generic *msg)
static inline void log_backend_put_sync_string(const struct log_backend *const backend, struct log_msg_ids src_level, uint32_t timestamp, const char *fmt, va_list ap)

Synchronously process log message.

Parameters
  • backend[in] Pointer to the backend instance.

  • src_level[in] Message details.

  • timestamp[in] Timestamp.

  • fmt[in] Log string.

  • ap[in] Log string arguments.

static inline void log_backend_put_sync_hexdump(const struct log_backend *const backend, struct log_msg_ids src_level, uint32_t timestamp, const char *metadata, const uint8_t *data, uint32_t len)

Synchronously process log hexdump_message.

Parameters
  • backend[in] Pointer to the backend instance.

  • src_level[in] Message details.

  • timestamp[in] Timestamp.

  • metadata[in] Raw string associated with the data.

  • data[in] Data.

  • len[in] Data length.

static inline void log_backend_dropped(const struct log_backend *const backend, uint32_t cnt)

Notify backend about dropped log messages.

Function is optional.

Parameters
  • backend[in] Pointer to the backend instance.

  • cnt[in] Number of dropped logs since last notification.

static inline void log_backend_panic(const struct log_backend *const backend)

Reconfigure backend to panic mode.

Parameters
  • backend[in] Pointer to the backend instance.

static inline void log_backend_id_set(const struct log_backend *const backend, uint8_t id)

Set backend id.

Note

It is used internally by the logger.

Parameters
  • backend – Pointer to the backend instance.

  • id – ID.

static inline uint8_t log_backend_id_get(const struct log_backend *const backend)

Get backend id.

Note

It is used internally by the logger.

Parameters
  • backend[in] Pointer to the backend instance.

Returns

Id.

static inline const struct log_backend *log_backend_get(uint32_t idx)

Get backend.

Parameters
  • idx[in] Pointer to the backend instance.

Returns

Pointer to the backend instance.

static inline int log_backend_count_get(void)

Get number of backends.

Returns

Number of backends.

static inline void log_backend_activate(const struct log_backend *const backend, void *ctx)

Activate backend.

Parameters
  • backend[in] Pointer to the backend instance.

  • ctx[in] User context.

static inline void log_backend_deactivate(const struct log_backend *const backend)

Deactivate backend.

Parameters
  • backend[in] Pointer to the backend instance.

static inline bool log_backend_is_active(const struct log_backend *const backend)

Check state of the backend.

Parameters
  • backend[in] Pointer to the backend instance.

Returns

True if backend is active, false otherwise.

struct log_backend_api
#include <log_backend.h>

Logger backend API.

struct log_backend_control_block
#include <log_backend.h>

Logger backend control block.

struct log_backend
#include <log_backend.h>

Logger backend structure.

Logger output formatting

group log_output

Log output API.

Defines

LOG_OUTPUT_FLAG_COLORS

Flag forcing ANSI escape code colors, red (errors), yellow (warnings).

LOG_OUTPUT_FLAG_TIMESTAMP

Flag forcing timestamp.

LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP

Flag forcing timestamp formatting.

LOG_OUTPUT_FLAG_LEVEL

Flag forcing severity level prefix.

LOG_OUTPUT_FLAG_CRLF_NONE

Flag preventing the logger from adding CR and LF characters.

LOG_OUTPUT_FLAG_CRLF_LFONLY

Flag forcing a single LF character for line breaks.

LOG_OUTPUT_FLAG_FORMAT_SYSLOG

Flag forcing syslog format specified in RFC 5424.

LOG_OUTPUT_FLAG_FORMAT_SYST

Flag forcing syslog format specified in mipi sys-t.

LOG_OUTPUT_DEFINE(_name, _func, _buf, _size)

Create log_output instance.

Parameters
  • _name – Instance name.

  • _func – Function for processing output data.

  • _buf – Pointer to the output buffer.

  • _size – Size of the output buffer.

Typedefs

typedef int (*log_output_func_t)(uint8_t *buf, size_t size, void *ctx)

Prototype of the function processing output data.

Note

If the log output function cannot process all of the data, it is its responsibility to mark them as dropped or discarded by returning the corresponding number of bytes dropped or discarded to the caller.

Parameters
  • buf – The buffer data.

  • size – The buffer size.

  • ctx – User context.

Returns

Number of bytes processed, dropped or discarded.

Functions

void log_output_msg_process(const struct log_output *output, struct log_msg *msg, uint32_t flags)

Process log messages to readable strings.

Function is using provided context with the buffer and output function to process formatted string and output the data.

Parameters
  • output – Pointer to the log output instance.

  • msg – Log message.

  • flags – Optional flags.

void log_output_msg2_process(const struct log_output *log_output, struct log_msg2 *msg, uint32_t flags)

Process log messages v2 to readable strings.

Function is using provided context with the buffer and output function to process formatted string and output the data.

Parameters
  • log_output – Pointer to the log output instance.

  • msg – Log message.

  • flags – Optional flags.

void log_output_string(const struct log_output *output, struct log_msg_ids src_level, uint32_t timestamp, const char *fmt, va_list ap, uint32_t flags)

Process log string.

Function is formatting provided string adding optional prefixes and postfixes.

Parameters
  • output – Pointer to log_output instance.

  • src_level – Log source and level structure.

  • timestamp – Timestamp.

  • fmt – String.

  • ap – String arguments.

  • flags – Optional flags.

void log_output_hexdump(const struct log_output *output, struct log_msg_ids src_level, uint32_t timestamp, const char *metadata, const uint8_t *data, uint32_t length, uint32_t flags)

Process log hexdump.

Function is formatting provided hexdump adding optional prefixes and postfixes.

Parameters
  • output – Pointer to log_output instance.

  • src_level – Log source and level structure.

  • timestamp – Timestamp.

  • metadata – String.

  • data – Data.

  • length – Data length.

  • flags – Optional flags.

void log_output_dropped_process(const struct log_output *output, uint32_t cnt)

Process dropped messages indication.

Function prints error message indicating lost log messages.

Parameters
  • output – Pointer to the log output instance.

  • cnt – Number of dropped messages.

void log_output_flush(const struct log_output *output)

Flush output buffer.

Parameters
  • output – Pointer to the log output instance.

static inline void log_output_ctx_set(const struct log_output *output, void *ctx)

Function for setting user context passed to the output function.

Parameters
  • output – Pointer to the log output instance.

  • ctx – User context.

static inline void log_output_hostname_set(const struct log_output *output, const char *hostname)

Function for setting hostname of this device.

Parameters
  • output – Pointer to the log output instance.

  • hostname – Hostname of this device

void log_output_timestamp_freq_set(uint32_t freq)

Set timestamp frequency.

Parameters
  • freq – Frequency in Hz.

uint64_t log_output_timestamp_to_us(uint32_t timestamp)

Convert timestamp of the message to us.

Parameters
  • timestamp – Message timestamp

Returns

Timestamp value in us.

struct log_output_control_block
#include <log_output.h>
struct log_output
#include <log_output.h>

Log_output instance structure.