1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_log_string: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker============= 4*61c4878aSAndroid Build Coastguard Workerpw_log_string 5*61c4878aSAndroid Build Coastguard Worker============= 6*61c4878aSAndroid Build Coastguard Worker``pw_log_string`` is a partial backend for ``pw_log``. This backend fowards the 7*61c4878aSAndroid Build Coastguard Worker``PW_LOG_*`` macros to the ``pw_log_string:handler`` facade which is backed by 8*61c4878aSAndroid Build Coastguard Workera C API. ``pw_log_string:handler`` does not implement the full C API, leaving 9*61c4878aSAndroid Build Coastguard Workerprojects to provide their own implementation of 10*61c4878aSAndroid Build Coastguard Worker``pw_log_string_HandleMessageVaList``. See ``pw_log_basic`` for a similar 11*61c4878aSAndroid Build Coastguard Worker``pw_log`` backend that also provides an implementation. 12*61c4878aSAndroid Build Coastguard Worker 13*61c4878aSAndroid Build Coastguard WorkerAs this module passes the log message, file name, and module name as a string to 14*61c4878aSAndroid Build Coastguard Workerthe handler function, it's relatively expensive and not well suited for 15*61c4878aSAndroid Build Coastguard Workerspace-constrained devices. This module is oriented towards usage on a host 16*61c4878aSAndroid Build Coastguard Worker(e.g. a simulated device). 17*61c4878aSAndroid Build Coastguard Worker 18*61c4878aSAndroid Build Coastguard WorkerNote that ``pw_log_string:handler`` may be used even when it's not used 19*61c4878aSAndroid Build Coastguard Workeras the backend for ``pw_log`` via ``pw_log_string``. For example it can be 20*61c4878aSAndroid Build Coastguard Workeruseful to mix tokenized and string based logging in case you have a C ABI where 21*61c4878aSAndroid Build Coastguard Workertokenization can not be used on the other side. 22*61c4878aSAndroid Build Coastguard Worker 23*61c4878aSAndroid Build Coastguard Worker.. _module-pw_log_string-get-started-gn: 24*61c4878aSAndroid Build Coastguard Worker 25*61c4878aSAndroid Build Coastguard Worker---------------- 26*61c4878aSAndroid Build Coastguard WorkerGet started (GN) 27*61c4878aSAndroid Build Coastguard Worker---------------- 28*61c4878aSAndroid Build Coastguard WorkerThis section outlines how to implement a ``pw_log_string`` backend in a 29*61c4878aSAndroid Build Coastguard WorkerGN-based project. 30*61c4878aSAndroid Build Coastguard Worker 31*61c4878aSAndroid Build Coastguard Worker.. note:: 32*61c4878aSAndroid Build Coastguard Worker The example code was written for a :ref:`host <target-host>` target running 33*61c4878aSAndroid Build Coastguard Worker on Linux. 34*61c4878aSAndroid Build Coastguard Worker 35*61c4878aSAndroid Build Coastguard WorkerInvoke a logging macro 36*61c4878aSAndroid Build Coastguard Worker====================== 37*61c4878aSAndroid Build Coastguard WorkerCall one of the :ref:`pw_log macros <module-pw_log-macros>` in your project 38*61c4878aSAndroid Build Coastguard Workercode: 39*61c4878aSAndroid Build Coastguard Worker 40*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 41*61c4878aSAndroid Build Coastguard Worker :emphasize-lines: 9 42*61c4878aSAndroid Build Coastguard Worker 43*61c4878aSAndroid Build Coastguard Worker /* //src/app.cc */ 44*61c4878aSAndroid Build Coastguard Worker 45*61c4878aSAndroid Build Coastguard Worker #include <unistd.h> 46*61c4878aSAndroid Build Coastguard Worker 47*61c4878aSAndroid Build Coastguard Worker #include "pw_log/log.h" 48*61c4878aSAndroid Build Coastguard Worker 49*61c4878aSAndroid Build Coastguard Worker int main() { 50*61c4878aSAndroid Build Coastguard Worker while (true) { 51*61c4878aSAndroid Build Coastguard Worker PW_LOG_INFO("Hello, world!"); 52*61c4878aSAndroid Build Coastguard Worker sleep(5); 53*61c4878aSAndroid Build Coastguard Worker } 54*61c4878aSAndroid Build Coastguard Worker return 0; 55*61c4878aSAndroid Build Coastguard Worker } 56*61c4878aSAndroid Build Coastguard Worker 57*61c4878aSAndroid Build Coastguard WorkerImplement the logging function 58*61c4878aSAndroid Build Coastguard Worker============================== 59*61c4878aSAndroid Build Coastguard WorkerImplement :cpp:func:`pw_log_string_HandleMessageVaList()` in C. Macros like 60*61c4878aSAndroid Build Coastguard Worker:cpp:func:`PW_LOG()` hand off the actual logging implementation to this 61*61c4878aSAndroid Build Coastguard Workerfunction. 62*61c4878aSAndroid Build Coastguard Worker 63*61c4878aSAndroid Build Coastguard WorkerThe function signature of your implementation must match the one specified by 64*61c4878aSAndroid Build Coastguard WorkerPigweed. 65*61c4878aSAndroid Build Coastguard Worker 66*61c4878aSAndroid Build Coastguard WorkerThe example code below just logs most of the available information to 67*61c4878aSAndroid Build Coastguard Worker``stdout``: 68*61c4878aSAndroid Build Coastguard Worker 69*61c4878aSAndroid Build Coastguard Worker.. code-block:: c 70*61c4878aSAndroid Build Coastguard Worker 71*61c4878aSAndroid Build Coastguard Worker /* //src/pw_log_string_backend.c */ 72*61c4878aSAndroid Build Coastguard Worker 73*61c4878aSAndroid Build Coastguard Worker #include <stdio.h> 74*61c4878aSAndroid Build Coastguard Worker #include <stdarg.h> 75*61c4878aSAndroid Build Coastguard Worker 76*61c4878aSAndroid Build Coastguard Worker void pw_log_string_HandleMessageVaList(int level, 77*61c4878aSAndroid Build Coastguard Worker unsigned int flags, 78*61c4878aSAndroid Build Coastguard Worker const char* module_name, 79*61c4878aSAndroid Build Coastguard Worker const char* file_name, 80*61c4878aSAndroid Build Coastguard Worker int line_number, 81*61c4878aSAndroid Build Coastguard Worker const char* message, 82*61c4878aSAndroid Build Coastguard Worker va_list args) { 83*61c4878aSAndroid Build Coastguard Worker printf("Entering custom pw_log_string backend...\n"); 84*61c4878aSAndroid Build Coastguard Worker printf("%d\n", level); 85*61c4878aSAndroid Build Coastguard Worker printf("%u\n", flags); 86*61c4878aSAndroid Build Coastguard Worker printf("%s\n", module_name); 87*61c4878aSAndroid Build Coastguard Worker printf("%s\n", file_name); 88*61c4878aSAndroid Build Coastguard Worker printf("%d\n", line_number); 89*61c4878aSAndroid Build Coastguard Worker printf("%s\n", message); 90*61c4878aSAndroid Build Coastguard Worker if (args) { /* Do something with your args here... */ } 91*61c4878aSAndroid Build Coastguard Worker printf("Exiting custom pw_log_string backend...\n\n"); 92*61c4878aSAndroid Build Coastguard Worker } 93*61c4878aSAndroid Build Coastguard Worker 94*61c4878aSAndroid Build Coastguard WorkerWhat exactly ``pw_log_string_HandleMessageVaList()`` should do is entirely up to 95*61c4878aSAndroid Build Coastguard Workerthe implementation. The log handler in ``pw_log_basic`` is one example, but it's 96*61c4878aSAndroid Build Coastguard Workeralso possible to encode as protobuf and send over a TCP port, write to a file, 97*61c4878aSAndroid Build Coastguard Workeror even blink an LED to log as morse code. 98*61c4878aSAndroid Build Coastguard Worker 99*61c4878aSAndroid Build Coastguard WorkerCreate source sets 100*61c4878aSAndroid Build Coastguard Worker================== 101*61c4878aSAndroid Build Coastguard Worker.. _source set: https://gn.googlesource.com/gn/+/main/docs/reference.md#c_language-source_sets 102*61c4878aSAndroid Build Coastguard Worker 103*61c4878aSAndroid Build Coastguard WorkerUse ``pw_source_set`` to create a `source set`_ for your logging 104*61c4878aSAndroid Build Coastguard Workerimplementation. Do not use GN's built-in ``source_set`` feature. 105*61c4878aSAndroid Build Coastguard Worker 106*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 107*61c4878aSAndroid Build Coastguard Worker 108*61c4878aSAndroid Build Coastguard Worker # //src/BUILD.gn 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker ... 111*61c4878aSAndroid Build Coastguard Worker 112*61c4878aSAndroid Build Coastguard Worker pw_source_set("pw_log_string_backend") { 113*61c4878aSAndroid Build Coastguard Worker sources = [ "pw_log_string_backend.c" ] 114*61c4878aSAndroid Build Coastguard Worker } 115*61c4878aSAndroid Build Coastguard Worker 116*61c4878aSAndroid Build Coastguard Worker pw_source_set("pw_log_string_backend.impl") { 117*61c4878aSAndroid Build Coastguard Worker sources = [] 118*61c4878aSAndroid Build Coastguard Worker } 119*61c4878aSAndroid Build Coastguard Worker 120*61c4878aSAndroid Build Coastguard Worker ... 121*61c4878aSAndroid Build Coastguard Worker 122*61c4878aSAndroid Build Coastguard Worker.. _//pw_log/BUILD.gn: https://cs.opensource.google/pigweed/pigweed/+/main:pw_log/BUILD.gn 123*61c4878aSAndroid Build Coastguard Worker 124*61c4878aSAndroid Build Coastguard WorkerThe empty ``pw_log_string_backend.impl`` source set prevents circular 125*61c4878aSAndroid Build Coastguard Workerdependencies. See the comment for ``group("impl")`` in `//pw_log/BUILD.gn`_ 126*61c4878aSAndroid Build Coastguard Workerfor more context. 127*61c4878aSAndroid Build Coastguard Worker 128*61c4878aSAndroid Build Coastguard WorkerConfigure backends 129*61c4878aSAndroid Build Coastguard Worker================== 130*61c4878aSAndroid Build Coastguard WorkerUpdate your target toolchain configuration file: 131*61c4878aSAndroid Build Coastguard Worker 132*61c4878aSAndroid Build Coastguard Worker* Set ``pw_log_BACKEND`` to ``dir_pw_log_string`` 133*61c4878aSAndroid Build Coastguard Worker* Point ``pw_log_string_HANDLER_BACKEND`` to your source set that implements 134*61c4878aSAndroid Build Coastguard Worker :cpp:func:`pw_log_string_HandleMessageVaList()` 135*61c4878aSAndroid Build Coastguard Worker* Update :ref:`pw_build_LINK_DEPS <module-pw_build-link-deps>` to include 136*61c4878aSAndroid Build Coastguard Worker ``"$dir_pw_log:impl"`` and ``"$dir_pw_log_string:handler:impl"`` 137*61c4878aSAndroid Build Coastguard Worker 138*61c4878aSAndroid Build Coastguard Worker.. code-block:: python 139*61c4878aSAndroid Build Coastguard Worker :emphasize-lines: 11,12,14,15 140*61c4878aSAndroid Build Coastguard Worker 141*61c4878aSAndroid Build Coastguard Worker # //targets/my_target/target_toolchains.gni 142*61c4878aSAndroid Build Coastguard Worker 143*61c4878aSAndroid Build Coastguard Worker ... 144*61c4878aSAndroid Build Coastguard Worker 145*61c4878aSAndroid Build Coastguard Worker my_target = { 146*61c4878aSAndroid Build Coastguard Worker ... 147*61c4878aSAndroid Build Coastguard Worker my_toolchain = { 148*61c4878aSAndroid Build Coastguard Worker name = "my_toolchain" 149*61c4878aSAndroid Build Coastguard Worker defaults = { 150*61c4878aSAndroid Build Coastguard Worker ... 151*61c4878aSAndroid Build Coastguard Worker pw_log_BACKEND = dir_pw_log_string 152*61c4878aSAndroid Build Coastguard Worker pw_log_string_HANDLER_BACKEND = "//src:pw_log_string_backend" 153*61c4878aSAndroid Build Coastguard Worker pw_build_LINK_DEPS = [ 154*61c4878aSAndroid Build Coastguard Worker "$dir_pw_log:impl", 155*61c4878aSAndroid Build Coastguard Worker "$dir_pw_log_string:handler.impl", 156*61c4878aSAndroid Build Coastguard Worker ... 157*61c4878aSAndroid Build Coastguard Worker ] 158*61c4878aSAndroid Build Coastguard Worker ... 159*61c4878aSAndroid Build Coastguard Worker } 160*61c4878aSAndroid Build Coastguard Worker } 161*61c4878aSAndroid Build Coastguard Worker } 162*61c4878aSAndroid Build Coastguard Worker 163*61c4878aSAndroid Build Coastguard Worker ... 164*61c4878aSAndroid Build Coastguard Worker 165*61c4878aSAndroid Build Coastguard Worker 166*61c4878aSAndroid Build Coastguard Worker(Optional) Implement message handler 167*61c4878aSAndroid Build Coastguard Worker==================================== 168*61c4878aSAndroid Build Coastguard WorkerOptionally provide your own implementation of ``PW_LOG_STRING_HANDLE_MESSAGE`` 169*61c4878aSAndroid Build Coastguard Workerwhich invokes ``pw_log_string_HANDLER_BACKEND`` with your selected arguments. 170*61c4878aSAndroid Build Coastguard Worker 171*61c4878aSAndroid Build Coastguard Worker``assert`` wrapper 172*61c4878aSAndroid Build Coastguard Worker================== 173*61c4878aSAndroid Build Coastguard WorkerA wrapper for ``assert`` is provided that redirects calls to the ``pw_log_string`` 174*61c4878aSAndroid Build Coastguard Workerhandler. This can be used to replace all usage of ``assert`` in a Newlib binary 175*61c4878aSAndroid Build Coastguard Workerat link time. 176*61c4878aSAndroid Build Coastguard Worker 177*61c4878aSAndroid Build Coastguard Worker------------- 178*61c4878aSAndroid Build Coastguard WorkerAPI reference 179*61c4878aSAndroid Build Coastguard Worker------------- 180*61c4878aSAndroid Build Coastguard Worker.. doxygenfunction:: 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) 181