-
Notifications
You must be signed in to change notification settings - Fork 7.4k
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
Global log enable/disable (IDFGH-9712) #11049
Comments
Have you tried setting the maximum log level via menuconfig? Similarly have you tried calling something like |
Yes that's what I described. With lots of logs compiled in but few enabled, you incur a performance hit as each log is checked to see if it's enabled. |
There is also the KConfig setting for logs to disable all logs that are below a certain level, they simply will not be available in the compiled binary. But having a bit more control to disable logs (such as a NDEBUG build) would speed it up considerably. |
The stated use case is to make all logs available and run-time select-able, but without the performance hit. I understand you can simply not compile them in but that's not what I want. |
I don't think it is feasible to have everything compiled in without having a performance hit, at least for lower level components built into IDF itself. |
I benchmarked it, rudimentary, but clearly very feasible. I'm suggesting this as an optional feature for certain use cases and asking for feedback about pitfalls of doing things this way. The performance difference is 100x. If it were not so great I wouldn't be suggesting this. |
You're right. There is going to be a big perf difference. ESP_LOG_X supports a different log level per tag, so it does not do the runtime check later until this code:
Which is already after we've done all this code too:
I think it's reasonable to speed this up. I'd open a PR with your changes. But instead of a bool, I would do this:
And perhaps add a new function:
|
I think going that route it would have to be #define ESP_LOG_LEVEL_LOCAL(level, tag, format, ...) do { \
if ( (g_master_log_level >= level) && (LOG_LOCAL_LEVEL >= level) ) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \
} while(0) And a slight performance hit with the compare.
Not sure why compiled-in but set to none perf is better, you'd think it'd be worse. But I like that approach- if you only want say, INFO level then you retain perf of not hitting the cache for DEBUG, etc. |
+1 |
@someburner your comments are hard to follow. What numbers are you comparing here?
Can you clarify - in this statement how are you setting it to none? Using my approach, yours, esp_log_level_set? And better than what? |
In both cases I'm benching with max+default log level set to debug. The slow-running (8us / invocation) is when And the comment is saying it's strange that the "slow" case is oddly a little faster than when using the boolean check that I suggested in OP vs your recommendation. But actually I think what might be happening is depending on when you do |
Got it. So the |
Yeah I will open a PR soon. We'll see how it's received though. The API can be a little strange if you make it optional, and making it required adds a decent chunk to code size. They will want test cases added too and I'm lazy. But I can start with just the PR. |
Perhaps put the |
I think I tried that and it had worse perf. But I can double check before opening a PR. I don't think that would make any difference in terms of API though. Basically you either compile this in there and have the master_log_level and For now I'm just adding a Kconfig option. |
Here is my current 5.1 edits against 5.0. Some other stuff in there I added that might be useful for others too. Espressif is good about integrating PRs quickly but until they add the feature to use more dram as iram I have to maintain my own idf patch set. Might also want to add this to |
Running a few more checks here:
Not surprising at all since this still doesn't skip timestamps if enabled and has to call a function. Placing in IRAM doesn't help much. I suppose there could be an argument for a 10x perf bonus with a bit smaller code size but IMO 5-20K ish is not a big deal if you really want perf. |
My concern is IRAM functions that call ESP_LOGX will also be larger - many apps have little IRAM to spare. So of course, we should put this behind a KConfig. CONFIG_ESP_LOG_FAST_MASTER_LEVEL - increase perf of master level ignore at the cost of code size and internal ram We should also keep a check in |
More discussion in the PR: I am pretty sure most components dont put debug macros into IRAM methods. Although I should probably check my IRAM usage with/without this to see. Edit: Checked # iram remaining without master_level check
4730
# iram remaining with with master_level check
4662 So there are a few log macros hiding in IRAM somewhere it would seem. I dont think they are in my project. Essentially maintainer is asking to make this an optional feature but transparent to the API. From my perspective that adds a lot of "what ifs" to how I would like this feature to be used. Unless I can be sure that IDF components and closed source libraries are only using ESP_LOGx macros guarded by KConfig macros that always default to being off, then making it transparent to API is problematic for me. |
Hi! Since we have a PR #11057 for this issue I close this issue. |
Closes #11049 Closes #11057 Signed-off-by: KonstantinKondrashov <[email protected]> Result from an example in 11057: When this option is not enabled: 1000 iterations took 10914 microseconds (10.9 microseconds per invocation) 1000 iterations took 10909 microseconds (10.9 microseconds per invocation) When this option is enabled: 1000 iterations took 10960 microseconds (10.9 microseconds per invocation) 1000 iterations took 107 microseconds (0.1 microseconds per invocation)
Any thoughts on adding a global variable that can be used to enable/disable all logs at runtime?
Use case:
In some applications, it may be desirable to have many logs compiled (e.g. set a high CONFIG_LOG_MAXIMUM_LEVEL), but not impose a performance hit during normal operation, and only do so when instructed. E.g. for remote debugging, or perhaps having conditions in code where you want to start seeing logs.
The log cache seems to be fairly performant, but as an example, in my project if I compile in logs at
LOG_LEVEL_DEBUG
, but disable them at runtime withesp_log_level_set("*", ESP_LOG_NONE);
, there is enough of a performance hit that it warrants looking into.For me, this results in
Not too bad but if you have a lot of logs, it can start to add up.
If instead we add a global log variable and do something like this:
And switch that on/off each time with the test code:
You get:
Which is much more acceptable, but adds about 15KB to program size in my case. Any pitfalls with this / is this a bad idea? Should I be measuring differently?
The text was updated successfully, but these errors were encountered: