log: Remove brittle and confusing LogPrintLevel #34051

pull maflcko wants to merge 4 commits into bitcoin:master from maflcko:2512-log-final-cleanup changing 8 files +58 −74
  1. maflcko commented at 7:08 pm on December 11, 2025: member

    LogPrintLevel has many issues:

    • It encourages to log several levels in one source location. This is problematic, because all levels (even warnings and errors) will be rate limited equally for the same location.
    • Its warning and error logs are specially formatted compared to all other warning and error logs in the codebase, making them harder to spot (both in the debug log and in the code).
    • It is verbose to type and read.
    • It is confusing, because the majority of code uses the Log$LEVEL(...) macros. Having less ways to achieve the same makes the code more consistent and easier to review.

    Fix all issues by removing it

  2. DrahtBot renamed this:
    log: Remove brittle and confusing LogPrintLevel
    log: Remove brittle and confusing LogPrintLevel
    on Dec 11, 2025
  3. DrahtBot added the label Utils/log/libs on Dec 11, 2025
  4. DrahtBot commented at 7:08 pm on December 11, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34051.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK stickies-v, pablomartin4btc, ajtowns
    Stale ACK w0xlt, rkrux

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #34038 (logging: API improvements by ajtowns)

    LLM Linter (✨ experimental)

    Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

    • [LogTrace(BCLog::HTTP, “trace_%s. This log level is lower than the global one.”, 2)] in src/test/logging_tests.cpp
    • [LogDebug(BCLog::HTTP, “debug_%s”, 3)] in src/test/logging_tests.cpp
    • [LogDebug(BCLog::NET, “debug_%s. This log level is the same as the global one but lower than the category-specific one, which takes precedence.”, 6)] in src/test/logging_tests.cpp

    2025-12-13

  5. maflcko force-pushed on Dec 11, 2025
  6. DrahtBot added the label CI failed on Dec 11, 2025
  7. DrahtBot commented at 7:15 pm on December 11, 2025: contributor

    🚧 At least one of the CI tasks failed. Task Windows-cross to x86_64, msvcrt: https://github.com/bitcoin/bitcoin/actions/runs/20144403035/job/57820697416 LLM reason (✨ experimental): C++ syntax error in wallet/coinselection.cpp due to mismatched braces (missing/extra brace) causing end-of-input and cascading “qualified-id … before ‘(’” errors.

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  8. DrahtBot removed the label CI failed on Dec 11, 2025
  9. in src/test/logging_tests.cpp:194 in fa35682637 outdated
    188@@ -207,22 +189,20 @@ BOOST_FIXTURE_TEST_CASE(logging_SeverityLevels, LogSetup)
    189     LogInstance().SetCategoryLogLevel(/*category_str=*/"net", /*level_str=*/"info");
    190 
    191     // Global log level
    192-    LogPrintLevel(BCLog::HTTP, BCLog::Level::Info, "foo1: %s\n", "bar1");
    193-    LogPrintLevel(BCLog::MEMPOOL, BCLog::Level::Trace, "foo2: %s. This log level is lower than the global one.\n", "bar2");
    194-    LogPrintLevel(BCLog::VALIDATION, BCLog::Level::Warning, "foo3: %s\n", "bar3");
    195-    LogPrintLevel(BCLog::RPC, BCLog::Level::Error, "foo4: %s\n", "bar4");
    196+    LogInfo("info_%s", 1);
    197+    LogTrace(BCLog::HTTP, "trace_%s. This log level is lower than the global one.", 2);
    


    stickies-v commented at 11:52 pm on December 11, 2025:
    nit: for people unfamiliar with these tests, it’s not obvious that the relevant debug/category settings are set in LogSetup. would be a nice improvement to make the test more self contained by explicitly setting them at the beginning of the test (even if it’s duplication)

    maflcko commented at 7:40 am on December 12, 2025:
    I’ve added a new LogDebug(BCLog::HTTP, in the line below, to clarify this in the test itself. If that is not sufficient, I am happy to push any diff or commit here, if someone writes one. Also, I am happy to review a separate pull, or a follow-up.

    stickies-v commented at 10:17 am on December 12, 2025:

    I’ve added a new LogDebug(BCLog::HTTP, in the line below, to clarify this in the test itself.

    That just made me wonder “wait why does this pass” rather than make it obvious that this was enabled in LogSetup. It’s confusing because in normal operation Info is the default level. I think the below diff is all that’s needed to make this test self-documenting.

     0diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp
     1index 3d95c97426..2a34aefae1 100644
     2--- a/src/test/logging_tests.cpp
     3+++ b/src/test/logging_tests.cpp
     4@@ -185,6 +185,7 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros_CategoryName, LogSetup)
     5 
     6 BOOST_FIXTURE_TEST_CASE(logging_SeverityLevels, LogSetup)
     7 {
     8+    LogInstance().SetLogLevel(BCLog::Level::Debug);
     9     LogInstance().EnableCategory(BCLog::LogFlags::ALL);
    10     LogInstance().SetCategoryLogLevel(/*category_str=*/"net", /*level_str=*/"info");
    11 
    

    maflcko commented at 10:33 am on December 12, 2025:

    Thanks for providing a diff. I’ve pushed a commit with that:

    0$ git diff fa35682637 fa33a9f5be -U0
    1diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp
    2index 3d95c97426..2a34aefae1 100644
    3--- a/src/test/logging_tests.cpp
    4+++ b/src/test/logging_tests.cpp
    5@@ -187,0 +188 @@ BOOST_FIXTURE_TEST_CASE(logging_SeverityLevels, LogSetup)
    6+    LogInstance().SetLogLevel(BCLog::Level::Debug);
    
  10. stickies-v approved
  11. stickies-v commented at 11:54 pm on December 11, 2025: contributor
    ACK fa35682637e7848106189e314a963d8f6c45b2bc
  12. in src/logging.h:379 in fa35682637 outdated
    380-// vulnerability if level >= Info is used. Additionally, users specifying -debug are assumed to be
    381+// Log by prefixing the output with the passed category name and severity level. This logs conditionally if
    382+// the category is allowed. No rate limiting is applied, because users specifying -debug are assumed to be
    383 // developers or power users who are aware that -debug may cause excessive disk usage due to logging.
    384-#define LogPrintLevel(category, level, ...)                           \
    385+#define detail_LogIfCategoryAndLevelEnabled(category, level, ...)     \
    


    Ataraxia009 commented at 5:32 am on December 12, 2025:

    Why not write it this like?

    0#define detail_LogIfCategoryAndLevelEnabled(category, level, ...)  
    1    do {                
    2        Assume(level < BCLog::Level::Info);                                             
    3        if (LogAcceptCategory((category), (level))) {
    4            LogPrintLevel_(category, level, false, __VA_ARGS__);
    5        }                                                            
    6    } while (0)
    

    maflcko commented at 7:34 am on December 12, 2025:

    Why not write it this like?

    0#define detail_LogIfCategoryAndLevelEnabled(category, level, ...)  
    1    do {                
    2        Assume(level < BCLog::Level::Info);                                             
    3        if (LogAcceptCategory((category), (level))) {
    4            LogPrintLevel_(category, level, false, __VA_ARGS__);
    5        }                                                            
    6    } while (0)
    

    That’d conceptually re-introduce the CVE from https://bitcoincore.org/en/2025/10/24/disclose-cve-2025-54605/:

    • The Assume is not hit in release builds, because it is compiled out. Only Assert are compiled into the release builds.
    • If some developer (accidentally or intentionally) re-introduces a call to detail_LogIfCategoryAndLevelEnabled with the Info level, the Assume would pass and the rate limiting would be disabled.

    I understand the CVE was low severity and the scenario to re-introduce it by accident is close to impossible, but I think it can’t hurt to leave in the belt-and-suspenders check for now. After all, it is just a single and trivial line of code.

    I’ll leave as-is for now, also to not invalidate the two existing reviews.


    Ataraxia009 commented at 9:55 am on December 12, 2025:
    sounds good

    Ataraxia009 commented at 11:22 am on December 12, 2025:
    I still don’t see the point of leaving the Assume in there since it seems to make no difference other than constricting somebody that would want to create a new macro for LogInfo w category. But i wont hold the PR back because of it.

    maflcko commented at 11:49 am on December 12, 2025:

    I still don’t see the point of leaving the Assume in there since it seems to make no difference

    The point of the Assume is to document internal assumptions for developers. The docs say No rate limiting is applied, . So writing an Assume(!rate_limit) ensures this to some extent for developers and documents it further.

    The assume is just a trivial single line, I don’t see the risk to keep it. It is also more trivial to remove, than to update the doc string itself.

    I’ll leave as-is for now, also to not invalidate the two existing reviews.


    pablomartin4btc commented at 7:32 pm on December 12, 2025:

    nit (if you have to retouch and agree):

    0#define detail_LogIfCategoryAcceptsLevel(category, level, ...)     \
    

    or detail_LogIfCategoryIsAcceptedAtLevel… perhaps it’s clearer and more consistent with existing internal call API LogAcceptCategory().


    Ataraxia009 commented at 5:24 am on December 13, 2025:

    doc string can be changed. No risk to keep it but also no point to add it imo. Can just be a normal function that only rate limits >= Info Level and only used within this file.

    But just move forward its fine

  13. Ataraxia009 commented at 5:33 am on December 12, 2025: none
    Concept Ack
  14. Ataraxia009 commented at 5:34 am on December 12, 2025: none
    This is good LogPrintLevel just leads to more confusion, standardise the macros!
  15. maflcko force-pushed on Dec 12, 2025
  16. stickies-v commented at 10:55 am on December 12, 2025: contributor

    re-ACK fa33a9f5be1beabfee6c217d133cc51dea3b9a63

    No changes except improved self-documentation of test, ty!

  17. DrahtBot requested review from w0xlt on Dec 12, 2025
  18. rkrux approved
  19. rkrux commented at 10:57 am on December 12, 2025: contributor

    ACK fa33a9f5be1beabfee6c217d133cc51dea3b9a63

    This is helpful. Having gone through the logging code recently, I found myself confused a bit upon seeing different ways to log. Removal of LogPrintLevel helps in decreasing the confusion by just using LOG<$LEVEL>() macros.

  20. pablomartin4btc commented at 7:32 pm on December 12, 2025: member

    ACK fa33a9f5be1beabfee6c217d133cc51dea3b9a63

    I agree with the benefits mentioned in the PR description.

  21. libevent: separate log statements per level
    Avoids ratelimiting unconditional log statements when debug logging
    is enabled. Introduces slight behaviour change by removing
    the category from unconditional logs, making them more uniform
    with the other unconditional logs in the codebase.
    
    Also, in a slight behavior change, prefix the info-level (and higher)
    messages with "libevent:".
    94c51ae540
  22. ipc: separate log statements per level
    Avoids ratelimiting unconditional log statements when debug logging
    is enabled. Introduces slight behaviour change by removing
    the category from unconditional logs, making them more uniform
    with the other unconditional logs in the codebase.
    
    Also, in a slight behavior change, prefix the info-level (and higher)
    messages with "ipc:".
    f273167661
  23. test: Clarify logging_SeverityLevels test
    The test was a bit confusing, because it just referred to the "global
    log level" without explicitly specifying what it is. The level is set
    though the LogSetup constructor. However, it is easier to follow unit
    tests, if they are self-contained. So just set the level to Debug
    explicitly here.
    
    Also, add a new debug_3 log, to further document the intended behavior
    of the unit test.
    
    Also, replace the LogPrintLevel with the shorter and exact replacements
    LogTrace and LogDebug.
    fac24bbec8
  24. in src/i2p.cpp:455 in fa33a9f5be
    451@@ -452,7 +452,7 @@ void Session::CreateIfNotCreatedAlready()
    452     m_session_id = session_id;
    453     m_control_sock = std::move(sock);
    454 
    455-    LogPrintLevel(BCLog::I2P, BCLog::Level::Info, "%s SAM session %s created, my address=%s\n",
    456+    LogInfo("%s SAM session %s created, my address=%s",
    


    ajtowns commented at 2:52 am on December 13, 2025:
    Should these log messages include “I2P” somewhere? Otherwise figuring out what SAM relates to may be confusing. The help text for -i2psam describes it as an “I2P SAM proxy”.

    maflcko commented at 1:53 pm on December 13, 2025:
    thx, done in all commits
  25. maflcko force-pushed on Dec 13, 2025
  26. maflcko force-pushed on Dec 13, 2025
  27. DrahtBot added the label CI failed on Dec 13, 2025
  28. DrahtBot commented at 12:12 pm on December 13, 2025: contributor

    🚧 At least one of the CI tasks failed. Task ASan + LSan + UBSan + integer: https://github.com/bitcoin/bitcoin/actions/runs/20191670716/job/57969925072 LLM reason (✨ experimental): i2p_tests failed due to an aborted subprocess caused by a SAM session error (Session was closed) during test execution.

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  29. log: Remove brittle and confusing LogPrintLevel fa8a5d215c
  30. maflcko force-pushed on Dec 13, 2025
  31. stickies-v commented at 1:39 pm on December 13, 2025: contributor
    re-ACK fa8a5d215c5a81a7282fd5dd1098f9d3fa40e5db
  32. DrahtBot requested review from rkrux on Dec 13, 2025
  33. DrahtBot requested review from pablomartin4btc on Dec 13, 2025
  34. pablomartin4btc approved
  35. pablomartin4btc commented at 1:54 pm on December 13, 2025: member
    re-ACK fa8a5d215c5a81a7282fd5dd1098f9d3fa40e5db
  36. DrahtBot removed the label CI failed on Dec 13, 2025
  37. ajtowns commented at 8:14 pm on December 13, 2025: contributor
    ACK fa8a5d215c5a81a7282fd5dd1098f9d3fa40e5db
  38. fanquake merged this on Dec 14, 2025
  39. fanquake closed this on Dec 14, 2025

  40. maflcko deleted the branch on Dec 15, 2025

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-01-01 12:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me