This PR is an internal cleanup for util/log.h that fixes several problems with the logging macros defined there.
The main change is replacing the internal LogPrintLevel_ macro with a LOG_EMIT macro. It makes all the external logging macros (LogDebug, LogInfo, etc.) call LOG_EMIT, eliminating inconsistencies, improving efficiency, and producing clearer compiler errors when called incorrectly.
Specific problems this PR fixes:
-
LogPrintLevel_is easy to call incorrectly because it takeslevelandratelimitas independent options, whenratelimitshould almost always depend onlevel, and currently requires hacks like a runtime assert to ensure consistency. By contrast,LOG_EMITsets options correctly by default while allowing explicit overrides (e.g..ratelimit = false) for special cases. -
Unlike other logging macros,
LogPrintLevel_allows categories to be specified atInfo,Warning, andErrorlevels. By contrast,LOG_EMITmakes it a compile-time error to specify categories at these levels, or to omit them at lower levels. -
Current logging macros produce hard to decipher syntax errors when category arguments are specified but not allowed, or required but not provided. Now all logging macros produce clear
static_asserterrors indicating whether to add or remove category arguments. -
Current logging macros duplicate logic and have undocumented, untested differences. For example, some macros evaluate their arguments when logging is disabled and others do not. By constrast, the
LOG_EMITmacro implements logging logic in one place, preventing hidden inconsistencies. -
Having multiple implementations of logging macros makes it difficult to add new logging features (see below), because it requires changing many macros and adding separate macro arguments for each feature. Having a single core
LOG_EMITmacro taking a single compile-timeoptionsargument makes it possible to add new features cleanly. -
Current
LogInfo,LogWarning, andLogErrormacros generate log entries and callutil::log::Log(Entry)even when logging is disabled.LOG_EMITavoids this overhead, which is probably minor but could improve performance in some kernel applications and fuzzing.
Possible followups
This PR does not add any new logging features. It is purely an internal cleanup that fixes the problems listed above. However, it is worth noting that this PR could make it easier to add logging features in the future. For example:
-
New logging options could be added. Examples:
.stacktrace = trueto log the current stack trace,.exception = trueto log the current exception,.impossible = trueto indicate an impossible condition and halt fuzzing or request a bug report,.log_once = trueto log at most once from this source location,.log_every = 60mto log at most once per hour,.dedup = trueto drop duplicste messages, etc. -
External macros like
LogInfoandLogDebugcould accept these options. Example: f5ca95b1e610ebad7063143ddef98fc318251bc4 -
Context information could be added to log messages, e.g., wallet names, chainstate names, or request IDs to distinguish logs from paralell requests. Example: #30343
-
Non-global logging streams could also be supported. For example, kernel functions could accept optional logger arguments instead of always writing to the global logger. Example: #30342