1.. SPDX-License-Identifier: GPL-2.0+ 2.. Copyright (c) 2017 Simon Glass <sjg@chromium.org> 3 4Logging in U-Boot 5================= 6 7Introduction 8------------ 9 10U-Boot's internal operation involves many different steps and actions. From 11setting up the board to displaying a start-up screen to loading an Operating 12System, there are many component parts each with many actions. 13 14Most of the time this internal detail is not useful. Displaying it on the 15console would delay booting (U-Boot's primary purpose) and confuse users. 16 17But for digging into what is happening in a particular area, or for debugging 18a problem it is often useful to see what U-Boot is doing in more detail than 19is visible from the basic console output. 20 21U-Boot's logging feature aims to satisfy this goal for both users and 22developers. 23 24Logging levels 25-------------- 26 27There are a number logging levels available. 28 29See enum :c:type:`log_level_t` 30 31Logging category 32---------------- 33 34Logging can come from a wide variety of places within U-Boot. Each log message 35has a category which is intended to allow messages to be filtered according to 36their source. 37 38See enum :c:type:`log_category_t` 39 40Enabling logging 41---------------- 42 43The following options are used to enable logging at compile time: 44 45* CONFIG_LOG - Enables the logging system 46* CONFIG_LOG_MAX_LEVEL - Max log level to build (anything higher is compiled 47 out) 48* CONFIG_LOG_CONSOLE - Enable writing log records to the console 49 50If CONFIG_LOG is not set, then no logging will be available. 51 52The above have SPL and TPL versions also, e.g. CONFIG_SPL_LOG_MAX_LEVEL and 53CONFIG_TPL_LOG_MAX_LEVEL. 54 55If logging is disabled, the default behaviour is to output any message at 56level LOGL_INFO and below. If logging is disabled and DEBUG is defined (at 57the very top of a C file) then any message at LOGL_DEBUG will be written. 58 59Temporary logging within a single file 60-------------------------------------- 61 62Sometimes it is useful to turn on logging just in one file. You can use this 63 64.. code-block:: c 65 66 #define LOG_DEBUG 67 68to enable building in of all logging statements in a single file. Put it at 69the top of the file, before any #includes. 70 71To actually get U-Boot to output this you need to also set the default logging 72level - e.g. set CONFIG_LOG_DEFAULT_LEVEL to 7 (:c:data:`LOGL_DEBUG`) or more. 73Otherwise debug output is suppressed and will not be generated. 74 75Using DEBUG 76----------- 77 78U-Boot has traditionally used a #define called DEBUG to enable debugging on a 79file-by-file basis. The debug() macro compiles to a printf() statement if 80DEBUG is enabled, and an empty statement if not. 81 82With logging enabled, debug() statements are interpreted as logging output 83with a level of LOGL_DEBUG and a category of LOGC_NONE. 84 85The logging facilities are intended to replace DEBUG, but if DEBUG is defined 86at the top of a file, then it takes precedence. This means that debug() 87statements will result in output to the console and this output will not be 88logged. 89 90Logging statements 91------------------ 92 93The main logging function is: 94 95.. code-block:: c 96 97 log(category, level, format_string, ...) 98 99Also debug() and error() will generate log records - these use LOG_CATEGORY 100as the category, so you should #define this right at the top of the source 101file to ensure the category is correct. 102 103Generally each log format_string ends with a newline. If it does not, then the 104next log statement will have the LOGRECF_CONT flag set. This can be used to 105continue the statement on the same line as the previous one without emitting 106new header information (such as category/level). This behaviour is implemented 107with log_console. Here is an example that prints a list all on one line with 108the tags at the start: 109 110.. code-block:: c 111 112 log_debug("Here is a list:"); 113 for (i = 0; i < count; i++) 114 log_debug(" item %d", i); 115 log_debug("\n"); 116 117Also see the special category LOGL_CONT and level LOGC_CONT. 118 119You can also define CONFIG_LOG_ERROR_RETURN to enable the log_ret() macro. This 120can be used whenever your function returns an error value: 121 122.. code-block:: c 123 124 return log_ret(uclass_first_device_err(UCLASS_MMC, &dev)); 125 126This will write a log record when an error code is detected (a value < 0). This 127can make it easier to trace errors that are generated deep in the call stack. 128 129The log_msg_ret() variant will print a short string if CONFIG_LOG_ERROR_RETURN 130is enabled. So long as the string is unique within the function you can normally 131determine exactly which call failed: 132 133.. code-block:: c 134 135 ret = gpio_request_by_name(dev, "cd-gpios", 0, &desc, GPIOD_IS_IN); 136 if (ret) 137 return log_msg_ret("gpio", ret); 138 139Some functions return 0 for success and any other value is an error. For these, 140log_retz() and log_msg_retz() are available. 141 142Convenience functions 143~~~~~~~~~~~~~~~~~~~~~ 144 145A number of convenience functions are available to shorten the code needed 146for logging: 147 148* log_err(_fmt...) 149* log_warning(_fmt...) 150* log_notice(_fmt...) 151* log_info(_fmt...) 152* log_debug(_fmt...) 153* log_content(_fmt...) 154* log_io(_fmt...) 155 156With these the log level is implicit in the name. The category is set by 157LOG_CATEGORY, which you can only define once per file, above all #includes, e.g. 158 159.. code-block:: c 160 161 #define LOG_CATEGORY LOGC_ALLOC 162 163or 164 165.. code-block:: c 166 167 #define LOG_CATEGORY UCLASS_SPI 168 169Remember that all uclasses IDs are log categories too. 170 171Logging destinations 172-------------------- 173 174If logging information goes nowhere then it serves no purpose. U-Boot provides 175several possible determinations for logging information, all of which can be 176enabled or disabled independently: 177 178* console - goes to stdout 179* syslog - broadcast RFC 3164 messages to syslog servers on UDP port 514 180 181The syslog driver sends the value of environmental variable 'log_hostname' as 182HOSTNAME if available. 183 184Filters 185------- 186 187Filters are attached to log drivers to control what those drivers emit. FIlters 188can either allow or deny a log message when they match it. Only records which 189are allowed by a filter make it to the driver. 190 191Filters can be based on several criteria: 192 193* minimum or maximum log level 194* in a set of categories 195* in a set of files 196 197If no filters are attached to a driver then a default filter is used, which 198limits output to records with a level less than CONFIG_MAX_LOG_LEVEL. 199 200Log command 201----------- 202 203The 'log' command provides access to several features: 204 205* level - list log levels or set the default log level 206* categories - list log categories 207* drivers - list log drivers 208* filter-list - list filters 209* filter-add - add a new filter 210* filter-remove - remove filters 211* format - access the console log format 212* rec - output a log record 213 214Type 'help log' for details. 215 216Log format 217~~~~~~~~~~ 218 219You can control the log format using the 'log format' command. The basic 220format is:: 221 222 LEVEL.category,file.c:123-func() message 223 224In the above, file.c:123 is the filename where the log record was generated and 225func() is the function name. By default ('log format default') only the message 226is displayed on the console. You can control which fields are present, but not 227the field order. 228 229Adding Filters 230~~~~~~~~~~~~~~ 231 232To add new filters at runtime, use the 'log filter-add' command. For example, to 233suppress messages from the SPI and MMC subsystems, run:: 234 235 log filter-add -D -c spi -c mmc 236 237You will also need to add another filter to allow other messages (because the 238default filter no longer applies):: 239 240 log filter-add -A -l info 241 242Log levels may be either symbolic names (like above) or numbers. For example, to 243disable all debug and above (log level 7) messages from ``drivers/core/lists.c`` 244and ``drivers/core/ofnode.c``, run:: 245 246 log filter-add -D -f drivers/core/lists.c,drivers/core/ofnode.c -L 7 247 248To view active filters, use the 'log filter-list' command. Some example output 249is:: 250 251 => log filter-list 252 num policy level categories files 253 2 deny >= DEBUG drivers/core/lists.c,drivers/core/ofnode.c 254 0 deny <= IO spi 255 mmc 256 1 allow <= INFO 257 258Note that filters are processed in-order from top to bottom, not in the order of 259their filter number. Filters are added to the top of the list if they deny when 260they match, and to the bottom if they allow when they match. For more 261information, consult the usage of the 'log' command, by running 'help log'. 262 263Code size 264--------- 265 266Code size impact depends largely on what is enabled. The following numbers are 267generated by 'buildman -S' for snow, which is a Thumb-2 board (all units in 268bytes):: 269 270 This series: adds bss +20.0 data +4.0 rodata +4.0 text +44.0 271 CONFIG_LOG: bss -52.0 data +92.0 rodata -635.0 text +1048.0 272 CONFIG_LOG_MAX_LEVEL=7: bss +188.0 data +4.0 rodata +49183.0 text +98124.0 273 274The last option turns every debug() statement into a logging call, which 275bloats the code hugely. The advantage is that it is then possible to enable 276all logging within U-Boot. 277 278To Do 279----- 280 281There are lots of useful additions that could be made. None of the below is 282implemented! If you do one, please add a test in test/log/log_test.c 283log filter-add -D -f drivers/core/lists.c,drivers/core/ofnode.c -l 6 284Convenience functions to support setting the category: 285 286* log_arch(level, format_string, ...) - category LOGC_ARCH 287* log_board(level, format_string, ...) - category LOGC_BOARD 288* log_core(level, format_string, ...) - category LOGC_CORE 289* log_dt(level, format_string, ...) - category LOGC_DT 290 291More logging destinations: 292 293* device - goes to a device (e.g. serial) 294* buffer - recorded in a memory buffer 295 296Convert debug() statements in the code to log() statements 297 298Convert error() statements in the code to log() statements 299 300Figure out what to do with BUG(), BUG_ON() and warn_non_spl() 301 302Add a way to browse log records 303 304Add a way to record log records for browsing using an external tool 305 306Add commands to add and remove log devices 307 308Allow sharing of printf format strings in log records to reduce storage size 309for large numbers of log records 310 311Consider making log() calls emit an automatic newline, perhaps with a logn() 312function to avoid that 313 314Passing log records through to linux (e.g. via device tree /chosen) 315 316Provide a command to access the number of log records generated, and the 317number dropped due to them being generated before the log system was ready. 318 319Add a printf() format string pragma so that log statements are checked properly 320 321Add a command to delete existing log records. 322