Linux Kernel Logging Concepts
Introduction
The Linux kernel log is one of the most important diagnostic tools in Linux development and system troubleshooting. Understanding the kernel log is therefore essential. Before exploring how the kernel logging mechanism works, it is important to understand its core component, which is the printk() function.
PrintK()
printk() is the Linux kernel’s printing function, it is similar to the user-space printf() function, but not fully compatible with it. For example, The printk() doesn't support floating-point formats such as (%f,%e,%g) because floating-point operations are generally avoided in kernel code. At the same time, printk() provides several kernel-specific format specifiers, like extended %p forms to %pS and %pe, for printing information such as symbol names and error-pointer values. For more information about the format specifiers supported by printk(), see the Linux kernel documentation.
Messages produced by printk() are written to the kernel ring buffer, commonly referred to as the kernel log. This kernel log can be viewed and managed using the dmesg command.
Examples:
$ dmesg # Display all messages from the kernel ring buffer
$ dmesg | tail -1 # Display the most recent kernel log message
$ dmesg | head -2 # Display the first two kernel log messages
$ dmesg | grep 'xyz' # Display kernel log messages containing "xyz"
Priority of kernel log messages
The Linux kernel provides a useful logging priority mechanism based on levels.
These log levels allow us to control the priority of messages produced by printk().
There are eight kernel log levels (0 to 7), where a lower number indicates a higher priority. These log levels are defined as C macros in the kern_levels.h
In most cases, the default printk() log level is set to 4, corresponding to the warning level. Please note that if no log level is specified in printk(), the message is automatically assigned the default log level.
Example of assigning a log level (INFO) to a message. Note that there is no comma between the log level and the log message.
printk(KERN_INFO"Info Message...\n");
Kernel Log Levels and Console Output
Every kernel message is stored in the kernel ring buffer. To determine whether a message should also appear on the console, its log level is compared with the current console log level. The message is printed to the console only when its log-level value is lower than the console log level.
printk() message
|
v
Stored in the kernel ring buffer
|
v
Is message log level < console log level?
/ \
Yes No
| |
v v
Printed to the Not printed to the
console console, but still
available through dmesg
For example, when the console log level is set to 7:
Message levels 0-6 -> Printed to the console
Message level 7 -> Kept in the kernel ring buffer only
The initial console log level is configured through the CONFIG_CONSOLE_LOGLEVEL_DEFAULT kernel configuration
option and is commonly set to 7. It can be modified through the kernel menuconfig interface or changed at runtime through /proc/sys/kernel/printk.
$ cat /proc/sys/kernel/printk # Display the printk log-level settings
$ echo 4 > /proc/sys/kernel/printk # Set the console log level to 4
The output of cat normally contains four values:
console_loglevel | default_message_loglevel | minimum_console_loglevel | default_console_loglevel
The pr_*() Logging Macros
Instead of calling printk() with an explicit log-level macro, the kernel provides pr_*() for the different log levels. For example, pr_info("xyz") is equivalent to printk(KERN_INFO"xyz"). These wrappers make logging statements shorter and easier to read.
| Level | Log-level macro | Logging macro |
|---|---|---|
| 0 | KERN_EMERG |
pr_emerg() |
| 1 | KERN_ALERT |
pr_alert() |
| 2 | KERN_CRIT |
pr_crit() |
| 3 | KERN_ERR |
pr_err() |
| 4 | KERN_WARNING |
pr_warn() |
| 5 | KERN_NOTICE |
pr_notice() |
| 6 | KERN_INFO |
pr_info() |
| 7 | KERN_DEBUG |
pr_debug() |
For example:
pr_info("Module loaded successfully\n");
pr_warn("A warning occurred\n");
pr_err("An error occurred\n");
Conclusion
Every log message is stored in the kernel ring buffer. Its log level determines whether the message is printed immediately to the console or kept in the kernel log for later inspection using the dmesg command. As discussed earlier, the Linux kernel also provides ready-to-use macros for the different log levels, So, there is no need to manually specify the log level each time we need to print a log message.
Understanding this logging mechanism also makes it easier to understand the Zephyr RTOS logging system, since both use similar concepts such as log levels, priorities, and predefined logging macros.
Commentaires (0)
Signaler ou Supprimer le Commentaire
Sélectionnez une action et entrez votre email. L'admin examinera votre demande.
Laisser un Commentaire
Envoyer une Question Privée
Votre message me sera envoyé directement par e-mail — non visible par les autres lecteurs.