-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Logging subsystem overhaul #30353
Comments
Great! In relation to this work, I would like to highlight #23021 as well |
I want to point out again that float arguments are already promoted to double when passed to a function that lacks a prototype (or in a varargs position), so there is nothing to do for "Any float arguments will be promoted to double". What has to be done is detecting that the value to be formatted takes more than one word on the stack. I added cbprintf_arglen() to help with that issue, but that doesn't help with caching transient strings. If the refactored log system still needs to copy out state for later processing rather than perform it immediately then cbprintf could also be enhanced with a function that walks the format string extracting the specifications and provides them to a callback function, which would allow detecting string parameters precisely. That wouldn't work with |
@pabigot I was thinking about extending cbprint api with something like:
then change current cbvprint body and replace
didn't yet try it but it seems to be doable. |
Can you point me to the proposed solution using I think the general idea of what you propose has potential, but I'm still concerned about ensuring argument processing is consistent throughout. Unless you're matching arguments against format specifications, which would require the callback API I proposed, I don't believe you can correctly detect strings. E.g. how do you handle a char* argument in a position that corresponds to I have some ideas of how to generalize the cbprintf API but want to understand the rest of your solution architecture before determining the most flexible enhancement. |
All macro wizardry starts here: https://github.com/nordic-krch/zephyr/blob/7960fd342b65f1779e0c47c1dfc360237d61bf4d/include/logging/log_msg2.h#L399 First, The most important thing is that all this complex operations not compiled if log message does not contain There are two versions of macros: one that writes directly to the space allocated for message and second version which creates array with serialized arguments on the stack and pass it to the function. This is a bit slower but may take less rom and is suitable for user space. I will experiment to determine if it makes sense to keep both versions. I will experiment tomorrow with cbprint extension. |
But that's wrong. If I write:
I expect to see the string value of The only way I can see to get correct output is to walk the format string, decode the specifiers, and use the specifier character to determine that a copy of a string needs to be stored somewhere. No macro wizardry would be involved. I have API in mind that would do this and be flexible enough to handle a few other use cases I can imagine. Let me prototype that API and see whether it'll do what you need. |
yes, that is exactly as you wrote. In case of your example, logger will present exactly what you want, |
Also it is possible to apply extension only to |
Ew. OK; where's |
this function is already used in master: zephyr/subsys/logging/log_core.c Line 84 in 87dddda
The branch i'm working on: https://github.com/nordic-krch/zephyr/tree/log_64bits |
Thanks; I see that now. It is another decoding of the format specifier, which I'd hoped to avoid because parsing the format sequence to extract conversions correctly is not trivial. (For example But my first attempt at sharing the conversion extraction fails, because of the way My attempt is at: https://github.com/pabigot/zephyr/commits/nordic/20201208b Please read the message of the top commit, which identifies the core problem. If, in principle, you think something like what's prototyped in the API could work, and agree that we should try to re-use the existing conversion extraction code, I'll revisit this. |
That is more or less what I have in mind regarding Walk might be second option when |
And definitely |
Can we make logging select IMO it's reasonable to require complete support when using logging. @carlescufi you particularly wanted nano as an option, what do you think? |
Logging is big enough as a subsystem that |
The solution proposed here as I understand it is based on external processing of the log format string and argument At a high level this seems reasonable, but I believe the packaging of data that will be processed by cbprintf must be done by cbprintf, for both correctness and maintainability. An example of a case that can't easily be handled externally is a I've created #30675 which extends the cbprintf infrastructure with something that captures formatting information into a buffer, allowing it to be processed later. I have some hopes that this would make use of |
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:
log_strdup
RFC: adjust policies and introduce new macros for logging strings #18147Further weaknesses:
zephyr/subsys/logging/log_output.c
Line 278 in a953ac8
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. Anyfloat
arguments will be promoted to double, anychar *
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:
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.The text was updated successfully, but these errors were encountered: