Logging¶
Mynewt log package supports logging of information within a Mynewt application. It allows packages to define their own log streams with separate names. It also allows an application to control the output destination of logs.
Description¶
In the Mynewt OS, the log package comes in two versions:
The
sys/log/full
package implements the complete log functionality and API.The
sys/log/stub
package implements stubs for the API.
Both packages export the log
API, and any package that uses the log
API must list log
as a requirement in its pkg.yml
file as
follows:
pkg.req_apis:
- log
The application’s pkg.yml
file specifies the version of the log
package to use. A project that requires the full logging capability must
list the sys/log/full
package as a dependency in its pkg.yml
file:
pkg.deps:
- "@apache-mynewt-core/sys/log/full"
You can use the sys/log/stub
package if you want to build your
application without logging to reduce code size.
Syscfg Settings¶
The LOG_LEVEL
syscfg setting allows you to specify the level of logs
to enable in your application. Only logs for levels higher or equal to
the value of LOG_LEVEL
are enabled. The amount of logs you include
affects your application code size. LOG_LEVEL: 0
specifies
LOG_LEVEL_DEBUG and includes all logs. You set LOG_LEVEL: 255
to
disable all logging. The #defines
for the log levels are specified
in the sys/log/full/include/log/log.h
file. For example the
following setting corresponds to LOG_LEVEL_ERROR:
syscfg.vals:
LOG_LEVEL: 3
The LOG_LEVEL
setting applies to all modules registered with the log
package.
Log Handler¶
To use logs, a log handler that handles the I/O from the log is required. The log package comes with three pre-built log handlers:
console – streams log events directly to the console port. Does not support walking and reading.
cbmem – writes/reads log events to a circular buffer. Supports walking and reading for access by newtmgr and shell commands.
fcb – writes/reads log events to a flash circular buffer. Supports walking and reading for access by newtmgr and shell commands.
In addition, it is possible to create custom log handlers for other methods. Examples may include
Flash file system
Flat flash buffer
Streamed over some other interface
To use logging, you typically do not need to create your own log handler. You can use one of the pre-built ones.
A package or an application must define a variable of type
struct log
and register a log handler for it with the log package.
It must call the log_register()
function to specify the log handler
to use:
log_register(char *name, struct log *log, const struct log_handler *lh, void *arg, uint8_t level)
The parameters are:
name
- Name of the log stream.log
- Log instance to register,lh
- Pointer to the log handler. You can specify one of the pre-built ones:&log_console_handler
for console&log_cbm_handler
for circular buffer&log_fcb_handler
for flash circular buffer
arg
- Opaque argument that the specified log handler uses. The value of this argument depends on the log handler you specify:NULL for the
log_console_handler
.Pointer to an initialized
cbmem
structure (seeutil/cbmem
package) for thelog_cbm_handler
.Pointer to an initialized
fcb_log
structure (seefs/fcb
package) for thelog_fcb_handler
.
Typically, a package that uses logging defines a global variable, such
as my_package_log
, of type struct log
. The package can call the
log_register()
function with default values, but usually an
application will override the logging properties and where to log to.
There are two ways a package can allow an application to override the
values:
Define system configuration settings that an application can set and the package can then call the
log_register()
function with the configuration values.Make the
my_package_log
variable external and let the application call thelog_register()
function to specify a log handler for its specific purpose.
Configuring Logging for Packages that an Application Uses¶
Here is an example of how an application can set the log handlers for the logs of the packages that the application includes.
In this example, the package1
package defines the variable
package1_log
of type struct log
and externs the variable.
Similarly, the package2
package defines the variable
package2_log
and externs the variable. The application sets logs for
package1
to use console and sets logs for package2
to use a
circular buffer.
#include <package1/package1.h>
#include <package2/package2.h>
#include <util/cbmem.h>
#include <log/log.h>
static uint32_t cbmem_buf[MAX_CBMEM_BUF];
static struct cbmem cbmem;
void app_log_init(void)
{
log_register("package1_log", &package1_log, &log_console_handler, NULL, LOG_SYSLEVEL);
cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
log_register("package2_log", &package2_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL);
}
Implementing a Package that Uses Logging¶
This example shows how a package logs to console. The package registers
default logging properties to use the console, but allows an application
to override the values. It defines the my_package_log
variable and
makes it external so an application can override log handler.
Make the my_package_log
variable external:
/* my_package.h*/
/* pick a unique name here */
extern struct log my_package_log;
Define the my_package_log
variable and register the console log
handler:
/* my_package.c */
struct log my_package_log;
{
...
/* register my log with a name to the system */
log_register("log", &my_package_log, &log_console_handler, NULL, LOG_LEVEL_DEBUG);
LOG_DEBUG(&my_package_log, LOG_MODULE_DEFAULT, "bla");
LOG_DEBUG(&my_package_log, LOG_MODULE_DEFAULT, "bab");
}
Log API and Log Levels¶
Defines
-
LOG_ENTRY_HDR_SIZE
¶
-
LOG_MODULE_STR
(module)¶
-
LOG_DEBUG
(__l, __mod, ...)¶
-
LOG_INFO
(__l, __mod, ...)¶
-
LOG_WARN
(__l, __mod, ...)¶
-
LOG_ERROR
(__l, __mod, ...)¶
-
LOG_CRITICAL
(__l, __mod, ...)¶
-
LOG_STATS_INC
(log, name)¶
-
LOG_STATS_INCN
(log, name, cnt)¶
Typedefs
-
typedef int (*
log_walk_func_t
)(struct log*, struct log_offset *log_offset, void *dptr, uint16_t len)¶
-
typedef int (*
log_walk_body_func_t
)(struct log *log, struct log_offset *log_offset, const struct log_entry_hdr *hdr, void *dptr, uint16_t len)¶
-
typedef int (*
lh_read_mbuf_func_t
)(struct log*, void *dptr, struct os_mbuf *om, uint16_t offset, uint16_t len)¶
-
typedef int (*
lh_append_body_func_t
)(struct log *log, const struct log_entry_hdr *hdr, const void *body, int body_len)¶
-
typedef int (*
lh_append_mbuf_body_func_t
)(struct log *log, const struct log_entry_hdr *hdr, const struct os_mbuf *om)¶
-
typedef int (*
lh_walk_func_t
)(struct log*, log_walk_func_t walk_func, struct log_offset *log_offset)¶
-
typedef int (*
lh_storage_info_func_t
)(struct log*, struct log_storage_info*)¶
Functions
-
void
log_init
(void)¶
-
uint8_t
log_module_register
(uint8_t id, const char *name)¶
-
const char *
log_module_get_name
(uint8_t id)¶
-
int
log_register
(char *name, struct log *log, const struct log_handler*, void *arg, uint8_t level)¶
-
void
log_set_append_cb
(struct log *log, log_append_cb *cb)¶ Configures the given log with the specified append callback.
A log’s append callback is executed each time an entry is appended to the log.
- Parameters
log
: The log to configure.cb
: The callback to associate with the log.
-
struct log *
log_find
(const char *name)¶ Searches the list of registered logs for one with the specified name.
- Return
The sought after log if found, NULL otherwise.
- Parameters
name
: The name of the log to search for.
-
int
log_append_typed
(struct log *log, uint8_t module, uint8_t level, uint8_t etype, void *data, uint16_t len)¶ Writes the raw contents of a flat buffer to the specified log.
NOTE: The flat buffer must have an initial padding of length
LOG_ENTRY_HDR_SIZE
. This padding is not reflected in the specified length. So, to log the string “abc”, you should pass the following arguments to this function:data: <padding>abc (total of `LOG_ENTRY_HDR_SIZE`+3 bytes.) len: 3
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The log module of the entry to write.level
: The severity of the log entry to write.etype
: The type of data being written; one of theLOG_ETYPE_[...]
constants.data
: The flat buffer to write.len
: The number of bytes in the message body.
-
int
log_append_mbuf_typed_no_free
(struct log *log, uint8_t module, uint8_t level, uint8_t etype, struct os_mbuf **om_ptr)¶ Logs the contents of the provided mbuf, only freeing the mbuf on failure.
Logs the contents of the provided mbuf, only freeing the mbuf on failure. On success, the mbuf remains allocated, but its structure may have been modified by pullup operations. The updated mbuf address is passed back to the caller via a write to the supplied mbuf pointer-to-pointer.
NOTE: The mbuf must have an initial padding of length
LOG_ENTRY_HDR_SIZE
. So, to log the string “abc”, you should pass an mbuf with the following characteristics:om_data: <padding>abc om_len: `LOG_ENTRY_HDR_SIZE` + 3
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The module ID of the entry to write.level
: The severity of the entry to write; one of theLOG_LEVEL_[...]
constants.etype
: The type of data to write; one of theLOG_ETYPE_[...]
constants.om_ptr
: Indirectly points to the mbuf to write. This function updates the mbuf address if it changes.
-
int
log_append_mbuf_typed
(struct log *log, uint8_t module, uint8_t level, uint8_t etype, struct os_mbuf *om)¶ Logs the contents of the provided mbuf.
Logs the contents of the provided mbuf. This function always frees the mbuf regardless of the outcome.
NOTE: The mbuf must have an initial padding of length
LOG_ENTRY_HDR_SIZE
. So, to log the string “abc”, you should pass an mbuf with the following characteristics:om_data: <padding>abc om_len: `LOG_ENTRY_HDR_SIZE` + 3
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The module ID of the entry to write.level
: The severity of the entry to write; one of theLOG_LEVEL_[...]
constants.etype
: The type of data to write; one of theLOG_ETYPE_[...]
constants.om
: The mbuf to write.
-
int
log_append_body
(struct log *log, uint8_t module, uint8_t level, uint8_t etype, const void *body, uint16_t body_len)¶ Writes the contents of a flat buffer to the specified log.
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The log module of the entry to write.level
: The severity of the log entry to write.etype
: The type of data being written; one of theLOG_ETYPE_[...]
constants.data
: The flat buffer to write.len
: The number of bytes in the message body.
-
int
log_append_mbuf_body_no_free
(struct log *log, uint8_t module, uint8_t level, uint8_t etype, struct os_mbuf *om)¶ Logs the contents of the provided mbuf, only freeing the mbuf on failure.
Logs the contents of the provided mbuf, only freeing the mbuf on failure. On success, the mbuf remains allocated, but its structure may have been modified by pullup operations. The updated mbuf address is passed back to the caller via a write to the supplied mbuf pointer-to-pointer.
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The module ID of the entry to write.level
: The severity of the entry to write; one of theLOG_LEVEL_[...]
constants.etype
: The type of data to write; one of theLOG_ETYPE_[...]
constants.om_ptr
: Indirectly points to the mbuf to write. This function updates the mbuf address if it changes.
-
int
log_append_mbuf_body
(struct log *log, uint8_t module, uint8_t level, uint8_t etype, struct os_mbuf *om)¶ Logs the contents of the provided mbuf.
Logs the contents of the provided mbuf. This function always frees the mbuf regardless of the outcome.
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The module ID of the entry to write.level
: The severity of the entry to write; one of theLOG_LEVEL_[...]
constants.etype
: The type of data to write; one of theLOG_ETYPE_[...]
constants.om
: The mbuf to write.
-
void
log_console_init
(void)¶
-
static inline int
log_append
(struct log *log, uint8_t module, uint8_t level, void *data, uint16_t len)¶ Writes the raw contents of a flat buffer to the specified log.
NOTE: The flat buffer must have an initial padding of length
LOG_ENTRY_HDR_SIZE
. This padding is not reflected in the specified length. So, to log the string “abc”, you should pass the following arguments to this function:data: <padding>abc (total of `LOG_ENTRY_HDR_SIZE`+3 bytes.) len: 3
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The log module of the entry to write.level
: The severity of the log entry to write.data
: The flat buffer to write.len
: The number of byte in the message body.
-
static inline int
log_append_mbuf_no_free
(struct log *log, uint8_t module, uint8_t level, struct os_mbuf **om)¶ Logs the contents of the provided mbuf, only freeing the mbuf on failure.
Logs the contents of the provided mbuf, only freeing the mbuf on failure. On success, the mbuf remains allocated, but its structure may have been modified by pullup operations. The updated mbuf address is passed back to the caller via a write to the supplied mbuf pointer-to-pointer.
NOTE: The mbuf must have an initial padding of length
LOG_ENTRY_HDR_SIZE
. So, to log the string “abc”, you should pass an mbuf with the following characteristics:om_data: <padding>abc om_len: `LOG_ENTRY_HDR_SIZE` + 3
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The module ID of the entry to write.level
: The severity of the entry to write; one of theLOG_LEVEL_[...]
constants.om_ptr
: Indirectly points to the mbuf to write. This function updates the mbuf address if it changes.
-
static inline int
log_append_mbuf
(struct log *log, uint8_t module, uint8_t level, struct os_mbuf *om)¶ Logs the contents of the provided mbuf.
Logs the contents of the provided mbuf. This function always frees the mbuf regardless of the outcome.
NOTE: The mbuf must have an initial padding of length
LOG_ENTRY_HDR_SIZE
. So, to log the string “abc”, you should pass an mbuf with the following characteristics:om_data: <padding>abc om_len: `LOG_ENTRY_HDR_SIZE` + 3
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to write to.module
: The module ID of the entry to write.level
: The severity of the entry to write; one of theLOG_LEVEL_[...]
constants.om
: The mbuf to write.
-
int
log_read_hdr
(struct log *log, void *dptr, struct log_entry_hdr *hdr)¶ Reads a single log entry header.
- Return
0 on success; nonzero on failure.
- Parameters
log
: The log to read from.dptr
: Medium-specific data describing the area to read from; typically obtained by a call tolog_walk
.hdr
: The destination header to read into.
-
int
log_read_body
(struct log *log, void *dptr, void *buf, uint16_t off, uint16_t len)¶ Reads data from the body of a log entry into a flat buffer.
- Return
The number of bytes actually read on success; -1 on failure.
- Parameters
log
: The log to read from.dptr
: Medium-specific data describing the area to read from; typically obtained by a call tolog_walk
.buf
: The destination buffer to read into.off
: The offset within the log entry at which to start the read.len
: The number of bytes to read.
-
int
log_read_mbuf_body
(struct log *log, void *dptr, struct os_mbuf *om, uint16_t off, uint16_t len)¶ Reads data from the body of a log entry into an mbuf.
- Return
The number of bytes actually read on success; -1 on failure.
- Parameters
log
: The log to read from.dptr
: Medium-specific data describing the area to read from; typically obtained by a call tolog_walk
.om
: The destination mbuf to read into.off
: The offset within the log entry at which to start the read.len
: The number of bytes to read.
-
int
log_walk
(struct log *log, log_walk_func_t walk_func, struct log_offset *log_offset)¶
-
int
log_walk_body
(struct log *log, log_walk_body_func_t walk_body_func, struct log_offset *log_offset)¶ Applies a callback to each message in the specified log.
Similar to
log_walk
, except it passes the message header and body separately to the callback.- Return
0 if the walk completed successfully; nonzero on error or if the walk was aborted.
- Parameters
log
: The log to iterate.walk_body_func
: The function to apply to each log entry.log_offset
: Specifies the range of entries to process. Entries not matching these criteria are skipped during the walk.
-
uint8_t
log_level_get
(uint8_t module)¶ Retrieves the globally configured minimum log level for the specified module ID.
Writes with a level less than the module’s minimum level are discarded.
- Return
The configured minimum level, or 0 (LOG_LEVEL_DEBUG) if unconfigured.
- Parameters
module
: The module whose level should be retrieved.
-
int
log_level_set
(uint8_t module, uint8_t level)¶ Sets the globally configured minimum log level for the specified module ID.
Writes with a level less than the module’s minimum level are discarded.
- Parameters
module
: The module to configure.level
: The minimum level to assign to the module (0-15, inclusive).
-
int
log_storage_info
(struct log *log, struct log_storage_info *info)¶ Return information about log storage.
This return information about size and usage of storage on top of which log instance is created.
- Return
0 on success, error code otherwise
- Parameters
log
: The log to query.info
: The destination to write information to.
-
int
log_set_watermark
(struct log *log, uint32_t index)¶ Set watermark on log.
This sets watermark on log item with given index. This information is used to calculate size of entries which were logged after watermark item, i.e. unread items. The watermark is stored persistently for each log.
- Return
0 on success, error code otherwise.
- Parameters
log
: The log to set watermark on.index
: The index of a watermarked item.
-
int
log_nmgr_register_group
(void)¶
Variables
-
const struct log_handler
log_console_handler
¶
-
const struct log_handler
log_cbmem_handler
¶
-
const struct log_handler
log_fcb_handler
¶
-
const struct log_handler
log_fcb_slot1_handler
¶
-
struct
log_offset
¶ - #include <log.h>
Used for walks and reads; indicates part of log to access.
-
struct
log_storage_info
- #include <log.h>
Log storage information.
-
struct
log_handler
¶ - #include <log.h>
Public Members
-
int
log_type
¶
-
lh_read_func_t
log_read
¶
-
lh_read_mbuf_func_t
log_read_mbuf
¶
-
lh_append_func_t
log_append
¶
-
lh_append_body_func_t
log_append_body
¶
-
lh_append_mbuf_func_t
log_append_mbuf
¶
-
lh_append_mbuf_body_func_t
log_append_mbuf_body
¶
-
lh_walk_func_t
log_walk
¶
-
lh_flush_func_t
log_flush
¶
-
lh_storage_info_func_t
log_storage_info
¶
-
lh_set_watermark_func_t
log_set_watermark
¶
-
lh_registered_func_t
log_registered
¶
-
int
-
struct
log
¶ - #include <log.h>
Public Functions
-
STAILQ_ENTRY (log) l_next
-
STATS_SECT_DECL (logs) l_stats
-