doc: move README.log to HTML documentation
Convert README.log to reStructuredText and add it to the generated HTML documentation. Assign doc/develop/logging.rst to the maintainer of LOGGING. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
b44c751efe
commit
a7813918fe
@ -698,6 +698,7 @@ S: Maintained
|
|||||||
T: git https://gitlab.denx.de/u-boot/u-boot.git
|
T: git https://gitlab.denx.de/u-boot/u-boot.git
|
||||||
F: common/log*
|
F: common/log*
|
||||||
F: cmd/log.c
|
F: cmd/log.c
|
||||||
|
F: doc/develop/logging.rst
|
||||||
F: test/log/
|
F: test/log/
|
||||||
F: test/py/tests/test_log.py
|
F: test/py/tests/test_log.py
|
||||||
|
|
||||||
|
@ -8,3 +8,4 @@ Develop U-Boot
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
crash_dumps
|
crash_dumps
|
||||||
|
logging
|
||||||
|
290
doc/develop/logging.rst
Normal file
290
doc/develop/logging.rst
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. Copyright (c) 2017 Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
Logging in U-Boot
|
||||||
|
=================
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
U-Boot's internal operation involves many different steps and actions. From
|
||||||
|
setting up the board to displaying a start-up screen to loading an Operating
|
||||||
|
System, there are many component parts each with many actions.
|
||||||
|
|
||||||
|
Most of the time this internal detail is not useful. Displaying it on the
|
||||||
|
console would delay booting (U-Boot's primary purpose) and confuse users.
|
||||||
|
|
||||||
|
But for digging into what is happening in a particular area, or for debugging
|
||||||
|
a problem it is often useful to see what U-Boot is doing in more detail than
|
||||||
|
is visible from the basic console output.
|
||||||
|
|
||||||
|
U-Boot's logging feature aims to satisfy this goal for both users and
|
||||||
|
developers.
|
||||||
|
|
||||||
|
|
||||||
|
Logging levels
|
||||||
|
--------------
|
||||||
|
|
||||||
|
There are a number logging levels available, in increasing order of verbosity:
|
||||||
|
|
||||||
|
* LOGL_EMERG - Printed before U-Boot halts
|
||||||
|
* LOGL_ALERT - Indicates action must be taken immediate or U-Boot will crash
|
||||||
|
* LOGL_CRIT - Indicates a critical error that will cause boot failure
|
||||||
|
* LOGL_ERR - Indicates an error that may cause boot failure
|
||||||
|
* LOGL_WARNING - Warning about an unexpected condition
|
||||||
|
* LOGL_NOTE - Important information about progress
|
||||||
|
* LOGL_INFO - Information about normal boot progress
|
||||||
|
* LOGL_DEBUG - Debug information (useful for debugging a driver or subsystem)
|
||||||
|
* LOGL_DEBUG_CONTENT - Debug message showing full message content
|
||||||
|
* LOGL_DEBUG_IO - Debug message showing hardware I/O access
|
||||||
|
|
||||||
|
|
||||||
|
Logging category
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Logging can come from a wide variety of places within U-Boot. Each log message
|
||||||
|
has a category which is intended to allow messages to be filtered according to
|
||||||
|
their source.
|
||||||
|
|
||||||
|
The following main categories are defined:
|
||||||
|
|
||||||
|
* LOGC_NONE - Unknown category (e.g. a debug() statement)
|
||||||
|
* UCLASS\_... - Related to a particular uclass (e.g. UCLASS_USB)
|
||||||
|
* LOGC_ARCH - Related to architecture-specific code
|
||||||
|
* LOGC_BOARD - Related to board-specific code
|
||||||
|
* LOGC_CORE - Related to core driver-model support
|
||||||
|
* LOGC_DT - Related to device tree control
|
||||||
|
* LOGC_EFI - Related to EFI implementation
|
||||||
|
|
||||||
|
|
||||||
|
Enabling logging
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The following options are used to enable logging at compile time:
|
||||||
|
|
||||||
|
* CONFIG_LOG - Enables the logging system
|
||||||
|
* CONFIG_LOG_MAX_LEVEL - Max log level to build (anything higher is compiled
|
||||||
|
out)
|
||||||
|
* CONFIG_LOG_CONSOLE - Enable writing log records to the console
|
||||||
|
|
||||||
|
If CONFIG_LOG is not set, then no logging will be available.
|
||||||
|
|
||||||
|
The above have SPL and TPL versions also, e.g. CONFIG_SPL_LOG_MAX_LEVEL and
|
||||||
|
CONFIG_TPL_LOG_MAX_LEVEL.
|
||||||
|
|
||||||
|
|
||||||
|
Temporary logging within a single file
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Sometimes it is useful to turn on logging just in one file. You can use this
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#define LOG_DEBUG
|
||||||
|
|
||||||
|
to enable building in of all logging statements in a single file. Put it at
|
||||||
|
the top of the file, before any #includes.
|
||||||
|
|
||||||
|
To actually get U-Boot to output this you need to also set the default logging
|
||||||
|
level - e.g. set CONFIG_LOG_DEFAULT_LEVEL to 7 (LOGL_DEBUG) or more. Otherwise
|
||||||
|
debug output is suppressed and will not be generated.
|
||||||
|
|
||||||
|
|
||||||
|
Convenience functions
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
A number of convenience functions are available to shorten the code needed
|
||||||
|
for logging:
|
||||||
|
|
||||||
|
* log_err(_fmt...)
|
||||||
|
* log_warning(_fmt...)
|
||||||
|
* log_notice(_fmt...)
|
||||||
|
* log_info(_fmt...)
|
||||||
|
* log_debug(_fmt...)
|
||||||
|
* log_content(_fmt...)
|
||||||
|
* log_io(_fmt...)
|
||||||
|
|
||||||
|
With these the log level is implicit in the name. The category is set by
|
||||||
|
LOG_CATEGORY, which you can only define once per file, above all #includes, e.g.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#define LOG_CATEGORY LOGC_ALLOC
|
||||||
|
|
||||||
|
Remember that all uclasses IDs are log categories too.
|
||||||
|
|
||||||
|
|
||||||
|
Log command
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The 'log' command provides access to several features:
|
||||||
|
|
||||||
|
* level - access the default log level
|
||||||
|
* format - access the console log format
|
||||||
|
* rec - output a log record
|
||||||
|
* test - run tests
|
||||||
|
|
||||||
|
Type 'help log' for details.
|
||||||
|
|
||||||
|
|
||||||
|
Using DEBUG
|
||||||
|
-----------
|
||||||
|
|
||||||
|
U-Boot has traditionally used a #define called DEBUG to enable debugging on a
|
||||||
|
file-by-file basis. The debug() macro compiles to a printf() statement if
|
||||||
|
DEBUG is enabled, and an empty statement if not.
|
||||||
|
|
||||||
|
With logging enabled, debug() statements are interpreted as logging output
|
||||||
|
with a level of LOGL_DEBUG and a category of LOGC_NONE.
|
||||||
|
|
||||||
|
The logging facilities are intended to replace DEBUG, but if DEBUG is defined
|
||||||
|
at the top of a file, then it takes precedence. This means that debug()
|
||||||
|
statements will result in output to the console and this output will not be
|
||||||
|
logged.
|
||||||
|
|
||||||
|
|
||||||
|
Logging destinations
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
If logging information goes nowhere then it serves no purpose. U-Boot provides
|
||||||
|
several possible determinations for logging information, all of which can be
|
||||||
|
enabled or disabled independently:
|
||||||
|
|
||||||
|
* console - goes to stdout
|
||||||
|
* syslog - broadcast RFC 3164 messages to syslog servers on UDP port 514
|
||||||
|
|
||||||
|
The syslog driver sends the value of environmental variable 'log_hostname' as
|
||||||
|
HOSTNAME if available.
|
||||||
|
|
||||||
|
|
||||||
|
Log format
|
||||||
|
----------
|
||||||
|
|
||||||
|
You can control the log format using the 'log format' command. The basic
|
||||||
|
format is::
|
||||||
|
|
||||||
|
LEVEL.category,file.c:123-func() message
|
||||||
|
|
||||||
|
In the above, file.c:123 is the filename where the log record was generated and
|
||||||
|
func() is the function name. By default ('log format default') only the
|
||||||
|
function name and message are displayed on the console. You can control which
|
||||||
|
fields are present, but not the field order.
|
||||||
|
|
||||||
|
|
||||||
|
Filters
|
||||||
|
-------
|
||||||
|
|
||||||
|
Filters are attached to log drivers to control what those drivers emit. Only
|
||||||
|
records that pass through the filter make it to the driver.
|
||||||
|
|
||||||
|
Filters can be based on several criteria:
|
||||||
|
|
||||||
|
* maximum log level
|
||||||
|
* in a set of categories
|
||||||
|
* in a set of files
|
||||||
|
|
||||||
|
If no filters are attached to a driver then a default filter is used, which
|
||||||
|
limits output to records with a level less than CONFIG_MAX_LOG_LEVEL.
|
||||||
|
|
||||||
|
|
||||||
|
Logging statements
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The main logging function is:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
log(category, level, format_string, ...)
|
||||||
|
|
||||||
|
Also debug() and error() will generate log records - these use LOG_CATEGORY
|
||||||
|
as the category, so you should #define this right at the top of the source
|
||||||
|
file to ensure the category is correct.
|
||||||
|
|
||||||
|
You can also define CONFIG_LOG_ERROR_RETURN to enable the log_ret() macro. This
|
||||||
|
can be used whenever your function returns an error value:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
return log_ret(uclass_first_device(UCLASS_MMC, &dev));
|
||||||
|
|
||||||
|
This will write a log record when an error code is detected (a value < 0). This
|
||||||
|
can make it easier to trace errors that are generated deep in the call stack.
|
||||||
|
|
||||||
|
|
||||||
|
Code size
|
||||||
|
---------
|
||||||
|
|
||||||
|
Code size impact depends largely on what is enabled. The following numbers are
|
||||||
|
generated by 'buildman -S' for snow, which is a Thumb-2 board (all units in
|
||||||
|
bytes)::
|
||||||
|
|
||||||
|
This series: adds bss +20.0 data +4.0 rodata +4.0 text +44.0
|
||||||
|
CONFIG_LOG: bss -52.0 data +92.0 rodata -635.0 text +1048.0
|
||||||
|
CONFIG_LOG_MAX_LEVEL=7: bss +188.0 data +4.0 rodata +49183.0 text +98124.0
|
||||||
|
|
||||||
|
The last option turns every debug() statement into a logging call, which
|
||||||
|
bloats the code hugely. The advantage is that it is then possible to enable
|
||||||
|
all logging within U-Boot.
|
||||||
|
|
||||||
|
|
||||||
|
To Do
|
||||||
|
-----
|
||||||
|
|
||||||
|
There are lots of useful additions that could be made. None of the below is
|
||||||
|
implemented! If you do one, please add a test in test/py/tests/test_log.py
|
||||||
|
|
||||||
|
Convenience functions to support setting the category:
|
||||||
|
|
||||||
|
* log_arch(level, format_string, ...) - category LOGC_ARCH
|
||||||
|
* log_board(level, format_string, ...) - category LOGC_BOARD
|
||||||
|
* log_core(level, format_string, ...) - category LOGC_CORE
|
||||||
|
* log_dt(level, format_string, ...) - category LOGC_DT
|
||||||
|
|
||||||
|
More logging destinations:
|
||||||
|
|
||||||
|
* device - goes to a device (e.g. serial)
|
||||||
|
* buffer - recorded in a memory buffer
|
||||||
|
|
||||||
|
Convert debug() statements in the code to log() statements
|
||||||
|
|
||||||
|
Support making printf() emit log statements at L_INFO level
|
||||||
|
|
||||||
|
Convert error() statements in the code to log() statements
|
||||||
|
|
||||||
|
Figure out what to do with BUG(), BUG_ON() and warn_non_spl()
|
||||||
|
|
||||||
|
Figure out what to do with assert()
|
||||||
|
|
||||||
|
Add a way to browse log records
|
||||||
|
|
||||||
|
Add a way to record log records for browsing using an external tool
|
||||||
|
|
||||||
|
Add commands to add and remove filters
|
||||||
|
|
||||||
|
Add commands to add and remove log devices
|
||||||
|
|
||||||
|
Allow sharing of printf format strings in log records to reduce storage size
|
||||||
|
for large numbers of log records
|
||||||
|
|
||||||
|
Add a command-line option to sandbox to set the default logging level
|
||||||
|
|
||||||
|
Convert core driver model code to use logging
|
||||||
|
|
||||||
|
Convert uclasses to use logging with the correct category
|
||||||
|
|
||||||
|
Consider making log() calls emit an automatic newline, perhaps with a logn()
|
||||||
|
function to avoid that
|
||||||
|
|
||||||
|
Passing log records through to linux (e.g. via device tree /chosen)
|
||||||
|
|
||||||
|
Provide a command to access the number of log records generated, and the
|
||||||
|
number dropped due to them being generated before the log system was ready.
|
||||||
|
|
||||||
|
Add a printf() format string pragma so that log statements are checked properly
|
||||||
|
|
||||||
|
Enhance the log console driver to show level / category / file / line
|
||||||
|
information
|
||||||
|
|
||||||
|
Add a command to add new log records and delete existing records.
|
||||||
|
|
||||||
|
Provide additional log() functions - e.g. logc() to specify the category
|
Loading…
Reference in New Issue
Block a user