-
Notifications
You must be signed in to change notification settings - Fork 7k
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
log: add master log option (IDFGH-9721) #11057
Conversation
@someburner Thanks for the PR! This feature seems to have an odd interaction with Could we keep the existing API for setting the global log level? Something along these lines: esp_log_level_set("mytag", ESP_LOG_DEBUG); // (1) lowers "mytag" level to "DEBUG"
esp_log_level_set("*", ESP_LOG_NONE); // (2) all logs (including "mytag") now are disabled
esp_log_level_set("mytag", ESP_LOG_DEBUG); // (3) now "mytag" is enabled, everything else is disabled If the new Kconfig option is enabled, after point (2) the new "global" "minimal_log_level" variable would be set to ESP_LOG_NONE, and the checks for logs-disabled would be very quick. After point (3), "minimal_log_level" would again be set to ESP_LOG_DEBUG, so the checks would become slower, but the behavior would still be the same as it is now. This way, the component authors don't need to make assumptions whether the Kconfig option is set and write code accordingly. The behavior would be the same, just the performance/code size tradeoff would be different. Please let me know if this makes sense! Edit: corrected a typo in the code snippet |
@igrr that makes sense. I did think the API was a bit funky. So in this case you're suggesting to still keep this feature optional? And is it better to do a new PR or just add commits to this one. |
I think it should be optional if the global minimal log level is checked inside the log macro — since that leads to a significant increase in binary size. (If you can tolerate slightly lower performance and check the global log level inside esp_log_write then it doesn't have to be optional.) You can push more commits to this branch, and eventually squash the commits (git rebase -i) once you are done working on the feature. |
I feel like this feature is targeted at performance, the 100x->10x hit is significant so I'll leave it optional. Regarding your suggestion though- The only issue I see here is that some components call In particular there is So my concern is something else in the SDK calling It does seem like most of those are done in initialization functions. It would need to be clear in documentation exactly which components/options can undo this setting, and when. And that is not to mention the potential of closed source libraries calling it.. |
Another issue, potentially- In my case I want to be able to set various log tags to various levels at runtime, based on a configuration received from a server. But I still don't want the performance hit until I explicitly say "turn on the logs" however that is done. I suppose for that situation, I would have to set the various tags/levels to the desired configuration, and then call That could be achieved by having a From the perspective of those using this feature for performance, that all seems to be much more confusing. |
Hi @someburner!
It makes me think that you just want to enable and disable all logs. So I think a better solution that fits your needs would be to add APIs: esp_log_enable() and esp_log_disable(), without setting the log level. So I see the usage like this:
FYI, I am working on refactoring the log component so it will be much easier to add your feature after this work will be done. |
Regarding esp_log_enable/disable, one remark is that it's difficult to deal with such centralized log control unless you are in control of the entire application code. For example, if one of the components you depend on decides to use esp_log_enable/disable, that might affect logging from other components, and you won't be able to do much about the issue without modifying the component source code. |
Ideally, yeah. But in an environment of many components, and many logs, each taking 10us to check in cache, those times add up for end users who might have strict timing requirements, but also need visibility sometimes. In the embedded world you really can't have something like logging -not- affect other components unless your application has pretty loose timing requirements. I don't depend on many 3rd party components, and if I do, I manage them myself. I imagine a lot of people follow this workflow. I just grepped IDF and it appears only a few places where In any case, I believe it would be to everyone's benefit to have a policy for IDF components regarding |
Interested to see how the refactor looks. Please do keep in mind performance considerations in the refactor. In my case putting the check in the macro itself is preferred over checking inside a function. Or at least making it possible to hack something like this in but not maintained. For me the 10KB code increase is not a big deal on an 8MB or 16MB chip. Also- in my case with this PR I get slightly different IRAM sizes from
Seems like most of them not a big deal but probably not ideal to have it in I know this is a separate issue but goes towards my point of performance creep depending on log level. |
In my use case, I want to be able to turn on debug logs at runtime, but have them off by default without a big perf hit. I think a master switch, which is ideally only called by the end user is the best approach. If we want to make it play nice with other components, use a counting semaphore per log level. +1 on disable, -1 on enable. |
|
see #11049
Adds optional
LOG_MASTER_LEVEL
Kconfig option to log component. Results in 100x performance increase on ESP32 at 240Mhz when logs are compiled in, but disabled at runtime. Useful in cases where you only want log output some of the time. Results in a non-negligible increase in code size with lots of logs enabled, but that is also when you have the most to gain performance-wise.I have not added test cases pending feedback.
Other things worth considering:
noinit
section so setting is preserved across boots.Test it out for yourself: