Skip to content

RFC: Logging subsystem overhaul #30353

@nordic-krch

Description

@nordic-krch

Introduction

Logging subsystem has been in zephyr for more than 2 years. During that time there were feature requests which could not be fulfilled with current design. As number of those requests has grown I've started to look into overhaul of logger internals. Overhaul does not plan to change logger application API but it will change backend API. Currently logger has following limitations:

Further weaknesses:

  • processing log message takes a lot of stack and flash as log message arguments need to be resolved to vla function:
    static void std_print(struct log_msg *msg,
  • internal handling of log messages is troublesome because of fragmented nature.

There were suggestions (@andyross) to switch to use ring buffer instead of current fragmented messages.

Proposed change

Plan is to rework internals of the logger to store log message in a ring buffer. This will require that backends handle message synchronously (make a copy if needed).

There will be only one type of a log message (instead of current distinction between standard and hexdump). Message will consist of header, arguments, data (optional), transient strings (optional). Logger will attempt to store arguments in a way that it can be directly casted to va_list (validated on majority of platforms). String arguments will point to space within the message.

_Generic keyword (https://en.cppreference.com/w/c/language/generic) will be used to detect types of logger message arguments at compile time. Any float arguments will be promoted to double, any char * arguments will trigger further processing which will involve detecting %s arguments, calculating length needed to store strings, copying strings to the message body. log_strdup will be deprecated.

This approach shall solve all weaknesses and limitations mentioned above.

As already mentioned, internal architecture change will impact backend interface. Currently, log_message handling is asynchronous, message is alive until last backend indicates that message is not used. This approach may give better memory utilization in certain scenarios because backend does not need to copy the message but, in general, new approach will more memory efficient due to ring buffer. Current approach comes from nrf5 sdk where it was used in a bare metal applications where asynchronous handling is more welcomed. In RTOS environment value of this approach diminishes.

Ring buffer needed for the logger may be generic since it is a variable length messages buffer with following arguments:

  • multiple producers
  • 3 modes: saturate, overwrite the oldest, block thread context until available
  • two consumers: standard and panic which may interrupt standard

There are further requests which does not imply architecture change and they will be gradually fixed:

@andyross please let me know if you have any comments.

Dependencies

Logger backends interface will change. It will be simplified as there will be only single message type, message will not be fragmented and arguments will form va_list which can be directly passed to the formatter.

Concerns and Unresolved Questions

_Generic keyword is C11 (#30105) and it is unclear which C standard is currently used by Zephyr. However, it currently compiles without enforcing C11. I didn't who enables C11.

Metadata

Metadata

Assignees

Labels

LTSLong term release branch relatedRFCRequest For Comments: want input from the communityarea: Logging

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions