xref: /aosp_15_r20/external/pigweed/pw_log_string/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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