log: Use __func__ for -logsourcelocations #34088

pull maflcko wants to merge 1 commits into bitcoin:master from maflcko:2512-log-func changing 4 files +53 −29
  1. maflcko commented at 9:49 am on December 17, 2025: member

    The -logsourcelocations option was recently changed to print the full function signature, as a side-effect of moving toward std::source_location internally.

    This is fine, but at least for me, it makes debugging functional test failures harder, because the log is just so massively verbose, with questionable benefit.

    I think the historically used file name, line number, and plain __func__ name are more than sufficient for -logsourcelocations.

    So switch back to using that.

    For reference, a verbose log may look like:

    0...
    1node0 2025-12-17T07:28:37.528146Z [init] [checkqueue.h:147] [CCheckQueue<T, R>::CCheckQueue(unsigned int, int) [with T = CScriptCheck; R = std::pair<ScriptError_t, std::__cxx11::basic_string<char> >]] Script verificatio
    2n uses 1 additional threads
    3...
    

    I don’t think there is value in printing stuff, like the (anon) namespace, the class template args, or the functionn (template) args. The following should be more than sufficient:

    0...
    1node0 2025-12-17T09:45:57.017122Z [init] [checkqueue.h:147] [CCheckQueue] Script verification uses 1 additional threads 
    2...
    
  2. DrahtBot added the label Utils/log/libs on Dec 17, 2025
  3. DrahtBot commented at 9:49 am on December 17, 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/34088.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK ajtowns, stickies-v
    Concept ACK Crypt-iQ, 0xB10C

    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)
    • #30343 (wallet, logging: Replace WalletLogPrintf() with LogInfo() by ryanofsky)
    • #29256 (log, refactor: Allow log macros to accept context arguments by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  4. maflcko force-pushed on Dec 17, 2025
  5. DrahtBot added the label CI failed on Dec 17, 2025
  6. maflcko force-pushed on Dec 17, 2025
  7. stickies-v commented at 11:48 am on December 17, 2025: contributor

    Concept ACK. I agree that for some functions (such as your example), the verbosity is a downside.

    Have you considered just capping the function_name() to, say, 20 characters, when printing? (could even make it fixed length to make logs a bit more uniform for readability) I think that’d be about as helpful without having to introduce our own SourceLocation?

  8. DrahtBot removed the label CI failed on Dec 17, 2025
  9. maflcko commented at 12:12 pm on December 17, 2025: member

    Have you considered just capping the function_name() to, say, 20 characters, when printing? (could even make it fixed length to make logs a bit more uniform for readability) I think that’d be about as helpful without having to introduce our own SourceLocation?

    I don’t think this works, because the return type is included in the function signature. I think printing something short but wrong is worse than printing the full thing.

    Some examples:

    0std::variant<int, double, float, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > {anonymous}::Foo<T>::calc_block_stats() [with U = double; T = int]
    

    Or:

    0 std::variant<int, double, float, std::string> (anonymous namespace)::Foo<int>::calc_block_stats() [T = int, U = double]
    

    So another simple alternative of just stripping after the first ( char does not work either.

  10. in src/logging.h:47 in fa41dd987e outdated
    42+{
    43+public:
    44+    /// The func argument must be constructed from the C++11 __func__ macro.
    45+    /// Ref: https://en.cppreference.com/w/cpp/language/function.html#func
    46+    /// Non-static string literals are not supported.
    47+    SourceLocation(const char* func,
    


    stickies-v commented at 1:29 pm on December 17, 2025:
    consteval could be help enforce that only strings with static lifetime are passed, at least somewhat reducing the potential of wrong use?

    maflcko commented at 3:14 pm on December 17, 2025:
    Not sure if __func__ is guaranteed to be consteval/constexpr?

    stickies-v commented at 4:36 pm on December 17, 2025:
    Eh, good point. It compiles for me but unsure how it’ll behave across platforms.
  11. stickies-v commented at 1:41 pm on December 17, 2025: contributor

    I don’t think this works, because the return type is included in the function signature. I think printing something short but wrong is worse than printing the full thing.

    Hmm, good point. And also, the function name is implementation-specific so manually trying to parse it is probably a bad idea. Approach ACK.

  12. in src/logging.h:61 in fa41dd987e outdated
    57+    std::source_location m_loc;
    58+};
    59+
    60 struct SourceLocationEqual {
    61-    bool operator()(const std::source_location& lhs, const std::source_location& rhs) const noexcept
    62+    bool operator()(const SourceLocation& lhs, const SourceLocation& rhs) const noexcept
    


    stickies-v commented at 1:59 pm on December 17, 2025:

    I’m not sure we should replace all std::source_location usage. There is value in uniformity, but I think it’s also good to keep places that don’t require the shorter function name to stick with stdlib? This is fairly trivial to achieve with e.g.:

     0diff --git a/src/logging.cpp b/src/logging.cpp
     1index b5baac0721..b321991930 100644
     2--- a/src/logging.cpp
     3+++ b/src/logging.cpp
     4@@ -388,7 +388,7 @@ std::shared_ptr<BCLog::LogRateLimiter> BCLog::LogRateLimiter::Create(
     5 }
     6 
     7 BCLog::LogRateLimiter::Status BCLog::LogRateLimiter::Consume(
     8-    const SourceLocation& source_loc,
     9+    const std::source_location& source_loc,
    10     const std::string& str)
    11 {
    12     StdLockGuard scoped_lock(m_mutex);
    13diff --git a/src/logging.h b/src/logging.h
    14index 8c276d4606..f0eb23c48e 100644
    15--- a/src/logging.h
    16+++ b/src/logging.h
    17@@ -51,6 +51,7 @@ public:
    18     std::string_view file_name() const { return m_loc.file_name(); }
    19     std::uint_least32_t line() const { return m_loc.line(); }
    20     std::string_view function_name() const { return m_func; }
    21+    operator const std::source_location&(){ return m_loc; };
    22 
    23 private:
    24     std::string_view m_func;
    25@@ -58,14 +59,14 @@ private:
    26 };
    27 
    28 struct SourceLocationEqual {
    29-    bool operator()(const SourceLocation& lhs, const SourceLocation& rhs) const noexcept
    30+    bool operator()(const std::source_location& lhs, const std::source_location& rhs) const noexcept
    31     {
    32         return lhs.line() == rhs.line() && std::string_view(lhs.file_name()) == std::string_view(rhs.file_name());
    33     }
    34 };
    35 
    36 struct SourceLocationHasher {
    37-    size_t operator()(const SourceLocation& s) const noexcept
    38+    size_t operator()(const std::source_location& s) const noexcept
    39     {
    40         // Use CSipHasher(0, 0) as a simple way to get uniform distribution.
    41         return size_t(CSipHasher(0, 0)
    42@@ -151,7 +152,7 @@ namespace BCLog {
    43         mutable StdMutex m_mutex;
    44 
    45         //! Stats for each source location that has attempted to log something.
    46-        std::unordered_map<SourceLocation, Stats, SourceLocationHasher, SourceLocationEqual> m_source_locations GUARDED_BY(m_mutex);
    47+        std::unordered_map<std::source_location, Stats, SourceLocationHasher, SourceLocationEqual> m_source_locations GUARDED_BY(m_mutex);
    48         //! Whether any log locations are suppressed. Cached view on m_source_locations for performance reasons.
    49         std::atomic<bool> m_suppression_active{false};
    50         LogRateLimiter(uint64_t max_bytes, std::chrono::seconds reset_window);
    51@@ -183,7 +184,7 @@ namespace BCLog {
    52         //! Consumes `source_loc`'s available bytes corresponding to the size of the (formatted)
    53         //! `str` and returns its status.
    54         [[nodiscard]] Status Consume(
    55-            const SourceLocation& source_loc,
    56+            const std::source_location& source_loc,
    57             const std::string& str) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
    58         //! Resets all usage to zero. Called periodically by the scheduler.
    59         void Reset() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex);
    

    With that diff (and perhaps without it too), it’s probably better to expose the abbreviated name under a different name, e.g. SourceLocation::function_name_short()?


    maflcko commented at 3:15 pm on December 17, 2025:

    Not sure about the implicit operator const std::source_location&(){ return m_loc; };. This seems like it could silently make some places use the wrong function name.

    function_name_short

    Thx, done


    stickies-v commented at 4:30 pm on December 17, 2025:

    This seems like it could silently make some places use the wrong function name.

    Not with function_name_short(), though? I think SourceLocation::function_name() behaving identical to std::source_location::function_name() is desirable, letting users explicitly choose between the stdlib behaviour or our custom behaviour?


    maflcko commented at 5:39 pm on December 17, 2025:

    This seems like it could silently make some places use the wrong function name.

    Not with function_name_short(), though? I think SourceLocation::function_name() behaving identical to std::source_location::function_name() is desirable, letting users explicitly choose between the stdlib behaviour or our custom behaviour?

    I am pretty sure that reverting a function argument incorrectly to const std::source_location& and incorrectly using funciton_name() will compile fine. Maybe “reverting” is a bit too theoretical, but I am thinking about silent merge conflicts, or future patches that accidentally use std::source_location.

    Just being type-safe seems better.

    If someone really wants the long name, a SourceLocation::function_name_long() could be added in the future.


    stickies-v commented at 10:34 am on December 18, 2025:

    If someone really wants the long name, a SourceLocation::function_name_long() could be added in the future.

    Sounds good to me, and I agree that this should only be added when necessary. My concern was more about needlessly converting code that doesn’t care about the function name being long or short, but I see your point about type safety. Can be marked as resolved.

  13. Crypt-iQ commented at 2:42 pm on December 17, 2025: contributor
    Concept ACK. The debug logs are harder to read now.
  14. maflcko force-pushed on Dec 17, 2025
  15. fanquake commented at 4:09 pm on December 17, 2025: member

    https://github.com/bitcoin/bitcoin/actions/runs/20307712389/job/58333931476?pr=34088#step:11:3126:

    0 /home/admin/actions-runner/_work/_temp/src/test/logging_tests.cpp:135:120: error: no member named 'function_name' in 'SourceLocation'
    1  135 |         expected.push_back(tfm::format("[%s:%s] [%s] %s%s", util::RemovePrefix(loc.file_name(), "./"), loc.line(), loc.function_name(), prefix, msg));
    2      |                                                                                                                    ~~~ ^
    31 error generated.
    
  16. 0xB10C commented at 4:20 pm on December 17, 2025: contributor
    Concept ACK! I’ve turned off -logsourcelocations since it wasn’t practical to use anymore for me after #32604. This would allow me to turn it back on.
  17. DrahtBot added the label CI failed on Dec 17, 2025
  18. DrahtBot commented at 5:21 pm on December 17, 2025: contributor

    🚧 At least one of the CI tasks failed. Task Windows-cross to x86_64, msvcrt: https://github.com/bitcoin/bitcoin/actions/runs/20307712389/job/58333931430 LLM reason (✨ experimental): Compile error in testing: SourceLocation::function_name() not available, causing test_bitcoin build to fail.

    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.

  19. log: Use `__func__` for -logsourcelocations facd3d56cc
  20. maflcko force-pushed on Dec 17, 2025
  21. DrahtBot removed the label CI failed on Dec 17, 2025
  22. ajtowns commented at 3:54 am on December 18, 2025: contributor
    ACK facd3d56ccbe2414a5f2b75be7132cd8b904f1e9 – those long signatures are terrible
  23. DrahtBot requested review from Crypt-iQ on Dec 18, 2025
  24. DrahtBot requested review from 0xB10C on Dec 18, 2025
  25. DrahtBot requested review from stickies-v on Dec 18, 2025
  26. stickies-v commented at 10:35 am on December 18, 2025: contributor
    ACK facd3d56ccbe2414a5f2b75be7132cd8b904f1e9
  27. fanquake merged this on Dec 18, 2025
  28. fanquake closed this on Dec 18, 2025

  29. maflcko deleted the branch on Dec 18, 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: 2025-12-31 06:13 UTC

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