Repository: bitcoin/bitcoin
File: src/logging.h (C/C++)

Code before:
        LIBEVENT    = (CategoryMask{1} << 17),
        COINDB      = (CategoryMask{1} << 18),
        QT          = (CategoryMask{1} << 19),
        LEVELDB     = (CategoryMask{1} << 20),
        VALIDATION  = (CategoryMask{1} << 21),
        I2P         = (CategoryMask{1} << 22),
        IPC         = (CategoryMask{1} << 23),
#ifdef DEBUG_LOCKCONTENTION
        LOCK        = (CategoryMask{1} << 24),
#endif
        BLOCKSTORAGE = (CategoryMask{1} << 25),
        TXRECONCILIATION = (CategoryMask{1} << 26),
        SCAN        = (CategoryMask{1} << 27),
        TXPACKAGES  = (CategoryMask{1} << 28),
        ALL         = ~NONE,
    };
    enum class Level {
        Trace = 0, // High-volume or detailed logging for development/debugging
        Debug,     // Reasonably noisy logging, but still usable in production
        Info,      // Default
        Warning,
        Error,
    };
    constexpr auto DEFAULT_LOG_LEVEL{Level::Debug};
    constexpr size_t DEFAULT_MAX_LOG_BUFFER{1'000'000}; // buffer up to 1MB of log data prior to StartLogging
    constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes per source location that can be logged within the specified time-window

    //! Fixed window rate limiter for logging.
    class LogRateLimiter
    {
    public:
        //! Keeps track of an individual source location and how many available bytes are left for logging from it.
        struct Stats {
            //! Remaining bytes
            uint64_t available_bytes;
            //! Number of bytes that were consumed but didn't fit in the available bytes.
            uint64_t dropped_bytes{0};

            Stats(uint64_t max_bytes) : available_bytes{max_bytes} {}
            //! Updates internal accounting and returns true if enough available_bytes were remaining
            bool Consume(uint64_t bytes);
        };

    private:
        mutable StdMutex m_mutex;

        //! Stats for each source location that has attempted to log something.
        std::unordered_map<std::source_location, Stats, SourceLocationHasher, SourceLocationEqual> m_source_locations GUARDED_BY(m_mutex);
        //! Whether any log locations are suppressed. Cached view on m_source_locations for performance reasons.
        std::atomic<bool> m_suppression_active{false};


Review comment (bug):
nit on 35585c54b57bbb05bfc4de63880c1767931e3696: more consistent parameterise both:

<details>
<summary>git diff on d0b3a80b7f</summary>

```diff
diff --git a/src/init.cpp b/src/init.cpp
index 63244c802e..863b2e088e 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1382,7 +1382,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
     LogInstance().SetRateLimiting(std::make_unique<BCLog::LogRateLimiter>(
         [&scheduler](auto func, auto window) { scheduler.scheduleEvery(std::move(func), window); },
         BCLog::RATELIMIT_MAX_BYTES,
-        1h));
+        BCLog::RATELIMIT_WINDOW));
 
     assert(!node.validation_signals);
     node.validation_signals = std::make_unique<ValidationSignals>(std::make_unique<SerialTaskRunner>(scheduler));
diff --git a/src/logging.h b/src/logging.h
index 5437d73c78..a2cbbf51f7 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -104,7 +104,8 @@ namespace BCLog {
     };
     constexpr auto DEFAULT_LOG_LEVEL{Level::Debug};
     constexpr size_t DEFAULT_MAX_LOG_BUFFER{1'000'000}; // buffer up to 1MB of log data prior to StartLogging
-    constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes per source location that can be logged within the specified time-window
+    constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes per source location that can be logged within the RATELIMIT_WINDOW
+    constexpr auto RATELIMIT_WINDOW{1h}; // time window after which log ratelimit stats are reset
 
     //! Fixed window rate limiter for logging.
     class LogRateLimiter

```
</details>


Code after:
        MEMPOOLREJ  = (CategoryMask{1} << 16),
        LIBEVENT    = (CategoryMask{1} << 17),
        COINDB      = (CategoryMask{1} << 18),
        QT          = (CategoryMask{1} << 19),
        LEVELDB     = (CategoryMask{1} << 20),
        VALIDATION  = (CategoryMask{1} << 21),
        I2P         = (CategoryMask{1} << 22),
        IPC         = (CategoryMask{1} << 23),
#ifdef DEBUG_LOCKCONTENTION
        LOCK        = (CategoryMask{1} << 24),
#endif
        BLOCKSTORAGE = (CategoryMask{1} << 25),
        TXRECONCILIATION = (CategoryMask{1} << 26),
        SCAN        = (CategoryMask{1} << 27),
        TXPACKAGES  = (CategoryMask{1} << 28),
        ALL         = ~NONE,
    };
    enum class Level {
        Trace = 0, // High-volume or detailed logging for development/debugging
        Debug,     // Reasonably noisy logging, but still usable in production
        Info,      // Default
        Warning,
        Error,
    };
    constexpr auto DEFAULT_LOG_LEVEL{Level::Debug};
    constexpr size_t DEFAULT_MAX_LOG_BUFFER{1'000'000}; // buffer up to 1MB of log data prior to StartLogging
    constexpr uint64_t RATELIMIT_MAX_BYTES{1024 * 1024}; // maximum number of bytes per source location that can be logged within the RATELIMIT_WINDOW
    constexpr auto RATELIMIT_WINDOW{1h}; // time window after which log ratelimit stats are reset
    constexpr bool DEFAULT_LOGRATELIMIT{true};

    //! Fixed window rate limiter for logging.
    class LogRateLimiter
    {
    public:
        //! Keeps track of an individual source location and how many available bytes are left for logging from it.
        struct Stats {
            //! Remaining bytes
            uint64_t m_available_bytes;
            //! Number of bytes that were consumed but didn't fit in the available bytes.
            uint64_t m_dropped_bytes{0};

            Stats(uint64_t max_bytes) : m_available_bytes{max_bytes} {}
            //! Updates internal accounting and returns true if enough available_bytes were remaining
            bool Consume(uint64_t bytes);
        };

    private:
        mutable StdMutex m_mutex;

        //! Stats for each source location that has attempted to log something.
        std::unordered_map<std::source_location, Stats, SourceLocationHasher, SourceLocationEqual> m_source_locations GUARDED_BY(m_mutex);