pw_log_string#
pw_log_string
is a partial backend for pw_log
. This backend fowards the
PW_LOG_*
macros to the pw_log_string:handler
facade which is backed by
a C API. pw_log_string:handler
does not implement the full C API, leaving
projects to provide their own implementation of
pw_log_string_HandleMessageVaList
. See pw_log_basic
for a similar
pw_log
backend that also provides an implementation.
As this module passes the log message, file name, and module name as a string to the handler function, it’s relatively expensive and not well suited for space-constrained devices. This module is oriented towards usage on a host (e.g. a simulated device).
Note that pw_log_string:handler
may be used even when it’s not used
as the backend for pw_log
via pw_log_string
. For example it can be
useful to mix tokenized and string based logging in case you have a C ABI where
tokenization can not be used on the other side.
Get started (GN)#
This section outlines how to implement a pw_log_string
backend in a
GN-based project.
Note
The example code was written for a host target running on Linux.
Invoke a logging macro#
Call one of the pw_log macros in your project code:
/* //src/app.cc */
#include <unistd.h>
#include "pw_log/log.h"
int main() {
while (true) {
PW_LOG_INFO("Hello, world!");
sleep(5);
}
return 0;
}
Implement the logging function#
Implement pw_log_string_HandleMessageVaList()
in C. Macros like
PW_LOG()
hand off the actual logging implementation to this
function.
The function signature of your implementation must match the one specified by Pigweed.
The example code below just logs most of the available information to
stdout
:
/* //src/pw_log_string_backend.c */
#include <stdio.h>
#include <stdarg.h>
void pw_log_string_HandleMessageVaList(int level,
unsigned int flags,
const char* module_name,
const char* file_name,
int line_number,
const char* message,
va_list args) {
printf("Entering custom pw_log_string backend...\n");
printf("%d\n", level);
printf("%u\n", flags);
printf("%s\n", module_name);
printf("%s\n", file_name);
printf("%d\n", line_number);
printf("%s\n", message);
if (args) { /* Do something with your args here... */ }
printf("Exiting custom pw_log_string backend...\n\n");
}
What exactly pw_log_string_HandleMessageVaList()
should do is entirely up to
the implementation. The log handler in pw_log_basic
is one example, but it’s
also possible to encode as protobuf and send over a TCP port, write to a file,
or even blink an LED to log as morse code.
Create source sets#
Use pw_source_set
to create a source set for your logging
implementation. Do not use GN’s built-in source_set
feature.
# //src/BUILD.gn
...
pw_source_set("pw_log_string_backend") {
sources = [ "pw_log_string_backend.c" ]
}
pw_source_set("pw_log_string_backend.impl") {
sources = []
}
...
The empty pw_log_string_backend.impl
source set prevents circular
dependencies. See the comment for group("impl")
in //pw_log/BUILD.gn
for more context.
Configure backends#
Update your target toolchain configuration file:
Set
pw_log_BACKEND
todir_pw_log_string
Point
pw_log_string_HANDLER_BACKEND
to your source set that implementspw_log_string_HandleMessageVaList()
Update pw_build_LINK_DEPS to include
"$dir_pw_log:impl"
and"$dir_pw_log_string:handler:impl"
# //targets/my_target/target_toolchains.gni
...
my_target = {
...
my_toolchain = {
name = "my_toolchain"
defaults = {
...
pw_log_BACKEND = dir_pw_log_string
pw_log_string_HANDLER_BACKEND = "//src:pw_log_string_backend"
pw_build_LINK_DEPS = [
"$dir_pw_log:impl",
"$dir_pw_log_string:handler.impl",
...
]
...
}
}
}
...
(Optional) Implement message handler#
Optionally provide your own implementation of PW_LOG_STRING_HANDLE_MESSAGE
which invokes pw_log_string_HANDLER_BACKEND
with your selected arguments.
assert
wrapper#
A wrapper for assert
is provided that redirects calls to the pw_log_string
handler. This can be used to replace all usage of assert
in a Newlib binary
at link time.
API reference#
- void pw_log_string_HandleMessageVaList(
- int level,
- unsigned int flags,
- const char *module_name,
- const char *file_name,
- int line_number,
- const char *message,
- va_list args,
Logs a message with the listed attributes. This must be implemented by the backend.