{
 "number": 29256,
 "repo": "bitcoin/bitcoin",
 "url": "https://github.com/bitcoin/bitcoin/pull/29256",
 "title": "log, refactor: Allow log macros to accept context arguments",
 "author": "ryanofsky",
 "author_association": "MEMBER",
 "created_at": "2024-01-16T22:09:35Z",
 "updated_at": "2026-09-11T02:31:30Z",
 "age_days": 974,
 "draft": true,
 "labels": [
  "Utils/log/libs"
 ],
 "milestone": null,
 "base": "master",
 "head_sha": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
 "head_ref": "pr/bclog",
 "head_repo": "ryanofsky/bitcoin",
 "head_history": [
  {
   "t": "2024-01-17T18:42:21Z",
   "sha": "d402c90a5c87922272be05a83e599cc3ffd7e1de"
  },
  {
   "t": "2024-01-17T19:15:15Z",
   "sha": "705f795aee4ebfdd0c785c7e39015cb43da2f0cf"
  },
  {
   "t": "2024-01-17T20:04:55Z",
   "sha": "632bbb887a40550477e753fbd24fa44fe030cb10"
  },
  {
   "t": "2024-01-17T20:22:48Z",
   "sha": "f929469779d17a9010f42b4db600fef7d6564934"
  },
  {
   "t": "2024-01-17T20:54:27Z",
   "sha": "15c08bcf359abba8e5c726df0f8c38acbe7aea81"
  },
  {
   "t": "2024-01-18T01:25:10Z",
   "sha": "99feed7350b5fc3ae3157dd395ae6260c5bfc092"
  },
  {
   "t": "2024-02-27T22:53:59Z",
   "sha": "0cd1616d47e61e125eb3e573573c0c56fba6b775"
  },
  {
   "t": "2024-02-27T23:45:00Z",
   "sha": "93d37f7d655409e6830475a10f4c9f16e35c76cd"
  },
  {
   "t": "2024-02-28T01:49:38Z",
   "sha": "a91fbbd61551702f26f734f3cdd1c080f9d51628"
  },
  {
   "t": "2024-03-28T16:55:50Z",
   "sha": "ce0004e42d37786f98cdf9d55b976b935dcf1ba1"
  },
  {
   "t": "2024-06-26T17:49:26Z",
   "sha": "5f64eab013a58967af37a59c863c2ab6d45ba6e8"
  },
  {
   "t": "2024-06-27T03:12:31Z",
   "sha": "38d3298ea7e547797871140a02df3e7d60d34d36"
  },
  {
   "t": "2024-06-28T14:11:37Z",
   "sha": "681b21f7ca07f0e1411354baa01649e7b1f30e8c"
  },
  {
   "t": "2024-08-07T01:56:15Z",
   "sha": "46f5e27e86f9bd2c88df86f0d652fedab1bd0f21"
  },
  {
   "t": "2024-12-09T19:11:46Z",
   "sha": "48b3c951aa256c6be0cc50461de00f758d92dcb4"
  },
  {
   "t": "2024-12-09T20:29:57Z",
   "sha": "5db1958e60aef9d3604448c21e1f397e561480ee"
  },
  {
   "t": "2025-04-03T17:30:51Z",
   "sha": "07295ff649e72e267b6f285dcf0f670e676019ef"
  },
  {
   "t": "2025-04-03T17:36:56Z",
   "sha": "2ebcc54b886dd7e54688bf7e0a6238e354a35236"
  },
  {
   "t": "2025-04-03T19:13:06Z",
   "sha": "176ad35e69b2f0ba94b4db47c66a583b1bf87744"
  },
  {
   "t": "2025-04-04T03:35:23Z",
   "sha": "093d58e055b10a1031c97b24de5e029221f176d7"
  },
  {
   "t": "2025-10-15T00:42:14Z",
   "sha": "d032022ff59204b85b2057ab9a88f4d2842dbde9"
  },
  {
   "t": "2025-10-16T13:37:34Z",
   "sha": "a66d1e27f11b2c061879dbee02b889fad5cc2669"
  },
  {
   "t": "2025-10-16T14:46:28Z",
   "sha": "8428899fb97ea5f71e879f958b4f10846f28e73a"
  },
  {
   "t": "2025-11-10T23:35:04Z",
   "sha": "3e4c8b9320783f2985937e9f326df3bc532e7905"
  },
  {
   "t": "2025-12-12T12:19:40Z",
   "sha": "cecf87c92a459b462d98d43c3e5c0b87286c1e4e"
  },
  {
   "t": "2025-12-16T02:10:49Z",
   "sha": "c566ebc71083e93b6898e37549fc42eb524dcf10"
  },
  {
   "t": "2026-01-18T01:00:50Z",
   "sha": "326c62d1d327549526f2975342bd64c82231a16a"
  },
  {
   "t": "2026-01-18T14:37:32Z",
   "sha": "1ceea94931b72bc1f949fbaab1f26a0ef6eb4a21"
  },
  {
   "t": "2026-02-09T13:25:02Z",
   "sha": "e19ce37359227849ec55d45dfd33303ccaceeccf"
  },
  {
   "t": "2026-02-09T14:30:56Z",
   "sha": "487f7e77cf8569b15a86631e03439dd648703822"
  },
  {
   "t": "2026-03-02T00:50:37Z",
   "sha": "6d91998175b40939001e01ae2cd78571bff392b7"
  },
  {
   "t": "2026-03-04T16:25:39Z",
   "sha": "fe17020b09ca223be907ed964bfc63b7a4fe8e1b"
  },
  {
   "t": "2026-03-09T15:43:34Z",
   "sha": "724b5aed21d6abe6345d8b556d7f6b4ff4a8494a"
  },
  {
   "t": "2026-04-01T18:53:24Z",
   "sha": "551a030b6fcfa5671bb0da73c66b1a7c1fd2d0a4"
  },
  {
   "t": "2026-05-07T08:02:15Z",
   "sha": "7eef6bfa91d5aade1d6984a75f2a4315e0f48167"
  },
  {
   "t": "2026-05-27T00:54:44Z",
   "sha": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e"
  }
 ],
 "additions": 417,
 "deletions": 114,
 "changed_files": 6,
 "commit_count": 10,
 "size_bucket": "L",
 "mergeable_state": "clean",
 "bot": {
  "drahtbot": {
   "present": true,
   "reviews": {
    "concept_nack": [
     {
      "login": "hodlinator",
      "url": "https://github.com/bitcoin/bitcoin/pull/29256#pullrequestreview-2142978382"
     },
     {
      "login": "ajtowns",
      "url": "https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-4005436980"
     }
    ],
    "concept_ack": [
     {
      "login": "sedited",
      "url": "https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2189810744"
     },
     {
      "login": "jonatack",
      "url": "https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2197318437"
     }
    ]
   },
   "conflicts": [
    {
     "number": 36197,
     "title": "kernel: Replace application log callbacks with file logging",
     "author": "w0xlt"
    },
    {
     "number": 35322,
     "title": "logging: streamline Logger state and drop redundant methods",
     "author": "ryanofsky"
    }
   ]
  }
 },
 "acks_parsed": {
  "ajtowns": {
   "kind": "concept_nack",
   "hash": null,
   "t": "2024-01-16T22:34:50Z",
   "stale": false
  },
  "sedited": {
   "kind": "concept_ack",
   "hash": null,
   "t": "2024-06-25T19:26:27Z",
   "stale": false
  },
  "hodlinator": {
   "kind": "nack",
   "hash": "5f64eab013a58967af37a59c863c2ab6d45ba6e8",
   "t": "2024-06-26T22:02:30Z",
   "stale": false
  }
 },
 "acks_tally": {
  "ack": 0,
  "stale_ack": 0,
  "concept_ack": 1,
  "approach_ack": 0,
  "nack": 1,
  "concept_nack": 1,
  "approach_nack": 0
 },
 "reviews": {
  "approved": 0,
  "changes_requested": 3,
  "distinct_reviewers": [
   "ajtowns",
   "hodlinator",
   "jonatack",
   "l0rinc",
   "sedited",
   "vasild"
  ]
 },
 "signals": {
  "needs_rebase": false,
  "ci_failed": false,
  "mergeable_state": "clean",
  "last_author_activity": "2026-05-27T00:54:44Z",
  "last_reviewer_activity": "2026-03-05T14:24:33Z",
  "last_reviewer": "ajtowns",
  "author_silent_days": 113,
  "waiting_on_author_days": 0,
  "days_since_update": 6
 },
 "refs": {
  "mentioned": [
   3009,
   16545,
   26836,
   28318,
   29077,
   30338,
   30342,
   30343,
   30347,
   30348,
   30355,
   30361,
   30364,
   30386,
   31174,
   33517,
   33847,
   34038,
   34374,
   34465,
   34729,
   34730,
   34778
  ],
  "depends_on": [
   34778
  ],
  "fixes": [],
  "linked_issues": [],
  "references": [
   {
    "number": 34778,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "logging: rewrite macros to enforce restrictions at compile-time, improve efficiency and usability"
   },
   {
    "number": 30343,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "wallet, logging: Replace WalletLogPrintf() with LogInfo()"
   },
   {
    "number": 30342,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "kernel, logging: Pass Logger instances to kernel objects"
   },
   {
    "number": 3009,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2013-09-18",
    "title": "Remove #define printf, replace OutputDebugStringf with LogPrint(f)"
   },
   {
    "number": 16545,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "refactor: Implement missing error checking for ArgsManager flags"
   },
   {
    "number": 26836,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2024-02-08",
    "title": "wallet: batch and simplify addressbook migration process"
   },
   {
    "number": 28318,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2024-01-10",
    "title": "logging: Simplify API for level based logging"
   },
   {
    "number": 29077,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "build: Require libc++-16 or later"
   },
   {
    "number": 30338,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "RFC: Instanced logs"
   },
   {
    "number": 30347,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "logging: Use LogFatal instead LogError for fatal errors"
   },
   {
    "number": 30348,
    "type": "issue",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "RFC: Misused LogError and LogWarning macros"
   },
   {
    "number": 30355,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2024-07-08",
    "title": "wallet: use LogTrace for walletdb log messages at trace level"
   },
   {
    "number": 30361,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "doc: Drop description of LogError messages as fatal"
   },
   {
    "number": 30364,
    "type": "pull",
    "state": "closed",
    "merged": false,
    "merged_at": null,
    "title": "logging: Replace LogError and LogWarning with LogAlert"
   },
   {
    "number": 30386,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2024-07-26",
    "title": "Early logging improvements"
   },
   {
    "number": 31174,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2024-11-14",
    "title": "tinyformat: Add compile-time checking for literal format strings"
   },
   {
    "number": 33517,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2025-10-14",
    "title": "multiprocess: Fix high overhead from message logging"
   },
   {
    "number": 33847,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "kernel: Improve logging API"
   },
   {
    "number": 34038,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "logging: replace -loglevel with -trace, expose trace logging via RPC"
   },
   {
    "number": 34374,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "kernel: use struct-based logging and simplify logging interface"
   },
   {
    "number": 34465,
    "type": "pull",
    "state": "closed",
    "merged": true,
    "merged_at": "2026-02-07",
    "title": "refactor: separate log generation from log handling"
   },
   {
    "number": 34729,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "Reduce log noise"
   },
   {
    "number": 34730,
    "type": "pull",
    "state": "open",
    "merged": false,
    "merged_at": null,
    "title": "util/log: Combine the warning/error log levels into a single alert level"
   }
  ],
  "conflicts": [
   36197,
   35322
  ]
 },
 "stack": {
  "shares_commits_with": [
   30342,
   30343,
   34778
  ],
  "based_on": [
   34778
  ],
  "base_for": [
   30342,
   30343
  ]
 },
 "review_paths": [
  "doc/developer-notes.md",
  "src/logging.cpp",
  "src/logging.h",
  "src/signet.cpp",
  "src/test/logging_tests.cpp",
  "src/util/log.h"
 ],
 "body": "Allow `LogTrace()`, `LogDebug()`, `LogInfo()`, `LogWarning()`, and `LogError()` macros to accept context arguments to provide more information in log messages and more control over logging to callers.\n\nFor example, with this change wallet code can log with (in #30343):\n\n```diff\n-        WalletLogPrintf(\"Error: cannot erase address book entry data\\n\");\n+        LogError(m_log, \"Error: cannot erase address book entry data\\n\");\n```\n\nAnd kernel code can log with (in #30342):\n\n```diff\n-        LogDebug(BCLog::VALIDATION, \"Block mutated: %s\\n\", state.ToString());\n+        LogDebug(log, \"Block mutated: %s\\n\", state.ToString());\n```\n\nwhere `m_log` / `log` types can vary and be defined by the subsystem. This allows subsystems to attach extra context to log messages like wallet names, or request ids. It also allows more than a single log stream to exist, and for messages to be logged to specified streams. Having a single global log stream works very well for `bitcoind` and will not change. But it limits functionality of libbitcoinkernel, forcing all potential users of the library, including applications written in different languages and running in different environments (like jupyter notebooks) to use shared global state and not be able to do things like get an isolated log trace from one operation.\n\nThe change is fully backwards compatible and does not require any updates to code that wants to continue using the macros as they are. The implementation of the macros is also improved. They now provide improved error messages when called with the wrong arguments. And they only call underlying `ShouldLog` `Log` and `Format` hooks as needed to avoid unnecessary work. The PR also adds more test coverage and documentation.\n\n---\n\nNote: Originally this PR also removed some restrictions around passing category constants to log macros to try to make them more consistent, but these changes were too controversial and have been dropped.\n\n---\n\n**This is based on #34778.** The non-base commits are:\n\n- [`aa37de26b0f` log refactor: Allow log macros to accept context arguments](https://github.com/bitcoin/bitcoin/pull/29256/commits/aa37de26b0f31d1d731fc3a3fe20ca9d99f69062)\n- [`1eedcb9db51` doc: Add documentation about log levels and macros](https://github.com/bitcoin/bitcoin/pull/29256/commits/1eedcb9db5156d36916ce4ccac49096a61d9c186)\n- [`b5d3925d274` log refactor: Add support for custom log contexts](https://github.com/bitcoin/bitcoin/pull/29256/commits/b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e)",
 "commits": [
  {
   "sha": "963ed23bc8c466188c2be7553ae383cf182c24b4",
   "date": "2026-05-26T12:39:03Z",
   "message": "log test: verify log argument evaluation semantics\n\nTest that LogInfo/LogWarning/LogError always evaluate their arguments\neven when logging is disabled.\n\najtowns pointed out this behavior was important and could affect non-logging\ncode if changed in\nhttps://github.com/bitcoin/bitcoin/pull/34374#discussion_r2734793117\n\nCo-authored-by: l0rinc <pap.lorinc@gmail.com>"
  },
  {
   "sha": "3ea9b7cb10f0667d7fd1d2e8b4e25e8aea9932b3",
   "date": "2026-05-26T12:39:03Z",
   "message": "log test: add some test coverage on LogAcceptCategory\n\nCo-authored-by: Ryan Ofsky <ryan@ofsky.org>"
  },
  {
   "sha": "9c509ca53c0185a8f5b96c2a5aa3a5b7d73045a7",
   "date": "2026-05-26T12:39:03Z",
   "message": "log test: Add test for all accepted logging arguments\n\nAdd new logging test to call macros with all allowed combinations of macro\narguments.\n\nThe new test replaces a less comprehensive test that doesn't cover log\nstatements without format arguments. It's also moved to the top of the test\nsuite because it's a good illustration of what typical log prints look like,\nwhat logging calls are allowed and disallowed, and what the resulting log\noutput looks like."
  },
  {
   "sha": "98f3bd6242d999191f442271a77eb8cac7949ca1",
   "date": "2026-05-26T12:39:03Z",
   "message": "log refactor: Ensure categories are not logged at info and higher levels\n\nPreviously this used to be possible through the LogPrintLevel call but now that\ncall is removed, this change is just an internal refactoring and has no visible\neffect except in tests."
  },
  {
   "sha": "31f9929f3dea586104c0c11d7533385e139bdbdf",
   "date": "2026-05-26T12:39:03Z",
   "message": "log refactor: log macro rewrite\n\nRewrite log macros to fix a number of issues: unnecessary strprintf\ncalls during fuzzing, confusing error messages when macros are called\nwith the wrong arguments, duplicated code with unexplained differences\nand undocumented assumptions.\n\nSince this is a rewrite, reading the new code in log.h first should be clearer\nthan starting from the diff.\n\nSpecific benefits of the new implementation are:\n\n- Functionality is implemented once in a single `LOG_EMIT` macro instead of\n  multiple times in different macros with diverging code paths and unexplained\n  differences.\n\n- Unnecessary `strprintf` calls are now skipped when logging is disabled (in\n  bitcoind when `-noprinttoconsole -nodebuglogfile` options are used, and in\n  tests and kernel applications when DisableLogging is called). This change\n  should not affect bitcoind noticeably, but could speed up fuzz tests calling\n  functions which log.\n\n- Clearer error messages: If you pass a category to a macro which does not\n  accept it, or forget to pass a category to a macro which requires it, you\n  will see a direct message telling you to add or remove the category instead\n  of expanded macro syntax errors.\n\n- Previously it was possible to call `detail_LogWithSrcLoc` with\n  inconsistent or invalid arguments, for example bypassing ratelimiting\n  without it being explicit. New `LOG_EMIT` macro is compile-time safe\n  and enforces the exact same restrictions as other macros.\n\n- Previously \"always evaluate arguments\" behavior at Info and higher levels\n  looked accidental and was undocumented\n  (https://github.com/bitcoin/bitcoin/pull/34374#discussion_r2734793117). Now\n  the behavior is documented and explicit.\n\n- `NO_RATE_LIMIT` special case used to bypass rate limiting is dropped.\n  The `LOG_EMIT` macro can control rate limiting (and other options if\n  they are added in the future) while still using the same ratelimiting\n  defaults as other macros.\n\nCo-Authored-By: Hodlinator <172445034+hodlinator@users.noreply.github.com>\nCo-Authored-By: stickies-v <stickies-v@protonmail.com>"
  },
  {
   "sha": "f0929e1b781af5012d835f78a8b54054fb5cb21e",
   "date": "2026-05-26T12:39:03Z",
   "message": "log refactor: Drop Entry::should_ratelimit field\n\nDrop Entry::should_ratelimit field in favor of Options::ratelimit field.\n\nDropping the Entry::should_ratelimit field makes buffered log messages\nin m_msgs_before_open smaller, and avoids potential confusion because\nthe field is stored after rate limiting has been applied, so just gets\nignored. Conceptually it also makes sense to treat the ratelimit option\nas an input to the logger rather than as an attribute of the message\nbeing logged."
  },
  {
   "sha": "1ac1be8b159198d779bb0a37c4fbbbe5b5070ffb",
   "date": "2026-05-26T12:39:03Z",
   "message": "Merge branch 'pr/relog' into pr/bclog"
  },
  {
   "sha": "aa37de26b0f31d1d731fc3a3fe20ca9d99f69062",
   "date": "2026-05-26T12:39:03Z",
   "message": "log refactor: Allow log macros to accept context arguments\n\nAllow LogDebug(), LogTrace(), LogInfo(), LogWarning(), and LogError() macros to\naccept context arguments to provide more information in log messages and more\ncontrol over logging to callers.\n\nThis functionality is used in followup PRs:\n\n- https://github.com/bitcoin/bitcoin/pull/30342 - To let libbitcoinkernel send\n  output to specfic `BCLog::Logger` instances instead of a global instance, so\n  output can be disambiguated and applications can have more control over\n  logging.\n\n- https://github.com/bitcoin/bitcoin/pull/30343 - To replace custom\n  `WalletLogPrintf` calls with standard logging calls that automatically include\n  wallet names and don't log everything at info level.\n\nThis commit does not change behavior of current log prints or require them to\nbe updated. It includes tests and documentation covering the new functionality.\n\nCo-Authored-By: Hodlinator <172445034+hodlinator@users.noreply.github.com>\nCo-Authored-By: stickies-v <stickies-v@protonmail.com>"
  },
  {
   "sha": "1eedcb9db5156d36916ce4ccac49096a61d9c186",
   "date": "2026-05-26T12:39:03Z",
   "message": "doc: Add documentation about log levels and macros"
  },
  {
   "sha": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "date": "2026-05-26T12:39:03Z",
   "message": "log refactor: Add support for custom log contexts\n\nCustom log contexts allow overridding log formatting and adding metadata, such\nas request ids or wallet names to log messages, while still using standard\nmacros for logging. This is used to replace WalletLogPrintf() functions with\nLogInfo() calls in followup PR #30343."
  }
 ],
 "timeline": [
  {
   "t": "2024-01-16T22:34:50Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "Concept NACK from me, this seems much uglier and trickier to work with. I've already written [in depth](https://github.com/bitcoin/bitcoin/pull/28318#issuecomment-1702318968) about why the current approach makes sense, so I'll be brief here.\n\n[quoted text omitted]\nBeing able to avoid logging critical messages is adding a bug, not a feature.\n\n[quoted text omitted]\n\"+841 -626\" and adding a dummy parameter to most calls does not make things less verbose, and it's also much harder to search for net related logging when the individual log statements just say `m_log` rather than `BCLog::NET`.\n\n[quoted text omitted]\nThe only thing needed here is renaming from `Printf` to `Info`..."
  },
  {
   "t": "2024-01-17T04:41:32Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "Hi AJ, this is a draft, and there will be some more changes which may address your concerns.\n\n[quoted text omitted]\nAgree, but the idea here is not to discard log messages, the idea just is to attach meaningful metadata to log messages so they can be filtered by component.\n\n[quoted text omitted]\nI can probably make the description clearer, but the idea here is that this will make the code less noisy:\n\n```diff\n-LogPrintLevel(BCLog::NET, BCLog::Level::Warning, \"getsockname failed\\n\");\n+LogWarning(log, \"getsockname failed\\n\");\n```\n\nIt is true this sacrifices ability to grep by category constants in the source code, and maybe in your judgement that is an unacceptable cost? But in my opinion, if we ever using same category constants in disparate parts of source code, or different category constants in the same part of the source code, it means source code is badly organized and we should fix that instead of resorting to a coping mechanism of searching for constants instead of searching by source path. In my experience, I've haven't used logging frameworks that have encouraged category constants to be scattered and mixed like this, and I don't think it is a good idea.\n\nThe \"+841 -626\" refactoring is definitely :hankey:-y and I plan to drop it from this PR. The change to the log macros is meant to facilitate that refactoring, not the other way around. I do think we should stop relying on the global logging instance for libbitcoinkernel code, but probably can keep using it elsewhere.\n\n[quoted text omitted]\nProbably something is lost in communication here, but the idea is to let wallet code use same LogDebug(), LogTrace(), LogInfo(), LogWarning(), LogError() macros other code uses. It just adds a little formatting hook so the wallet name is automatically included when the log source is the wallet. This way full functionality of #29256 is available to the wallet and we can drop WalletLogPrintf and not have dedicated wallet logging functions."
  },
  {
   "t": "2024-01-17T18:42:21Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "d402c90a5c87922272be05a83e599cc3ffd7e1de"
  },
  {
   "t": "2024-01-17T19:15:15Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "705f795aee4ebfdd0c785c7e39015cb43da2f0cf"
  },
  {
   "t": "2024-01-17T20:04:55Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "632bbb887a40550477e753fbd24fa44fe030cb10"
  },
  {
   "t": "2024-01-17T20:22:48Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "f929469779d17a9010f42b4db600fef7d6564934"
  },
  {
   "t": "2024-01-17T20:54:27Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "15c08bcf359abba8e5c726df0f8c38acbe7aea81"
  },
  {
   "t": "2024-01-18T01:25:10Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "99feed7350b5fc3ae3157dd395ae6260c5bfc092"
  },
  {
   "t": "2024-01-19T06:12:29Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nFiltering is discarding.\n\nIf you just want to *find* log messages, that what's grep is for, and if you want to make it more fine-grained than \"hey this is an important log message/warning/error\", that's what `-logsourcelocations` is for.\n\nIf it's any help, I think it's better to think of the sections as not related to which section of the code they appear in so much (again, that's what `-logsourcelocations` is for), but as a subset of the \"debug\" part, in that they let you filter/discard various parts of the full debug log that you would get with `-debug=1`.\n\n[quoted text omitted]\nThe current code there is noisy because it uses `LogPrintLevel`. The change you're actually making is:\n\n```diff\n-LogWarning(\"getsockname failed\\n\");\n+LogWarning(log, \"getsockname failed\\n\");\n```\n\nwhich is adding characters, without adding any information to the reader.\n\n[quoted text omitted]\nI think `LogDebug(BCLog::NET, \"oh no, it all went wrong\\n\")` is better than `LogDebug(m_log, \"oh no, it all went wrong)`. All the characters in the former are doing something useful; `m_log` in the latter isn't (if it weren't for macro magic, we'd write `m_log.Debug(\"...\")` instead, which would be okay at least). I don't think moving the category away from the line of code it's affecting is very useful; and if you want to group all the logs from an individual file together (the way putting `m_log{BCLog::NET}` at the top of the file/class does), then, again, that's what logsourcelocations is for...\n\n[quoted text omitted]\nThat's something that already happens: `BCLog::NET` is in timedata and headersync and banman and net and net_processing; `BCLog::VALIDATION` is in validation and validationinterface and flatfile (thought there was a pr to fix that one) and signet; `BCLog::MEMPOOL` is in txmempool, validation and net_processing. It doesn't mean the source code is badly organised, it means different parts of the source are generating related log messages.\n\n[quoted text omitted]\nI don't think there is anything here \"encouraging\" these categories to be scattered or mixed; most of them are specific to a small set of related files: TOR:torcontrol, HTTP:httpserver, ZMQ:zmq/*, WALLETDB:wallet/*, ESTIMATEFEE:policy/fees.cpp, SELECTCOINS:wallet/coinselection, REINDEX:validation, CMPCTBLOCK:blockencodings, RAND:random.cpp, etc.\n\nAnd you obviously have worked with code designed this way: that's how `LogPrint` has worked in this codebase since it was implemented in #3009.\n\n[quoted text omitted]\nUpdating `TraceSqlCallback` to call `LogTrace` rather than `LogPrintf` would be an improvement as those messages would get categorised properly; but otherwise this seems like massive overkill just to avoid writing `\"[%s] ...\", walletname, ...`.\n\n[quoted text omitted]\nA +190 -109 diff because you don't like a one-line wrapper function seems crazy to me.\n\nDo you have some reason to think there's large amounts of additional wallet debug logs that would be introduced if it didn't involve writing `[%s], walletname` or are there a bunch of the current unconditional `WalletLogPrintf` calls that should be silenced and only available when debugging is enabled?"
  },
  {
   "t": "2024-01-25T20:03:28Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "@ajtowns, to try to steer this discussion in a more constructive direction, would it be possible for you to make a list of the biggest harms you believe this PR would cause if it were merged? And if you have ideas on how the harms you see could be avoided, while the problems I am trying to solve (see \"Problems this PR attempts to solve\" in the PR description) could be addressed, it would be really helpful to know about. Maybe the harms you see this PR causing and the problems this PR is trying to solve are in direct contradiction, but it's not obvious to me that this is the case, so maybe there is a way out of our disagreement here. In the meantime, I responded to your last message below.\n\nre: https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-1899825975\n\n[quoted text omitted]\nIt's really not. You can view logs into a text editor or log viewer and highlight categories of messages you are interested in while not discarding other messages.\n\nI am just trying to add some basic flexibility here. If you don't want to attach categories to log messages, you don't have to, you can write `LogWarning({}, \"uncategorizable warning\")`. The PR just makes the log macros consistently accept a source parameter, so code has flexibility to set a category, set a log destination, add metadata to log messages, control log formatting, do a combination of these things, or do none of these things.\n\n[quoted text omitted]\nThis adds 5 characters, but also adds category information that was previously absent to the output. You can find examples of where the API changes in this PR increase verbosity, and examples where they decrease it, and I think there should be less verbosity on net. I also think some of this discussion around verbosity misses the bigger picture, and is a distraction from the actual goal of the PR, which is to add context to log messages, and give code that needs it control over logging behavior. But if making the log parameter optional is a requirement for you, it should be possible to implement that here and never increase verbosity in any case.\n\n[quoted text omitted]\nI agree `m_log.Debug(\"...\")` would be better than `LogDebug(m_log, \"...\")` but I don't understand why the former would be ok, but the latter is unacceptable. You definitely have much stronger opinions about verbosity than me, so maybe we can try to engage more constructively on this. I think on net, this PR should reduce verbosity, but maybe more improvements are possible that could alleviate your concerns.\n\n[quoted text omitted]\nThat's ok, since allowing this was a side effect, not a major goal of this PR. But `LogDebug(m_log, \"debug message\")` can be easier to write and read than `LogDebug(BCLog::TXRECONCILIATION, \"debug message\")`, especially if the code has a lot of log prints and the category is repeated a lot. In any case, you aren't forced to choose one approach or the other. The PR allows both.\n\n[quoted text omitted]\nOk, we definitely disagree on how well the code is organized. IMO, `validation.cpp` doing `BCLog::MEMPOOL` prints is messed up. But this is a tangent. I think log sources should encourage better organization, but this PR does not force anything or break anything that works now.\n\n[quoted text omitted]\nI don't want to make a big deal out of this, but just to clarify, I think the status quo where trace and debug macros require `BCLog::LogFlags` arguments and can't take source arguments makes it easier to mix up categories, intentionally and unintentionally. The alternative where source objects can be used for error/warning/info prints, not just debug/trace prints, and can tag everything with the same category should make it easier to be consistent if you want to be consistent (and not get in the way if you don't want to).\n\n[quoted text omitted]\nI don't see the massive overkill. This is a reasonable PR that adds documentation, tests, and doesn't change very much code. We don't want to require every individual wallet log print to include `\"[%s] ...\", walletname, ...` boilerplate for obvious reasons, I think. The problems with the `WalletLogPrintf` function are:\n\n1. It is only capable of logging at info level, does not provide a way to log at higher or lower levels.\n2. It evaluates its arguments unconditionally, so if it were extended to log at lower levels, it would either be inefficient or need to duplicate preprocessor code from logging.h to be as efficient.\n3. It is inconsistent with the rest of the codebase. It is nice if the same logging macros can be used everywhere, and the same features can be used everywhere. It also ensures logging is consistent within the wallet and only one logging API is used there."
  },
  {
   "t": "2024-01-29T03:45:15Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-1910905907\n\n[quoted text omitted]\nIt turns out making the category argument completely optional is not too hard to implement: 69e69b2a82c95f8040be093a29e5f84c37641f3a. So you could write:\n\n ```c++\nLogWarning(\"uncategorizable warning\")\n```\n\ninstead of\n\n ```\nLogWarning({}, \"uncategorizable warning\")\n```\n\nif that is the blocker here."
  },
  {
   "t": "2024-01-29T05:32:13Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI think the problem you are actually attempting to solve is [\"I, ryanofsky, find this weird and I don't like it\"](https://github.com/bitcoin/bitcoin/pull/28318#discussion_r1450411706), and I don't think code changes are the way of solving that, any more than code changes are the right way to solve the problem \"Bitcoin is weird and I don't like it\". I think you're wrong, but you seem unwilling to consider changing your opinion, so I'm pretty doubtful this is going to be productive. However, in case I'm wrong:\n\n[quoted text omitted]\nThe only cases where wallet names are automatically attached to log messages are in info level calls, which can be trivially dealt with by changing the existing wrapper to call `LogInfo`, and with an optional scripted diff renaming the wrapper as well.\n\n[quoted text omitted]\nThis, also, is not true: the assumption of these macros is that there is a global `BCLog::Logger` instance, which is already provided by `LogInstance()`. If we want to allow apps to configure libbitcoinkernel's logging in future, we could allow them to setup that global instance, or provide their own callbacks for it to use, in much the same way libevent allows you to setup callbacks. That's not something that needs changing.\n\n[quoted text omitted]\nThat's not filtering, that's 'grepping'. If you don't want to filter, but just want to highlight, then, as I've said repeatedly, logsourcelocations is what you want; the only benefit categories have compared to that is that categories can be (and by default are) filtered/discarded. logsourcelocations gives you much more exact information, is precisely separated by source file as you want, works with every level of log message, and requires no code changes or ongoing development effort to support.\n\n[quoted text omitted]\nIn that case you will not be able to use your log viewer to highlight that message when you're looking for it, which defeats your claimed goal. (Except, of course, you can select it for highlight, by looking for `[warning]` markers)\n\n[quoted text omitted]\nCan you please try using the logsourcelocations option before replying again? I really don't see how it doesn't already do everything you want, but you've ignored it every time I've mentioned it.\n\n[quoted text omitted]\nThe reader of the source code, is who I'm referring to here.\n\n[quoted text omitted]\nI don't think `m_log.Debug()` would be better than `LogDebug` -- in my opinion having a global log instance is the right thing here, and both having multiple references to a global log instance or having multiple log instances that all then coordinate writing to a single log would be worse.\n\nAs I've already said, I think `m_log.SetCategory(NET); m_log.Debug(\"connected to foo\")` is much worse than `LogDebug(NET, \"connected to foo\")`. Having to keep more context/state in your head when you're looking at code makes things harder, and it tends to make tool use go from \"usually works\" to \"never works\" (eg, `grep -RIl 'Log.*NET'`).\n\n[quoted text omitted]\nvalidation.cpp is where we have the code for \"is this valid for the mempool\", because we thought the word \"valid\" was more important than the word \"mempool\" in that sentence. `BCLog::VALIDATION` on the other hand is limited to blocks and headers, allowing it to be much less noisy than anything that triggers for every transaction, like `BCLog::MEMPOOL`. None of that is any indication of whether the code is well or badly organised.\n\n[quoted text omitted]\nI think by \"source arguments\" you mean \"a context argument\", and there's no reason they couldn't -- you can write `LogDebug(m_log_category, \"stuff\");` right now just as easily as you could `LogDebug(m_log, \"stuff\");` after this PR. That would still be a bad idea, though, as having the name of the log category obvious in the code is helpful.\n\n[quoted text omitted]\nIf there's a way of getting 99% of the benefits with a +1-1 change, then a +300-200 change is overkill in general.\n\n[quoted text omitted]\nWhy do you think that is a problem? None of the other existing cases need to add walletname boilerplate. What wallet-specific event (if it's not wallet specific, it doesn't need to be tagged with a wallet name) shouldn't be unconditionally logged (if an event is affecting the thing that holds all your funds, isn't that one of the most important things to log)?\n\n[quoted text omitted]\nThat it only logs at info level means it is unconditionally logged, so all the arguments are naturally unconditionally evaluated.\n\n[quoted text omitted]\nIt's inconsistent with your idea of how the codebase should be, but it's completely consistent with how the codebase actually is. Which is fine: changing the codebase to match better ideas is how you improve it. But things aren't going to improve if we can't recognise how things actually are in the first place."
  },
  {
   "t": "2024-02-16T09:00:33Z",
   "kind": "review",
   "who": "vasild",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "99feed7350b5fc3ae3157dd395ae6260c5bfc092",
   "text": "[quoted text omitted]\n\nThis seems like a step in the right direction. Currently we log messages unconditionally that don't have a category. But this is mixing two separate things - facility and severity. I have always found this confusing.\n\nThey got it right decades ago with [syslog(3)](https://www.man7.org/linux/man-pages/man3/syslog.3.html). Every log message has a facility and a severity. Because we don't want users to configure their systems in such a way as to dangerously omit important messages, then we don't provide a way to omit messages with higher severity than e.g. \"info\" or \"notice\". This is unrelated to the facility.\n\nIf some parts of this PR cause controversy, could it be reduced to the non-controversial things?"
  },
  {
   "t": "2024-02-27T22:53:59Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "0cd1616d47e61e125eb3e573573c0c56fba6b775"
  },
  {
   "t": "2024-02-27T23:05:42Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "Updated 99feed7350b5fc3ae3157dd395ae6260c5bfc092 -> 0cd1616d47e61e125eb3e573573c0c56fba6b775 ([`pr/bclog.12`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.12) -> [`pr/bclog.13`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.13), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.12..pr/bclog.13)) making the log macros backwards compatible to avoid any controversial changes.\nRebased 0cd1616d47e61e125eb3e573573c0c56fba6b775 -> 93d37f7d655409e6830475a10f4c9f16e35c76cd ([`pr/bclog.13`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.13) -> [`pr/bclog.14`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.14), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.13-rebase..pr/bclog.14)) due to silent conflicts with #26836.\nUpdated 93d37f7d655409e6830475a10f4c9f16e35c76cd -> a91fbbd61551702f26f734f3cdd1c080f9d51628 ([`pr/bclog.14`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.14) -> [`pr/bclog.15`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.15), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.14..pr/bclog.15)) to fix tidy failure https://cirrus-ci.com/task/6362757050662912, and try to work around MSVC compiler bug  https://github.com/bitcoin/bitcoin/actions/runs/8072891468/job/22055528830?pr=29256, and clean up some documentation.\n\n[quoted text omitted]\nI made a try at this in the latest push. I think most of the criticism of this PR from AJ is saying that the changes here are unnecessary, not really that they are harmful, so I made the logging macros completely backwards compatible using the approach I mentioned https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-1913911460, and only kept the changes I think are essential. I think this should help."
  },
  {
   "t": "2024-02-27T23:45:00Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "93d37f7d655409e6830475a10f4c9f16e35c76cd"
  },
  {
   "t": "2024-02-28T01:49:38Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "a91fbbd61551702f26f734f3cdd1c080f9d51628"
  },
  {
   "t": "2024-03-28T16:55:50Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "ce0004e42d37786f98cdf9d55b976b935dcf1ba1"
  },
  {
   "t": "2024-04-30T12:05:25Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI said \"As I've already said, I think `m_log.SetCategory(NET); m_log.Debug(\"connected to foo\")` is much worse than `LogDebug(NET, \"connected to foo\")`.\" Does that really not come across as me saying they're harmful? I really don't think I'm being **that** unclear. Anyway, I'll bow out, I'm already sorry for touching this."
  },
  {
   "t": "2024-04-30T13:06:39Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI think it's possible you might be referring to some changes in an earlier version of this PR. The PR allows the syntax you like and support it as a first-class usage! It does change wallet code, however to look like `LogDebug(m_log, \"debug message\")` to include wallet filenames in log messages. So if that is the harm which this PR causes, I want to acknowledge it, and I will update the PR description.\n\n@ajtowns we've definitely had difficulty communicating here and in some other issues, and I'm sorry for the dismissive comments I initially left on #28318, which on the whole I think is actually a good PR. I especially regret it you are \"sorry for touching this\", because #28318 is a real improvement, and your comments on this PR have made it better too, and motivated all the work and simplifications I've made to it since it was opened."
  },
  {
   "t": "2024-04-30T15:05:38Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\n[quoted text omitted]\nThat was the clearest example of saying that something was harmful, as evidence that I don't think you summarised my criticism accurately. English is my first language, so it's not like I can switch to another one to try to get my point across better... My main criticism of what remains is:\n\n[quoted text omitted]\nI'll rephrase how I see things again for whatever that's worth:\n\n * being able to match a log entry with where it came from in the source is super valuable\n * `-logsourcelocations` does that automatically for us, which is far less effort than manually specifying a category, and by giving a specific filename and line number, does a far better job of it as well\n * the only reason to keep the manual categories around at all is for selectively enabling/disabling noisy logs\n * the only noisy logs we have are those in the debug and trace levels (anything else would be a bug)\n * having those be manually specified rather than automatic is a win, as it allows us to rearrange our source code without accidentally breaking the configs of users who've enabled some noisy logs\n * adding those categories for non-noisy log messages is just busy work: it doesn't make it easier to find the source location of the debug message than `-logsourcelocations` does, and it doesn't help reduce log noise because those log messages aren't noisy in the first place\n\nThe macros in #28318 pretty much fall out from that. I suppose an alternative would be to have `Log(INFO, \"foo\")` and `LogNoisy(DEBUG, NET, \"bar\")` or so.\n\nThere are probably things `logsourcelocations` is bad at; if so, why not improve it so the benefits hit everywhere automatically?\n\n[quoted text omitted]\nI think specifying a category sometimes and not others depending on who happened to author that section of the code is a terrible idea. But I mean, it's not any more terrible than having \"LogPrint\" and \"LogPrintf\" having significantly different behaviour, so it's not like it's a disaster. Anyway, it's certainly not worth [15+ months of time/energy](https://github.com/bitcoin/bitcoin/pull/25203#issuecomment-1401126785)."
  },
  {
   "t": "2024-04-30T16:33:33Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "Thanks, I added a link directly to this comment in the summary so those who are interested can follow the chain of reasoning.\n\nTo reiterate my own point of view, `-logsourcelocation` does not solve the same problem this PR solves because it does not (1) let libitcoinkernel applications call validation functions and control which `Logger` object they write to, and (2) allow code like wallet code and index code to easily include additional metadata in log messages (wallet names and index names) while using convenient LogDebug(), LogTrace(), LogInfo(), LogWarning(), and LogError() macros."
  },
  {
   "t": "2024-05-02T10:06:51Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nThat ignores bullets (1), (2) and (5) from your OP (as it stands today).\n\nIt also ignores comments like [vasild's](https://github.com/bitcoin/bitcoin/pull/29256#pullrequestreview-1884614153), [jamesob's](https://github.com/bitcoin/bitcoin/pull/28318#discussion_r1445429093), [luke-jr's](https://github.com/bitcoin/bitcoin/pull/24464#pullrequestreview-902452600), [jonatack's](https://github.com/bitcoin/bitcoin/pull/28318#issuecomment-1879829758), [laanwj's](https://github.com/bitcoin/bitcoin/pull/28318#issuecomment-2085021744) or [your own](https://github.com/bitcoin/bitcoin/pull/28318#discussion_r1450411706). There's a valid disagreement there, isn't there? Can't we discuss it like engineers and work out what actual tradeoffs are lurking behind the intuition/gut feels? I've tried to spell out my reasoning both [before](https://github.com/bitcoin/bitcoin/pull/28318#issuecomment-1702318968) and after the PR got merged as well as having brought it up at the [irc meeting](https://www.erisian.com.au/bitcoin-core-dev/log-2023-08-31.html#l-384) to try to trigger discussion, but the response has just to reiterate the disagreement without any analysis or engagement with the reasoning that I've offered for doing it this way? Why? That makes no sense to me. I'm willing to be convinced I've made a mistake; but someone has to show me where I made the mistake, or at least do a show of hands that the majority prefers something else.\n\nI mean, am I incorrect in reading the previous two comments as \"here are the reasons I think this solution make sense: A, B, C, D, E, F\" and \"okay, that's nice, I'm going to completely ignore them, besides, X and Y are still important\"? Other than \"uh, okay, I guess I know when I'm not wanted\", how else am I meant to take it? What's the chance a response addressing X and Y will just also get equally ignored?\n\n(FWIW, I'd strongly contend that just declaring things should be such-and-such a way without being willing either talk through the tradeoffs and maybe find some mutually preferable solution, or to happily say \"oh well, not what I'd consider perfect, but not so bad, let's press on!\" is a pretty major contributor to things not progressing very fast. I can understand that habit in bitcoin broadly -- you explain why BTC is great and people shrug or call it a ponzi, and the only thing you can do is wait to be proven right, so you start just skipping straight to the final step -- but I don't understand it in the context of code changes at all...)\n\nAnyway, on to X and Y:\n\n[quoted text omitted]\nDoing that meaningfully means changing all the logging in all the bitcoin-kernel related modules (eg validation, mempool, blockstorage, scheduler, ...) to explicitly specify a logger rather than using the global functions, which seems like a lot of pointless busy work? I can't imagine why we'd want to support having multiple bitcoin-kernel instances in a single executable logging to different loggers; if someone wants to do that, it seems easy enough to just launch two separate processes.\n\nThe alternative would be to just have applications manipulate the global logger directly, which is how things already work, perhaps turning it into an atomic unique_ptr or similar and making many of its function virtual to allow overriding?. I'm just not really sure what the problem here is that's worth fixing; we already buffer log messages until `StartLogging` is called, and libbitcoin-kernel continuing to have a global logger instance seems simple and efficient for both us and any potential users of the library.\n\n(If we did want to do that anyway for some reason, then waiting until `std::source_location` is available would let us use `log.Debug(...)` syntax via template functions rather than having to use a macro and writing `LogDebug(log, ...)`. So rushing this change now seems bad even if the goal makes sense in some way I don't see)\n\n(The phrasing in the OP is currently \"The new macros cannot be used in libbitcoinkernel code because they do not allow specifying a logger instance.\" but that seems just false -- there's a bunch of LogInfo() calls in kernel/*.cpp already, and all the LogPrintf and LogPrint calls in validation are just aliases of LogInfo and LogDebug)\n\n[quoted text omitted]\nWe could do that simply by renaming `WalletLogPrintf` to `WalletLogInfo`, with behaviour no worse than today. There just isn't currently a need for non-info-level logs that report the wallet's name (which makes sense: in general ops on a wallet are important enough to be an \"INFO\" event).\n\nHaving `WalletLogPrintf` (or whatever) wrap around `LogInfo` sucks a bit, because it means `-logsourcelocations` reports the wrapper location rather than the caller. But a fix for that will be easy \"real-soon-now\" (#29077) when we can use `std::source_location`.\n\nChanging `wallet/sqlite`'s `TraceSqlCallback` to use `LogTrace` instead of `LogPrintf` is something we could do today that would improve things by making the output correctly indicate that it's trace-level rather than info-level, and be correctly annotated with the debug category that enables it to be logged. Again, that only needs a few characters changed, not a fundamental revamp.\n\nHere's a [patchset](https://github.com/ajtowns/bitcoin/commits/202405-walletlog/) that does those wallet changes:  it's a one line change for the trace logging, and two scripted diffs. Easy to do, easy to review, and \"allows the wallet code to easily include its metadata in log messages while using convenient LogInfo macros/functions\". If we want to improve things further (like using `std::source_location` when it's available or introducing some wallet-specific warnings or debug messages) we could still easily do that in the future."
  },
  {
   "t": "2024-06-25T19:26:27Z",
   "kind": "comment",
   "who": "sedited",
   "assoc": "MEMBER",
   "text": "Concept ACK\n\nRe https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2090083022\n\n[quoted text omitted]\nThere are use cases for having e.g. two chainstate managers running in parallel. Take a block file linearizer replacing the scripts in `contrib/linearize` as an example; you have one that reads blocks in their indexed order and another that writes blocks and their index back to another location on disk. Having something to distinguishing logs issued between the two sounds useful. In my eyes an important utility of the library is exactly that, you don't have to use multiple processes or go through the rpc to interact with Bitcoin Core's data structures and validation rules."
  },
  {
   "t": "2024-06-25T20:55:04Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2090083022\n\nAJ, thanks for the response. I want to let your comment stand, and not reply in detail right away to wait for input on this PR from other potential reviewers. I think your views on importance of hardcoding category constants in certain log statements, and on not allowing categories to be specified in other log statements are atypical, or at least will not be as strongly felt by other reviewers.\n\nBut your response does help me understand your concerns better, and your preferred solution of letting wallet code use its own logging functions, and having kernel code continue to use a global logger. It is also maybe a sign of hope to me that you seem to like `log.Debug(...)` syntax while disliking `LogDebug(log, ...)` syntax. I personally don't see much distinction between the two syntaxes, other than that latter allows arguments to be conditionally evaluated. But not evaluating arguments seems less important to me than being able to log in a consistent way across the codebase, so this offers hope for compromise.\n\nI also want to say again that I respect your opinions and appreciate you paying attention to this PR. Your earlier comments directly led to a number of improvements in the PR since it was opened."
  },
  {
   "t": "2024-06-26T08:05:24Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI don't think we should be reworking logging in our entire codebase in order to have a slight improvement in the hypothetical case where we replace some python scripts in contrib with C++ code? If this is worth doing, surely there is a *much* better example of why.\n\n[quoted text omitted]\nTo me, this suggests that a \"context\" parameter would be more appropriate than an \"instance\" one -- eg `LogInfo(walletctx, \"opened wallet, and sent all your funds to the genesis address, haha\\n\");` where the logging system would automatically invoke `msg = walletctx(msg)` when provided, in order to prefix the wallet name to the message or similar, but only after verifying logging is actually enabled. That's much more constrained behaviour than an instance parameter -- it just adds context information to a log message rather than allowing you to change the priority/category, or have completely different logging parameters (log file location, log to stdout, display source location, etc). The difference between `LogInfo(m_wallet_ctx, \"...\")` and the existing `WalletLogPrintf(\"...\")` seems pretty minor to me.\n\nThere are two different ways you might want to add context information: internally to a module, in the way that the wallet does, which would imply the `ctx` variable is established within the module and is private/local to that module. In that case, a similar approach to the one here would make sense -- have it be an optional parameter that the wallet module uses.\n\nThe other way is to have the context be provided externally to a module, so that you can create two instances of the module with different logging contexts that the caller controls. The latter seems like what you're imagining for the contrib/linearize example; but in that case, every module needs to pull in a context from its caller, much more like #30338. I don't see how the latter would mesh well with modules like wallet that also want to add internal context (would we have chained contexts? would the context object manage that?), and it seems like unnecessary complexity to me."
  },
  {
   "t": "2024-06-26T17:49:26Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "5f64eab013a58967af37a59c863c2ab6d45ba6e8"
  },
  {
   "t": "2024-06-26T18:19:38Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "With the latest push, this PR is now much smaller, and now mostly consists of documentation and test changes.\n\nI wanted to split this up in order to be able to base #30342 on a smaller changeset. The wallet changes that were previously part of this PR were moved to #30343.\n\nRebased ce0004e42d37786f98cdf9d55b976b935dcf1ba1 -> 5f64eab013a58967af37a59c863c2ab6d45ba6e8 ([`pr/bclog.16`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.16) -> [`pr/bclog.17`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.17), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.16-rebase..pr/bclog.17)) updating the PR as described."
  },
  {
   "t": "2024-06-26T21:09:30Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "doc/developer-notes.md",
   "commit": "5f64eab013a58967af37a59c863c2ab6d45ba6e8",
   "in_reply_to": null,
   "text": "`source` feels a bit abstract and special case, it would be good to keep `LogDebug(BCLog::CATEGORY, ...` examples as the most prominent as they are the common case."
  },
  {
   "t": "2024-06-26T21:13:23Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "Could do with a comment such as `// Implicitly constructible from a LogFlags value in order to be created by LogDebug(BCLog::NET, ...) etc.` if the current approach is kept."
  },
  {
   "t": "2024-06-26T21:13:36Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "```suggestion\n        const LogFlags category;\n```"
  },
  {
   "t": "2024-06-26T21:21:10Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "Could be made `constexpr` here and in other places:\n```suggestion\n    constexpr auto EXPECTED = std::to_array({\n```"
  },
  {
   "t": "2024-06-26T21:48:03Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "Feels like a half-baked workaround for having removed the global `LogPrintf_`."
  },
  {
   "t": "2024-06-26T22:02:30Z",
   "kind": "review",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "state": "CHANGES_REQUESTED",
   "commit": "5f64eab013a58967af37a59c863c2ab6d45ba6e8",
   "text": "NACK 5f64eab013a58967af37a59c863c2ab6d45ba6e8\n\nAt first glance it seems good to be able to specify an optional category to `LogInfo`, but it risks encouraging inflating `LogInfo` usage over `LogDebug`. This could open up future arguments like \"you can just filter out the whole category if you don't like my added `LogInfo`\". How about disallowing *category* for `LogInfo` like we currently do, but optionally accept something like *source* for the occasional exception like wallet code in #30343?\n\nIt's better to keep requiring either a category (or a source) for `LogDebug` & `LogTrace` as they are many and it makes them easier to filter."
  },
  {
   "t": "2024-06-27T03:11:11Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "doc/developer-notes.md",
   "commit": "5f64eab013a58967af37a59c863c2ab6d45ba6e8",
   "in_reply_to": 1655528095,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1655528095\n\n[quoted text omitted]\nGreat point, reverted this. There's no need to change this document anymore since the current version of this PR is backwards compatible (unlike the original version) so the original recommendations are still good. There's more complete reference documentation in the logging header."
  },
  {
   "t": "2024-06-27T03:11:19Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1655531815,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1655531815\n\nThanks again, but for now I did not take this suggestion. I think making individual struct members const can unnecessarily restrict the ways the struct can be initialized. I think the safety benefits of making the `category` member const are better enforced and more explicit when the entire struct is const, which should be best practice and already the case everywhere."
  },
  {
   "t": "2024-06-27T03:11:24Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1655531667,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1655531667\n\n[quoted text omitted]\nThank you! Added."
  },
  {
   "t": "2024-06-27T03:11:35Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1655537932,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1655537932\n\n[quoted text omitted]\nThanks! I don't think there's an obvious way to make these constexpr, but they should be const, so changed the declarations here, below, and in the next PR."
  },
  {
   "t": "2024-06-27T03:11:56Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1655562082,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1655562082\n\n[quoted text omitted]\nYes, good catch. I wanted to leave the test case below unchanged in the main commit to check (and let it be obvious) that the new logging features do not change any current behavior. But it's not good to leave behind a reference to an old function with a confusing name, so I added a new commit afterwards to modernize the test."
  },
  {
   "t": "2024-06-27T03:12:31Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "38d3298ea7e547797871140a02df3e7d60d34d36"
  },
  {
   "t": "2024-06-27T03:42:59Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "38d3298ea7e547797871140a02df3e7d60d34d36",
   "text": "Updated 5f64eab013a58967af37a59c863c2ab6d45ba6e8 -> 38d3298ea7e547797871140a02df3e7d60d34d36 ([`pr/bclog.17`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.17) -> [`pr/bclog.18`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.18), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.17..pr/bclog.18)) with suggested changes.\n\n---\n\nre: https://github.com/bitcoin/bitcoin/pull/29256#pullrequestreview-2142978382\n\nThank you for the close review!\n\nOn disallowing category arguments in `LogInfo`, that is an interesting line of reasoning that would not have occurred to me. Your suggestion to only accept source arguments not category arguments for `LogInfo` would probably be ok and is something I can implement.\n\nIf I understand correctly, you are worried that if it is possible to specify categories in `LogInfo`, then developers will be tempted to add spammy `LogInfo` prints that will drown out useful information, when they should be using `LogDebug` instead, because developers will assume that users can filter out categories they are not interested in. I think this is something worth thinking about, but I'm not sure if you know that logging options (before and after this PR) actually do not support filtering out Info/Warning/Error messages at all, by category or otherwise. These are considered unconditional logging levels, so users would need to write scripts or use external software to filter these. I'm not sure if that fact might change your opinion, but it should be concrete rationale that would push back against developers adding spammy `LogInfo` prints.\n\n~~It's also interesting that your reason for not wanting to allow category arguments in `LogInfo` is sort of the opposite of AJ's reason for not wanting to allow categories in `LogInfo` (though the reasons are technically compatible). AJ believes it is unsafe to allow specify category arguments in `LogInfo` and `LogWarning` and `LogError` statements because it creates the risk that users will write external scripts or filters that drop entire categories and leave themselves unaware of important log information.~~ (EDIT: Rereading AJ's comments, I'm not sure this paragraph actually represents what he thinks, so striking it out.)\n\nI do think there are plausible reasons to want to disallow attaching categories to certain log statements. If the only way I can make progress on this PR is to refuse to allow categories to be specified, I can make changes implementing that. But doing this would not be my starting point because I think generally category information is useful, and as long as we don't add unsafe options to our own software to filter out entire categories, I think we should try to provide users with category information and let them decide how to use it."
  },
  {
   "t": "2024-06-27T13:29:40Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1655537932,
   "text": "I suggested `constexpr auto EXPECTED = std::to_array({` above but maybe it doesn't work for you?\n[Should support `constexpr` that way under C++20 as far as I can tell](https://en.cppreference.com/w/cpp/container/array/to_array). Are you using some fancy interface to GitHub that doesn't yet show suggestion-embeds?"
  },
  {
   "t": "2024-06-27T13:51:04Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1655537932,
   "text": "Could go even more old-school and do:\n```C++\n    constexpr const char* EXPECTED[]{\n        ...\n    BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), std::cbegin(EXPECTED), std::cend(EXPECTED));\n```"
  },
  {
   "t": "2024-06-27T14:47:13Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nThanks for that, it was bumming me out thinking about how to try and clarify it.\n\nI really prefer your approach in #30348 and #30347 where you identify a specific objective problem and separately propose a targeted fix for exactly that problem.\n\n[quoted text omitted]\nNote that filtering out Info messages was previously a feature the logging system (and in particular, Info messages with a category would be filtered out by *default*). That feature was removed in https://github.com/bitcoin/bitcoin/pull/28318/commits/ab34dc6012351e7b8aab871dd9d2b38ade1cd9bc .\n\nI'll have another go at explaining my point of view:\n\n[quoted text omitted]\nI don't think category information is useful *except* for enabling log message filtering. It's not useful otherwise, because `-logsourcelocations` is strictly superior in multiple ways (it's automatic, it doesn't need to be updated if we refactor things, and it gives more detailed information). For messages we don't want users to filter, we shouldn't provide a category, as that would provide no benefit at all."
  },
  {
   "t": "2024-06-27T20:40:53Z",
   "kind": "comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\n[quoted text omitted]\nCool! Hoping that's something @ajtowns could agree to allowing something like an optional `source` being passed to `LogInfo` etc to make the wallet code and other exceptions nicer without suddenly also accepting category everywhere.\n\nThe fact that there's something behind the immediate macro level preventing `LogInfo`/`LogError`/`LogWarning` from being filtered is a weaker argument to use in pushing against added logging outside of `LogDebug`/`LogTrace` statements, than them not even accepting a category to potentially filter on. Gotta respect an opinionated API. :)"
  },
  {
   "t": "2024-06-28T14:08:47Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1655537932,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1657145216\n\n[quoted text omitted]\nNo sorry, that works perfectly. I was just careless and only noticed `constexpr` without seeing the rest of it. Added your suggestion to this PR and followup PR #30343."
  },
  {
   "t": "2024-06-28T14:11:37Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "681b21f7ca07f0e1411354baa01649e7b1f30e8c"
  },
  {
   "t": "2024-06-28T14:23:54Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "681b21f7ca07f0e1411354baa01649e7b1f30e8c",
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2195631997\n\n[quoted text omitted]\nUnderstood. If the current restrictions which prevent categories from being filtered out are not enough, a developer restriction to prevent categories constants from being specified could be a stronger tool to do the things you and maybe AJ are trying to accomplish. I implemented that restriction in 44afae705a12252149adbe7ac6d3646052b8bf3b and would be ok with adding it this PR if it solves problems for you and AJ, even if I don't personally see a need for the API to be so restrictive.\n\nI will say one nice thing about the approach in 44afae705a12252149adbe7ac6d3646052b8bf3b is that someone tries to write a `LogInfo` statement that includes a category they will get a clear `static_assert` error explaining that they need to drop the category argument or reduce the log level, instead of just seeing preprocessor and strprintf errors which are harder to decipher.\n\n---\n\nUpdated 38d3298ea7e547797871140a02df3e7d60d34d36 -> 681b21f7ca07f0e1411354baa01649e7b1f30e8c ([`pr/bclog.18`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.18) -> [`pr/bclog.19`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.19), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.18..pr/bclog.19)) with suggested `constexpr` change (thank you for the suggestion!)"
  },
  {
   "t": "2024-06-28T16:58:00Z",
   "kind": "comment",
   "who": "jonatack",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nI think I'd be Concept ACK on these, though I've somewhat tuned out since the unfortunate deviation the severity-based logging has taken since https://github.com/bitcoin/bitcoin/pull/28318 for the reasons I've stated there and in other PRs.\n\nWe've just over-wrought everything when it could be simple and open. A number of other developers think the same but don't speak up much because it seems pointless to do so.\n\nAside, and unsure it is an issue of discussion: Unless proven otherwise in practice later on, I do not think we need to be overly paranoid and helicopter parenting yet with respect to node operators footgunning themselves en masse with custom log level settings. Only developers and more technically aware users are likely to use them."
  },
  {
   "t": "2024-06-28T17:22:08Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2197318437\n\n[quoted text omitted]\nCurious, when you say \"over-complicated\", are you referring to the implementation of the logging code, or to the usage of the logging API? Or to effects of logging settings?\n\nI don't think the logging API is too complicated. I think #28318 made it more self documenting and simpler.\n\nOn the other hand, I would say that the macro definitions used to implement the logging API are pretty complicated. This PR does try to improve them by making the implementation sequential and documenting every part of it. But I think it is ok for the implementation to be complicated if the interface is simple, and if there are legitimate reasons to make it complicated, like not evaluating arguments when debug logging is turned off.\n\nI'm not sure about interpretation of logging settings, but I haven't been involved in those PRs."
  },
  {
   "t": "2024-06-28T18:49:08Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nThat comment had already stood for eight weeks, and included an example patchset of changes that could improve things with regards to your complaints about wallet logging, while discussion continued on this. Instead we've had no progress and no discussion, which seems to me to be pretty counter productive. I've opened up what I assume is the least controversial of those as #30355 if you have any interest."
  },
  {
   "t": "2024-06-28T18:52:33Z",
   "kind": "comment",
   "who": "jonatack",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nAll of these, I think.  The idea was:\n\n- one `Log(level, cat, msg)` macro with a consistent API replace the current macros\n- the -debug and -loglevel config options and logging RPC soft-aligned into a single user-facing logging API\n- the printed logs to be the same format for each `Log` call, apart from custom options\n- developer documentation in the `Log` macro and the level/category enums, where grepping would lead you directly\n\nInstead (from memory, I'm maybe not up to date), we now have:\n\n- a larger slew of macros\n- an inconsistent API and printed log that vary depending on which of the new level macros is called\n- various restrictions on calls and usage\n- documentation in various places\n- all these ducks to keep in a row\n\nNone of that seems necessary (unless there is a technical obstacle?)\n\nI suggest doing the simplest consistent implementation and API we can come up. Easier for both users and developers. Those seem more valuable than e.g. saving characters that developers might copy/paste when adding new logging."
  },
  {
   "t": "2024-06-28T19:54:43Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2197461775\n\nThanks I appreciate the clarification, and I agree with most of those points, except I genuinely do think having one convenience macro for each log level is nice. And LogPrintLevel exists so it is even possible to ignore the convenience macros if you want to do that.\n\nJust as an observation, I get the sense that I am not the only one who likes the convenience macros, and that when other people read your comments complaining about the existence of these macros, it might make them discount the value of other things you are saying. So I don't know if it would help, but it might be better if you could come to a grudging acceptance of the macros, and think about not bringing them up if they aren't essential to points you are making. It might help other points be better received and understood."
  },
  {
   "t": "2024-06-28T22:25:42Z",
   "kind": "comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "text": "(For what it is worth, I'm used to thin convenience macros for logging from other codebases. In the ecosystem we also have https://github.com/ElementsProject/lightning/blob/master/lightningd/log.h which follows the same pattern).\n\n[quoted text omitted]\nThe API feels good to me, nice touch with the `static_assert`! Wish the implementation of the combined functionality were simpler, but don't have the throughput to attempt boiling it down right now.\n\nSide note: `LogPrintfCategory` surprised me in that it is logging with categories at Info-level. Seems to be only used by tests and benchmarks.. maybe uses of it could be removed as it was [deprecated in the last release](https://github.com/bitcoin/bitcoin/blob/27.x/src/logging.h#L244), or changed to use `LogDebug`?"
  },
  {
   "t": "2024-08-07T01:56:15Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "46f5e27e86f9bd2c88df86f0d652fedab1bd0f21"
  },
  {
   "t": "2024-12-09T19:11:46Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "48b3c951aa256c6be0cc50461de00f758d92dcb4"
  },
  {
   "t": "2024-12-09T20:29:57Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "5db1958e60aef9d3604448c21e1f397e561480ee"
  },
  {
   "t": "2024-12-10T14:00:01Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "Rebased 46f5e27e86f9bd2c88df86f0d652fedab1bd0f21 -> 48b3c951aa256c6be0cc50461de00f758d92dcb4 ([`pr/bclog.20`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.20) -> [`pr/bclog.21`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.21), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.20-rebase..pr/bclog.21)) due to conflicts with with #31174 and other PRs.\nUpdated 48b3c951aa256c6be0cc50461de00f758d92dcb4 -> 5db1958e60aef9d3604448c21e1f397e561480ee ([`pr/bclog.21`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.21) -> [`pr/bclog.22`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.22), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.21..pr/bclog.22)) to fix MSVC error C3495 https://github.com/bitcoin/bitcoin/actions/runs/12242607762/job/34150305407?pr=29256\n\nIf reviewers agree with previous feedback that allowing category arguments to be passed to LogError/LogWarning/LogInfo macros is dangerous because it encourages developers to add log spam and encourages users to ignore important messages, I can add commit 0b5cbf9ee8ca39b91c6c635d27df94ec618be5cb here so specifying categories will remain forbidden. Would prefer not to do this because providing a consistent API and providing context with log messages seem like tangible benefits to me, while the current restrictions seem like an indirect and ineffective solution to log spam, but I could live with the restrictions if having them unblocks #30342 and #30343."
  },
  {
   "t": "2024-12-13T23:21:01Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "This looks less weird, would it be equivalent in this case or defeat the purpose?\n```suggestion\n#define _FirstArg(args) _FirstArgImpl(args)\n```"
  },
  {
   "t": "2024-12-13T23:33:44Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "Maybe best to avoid introducing identifiers starting with underscore, especially if followed by uppercase?\n\nhttps://stackoverflow.com/a/228848"
  },
  {
   "t": "2024-12-13T23:37:12Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "nit: Could potentially avoid repeated `Source` construction:\n```suggestion\n        auto log_source = _LogSource(_FirstArg((__VA_ARGS__)));           \\\n        if (LogEnabled(log_source, (level))) {                            \\\n            const auto& func = __func__;                                  \\\n            _LogFormat([&](auto&& source, auto&& message) {               \\\n                source.logger.LogPrintStr(message, func, __FILE__,        \\\n                    __LINE__, source.category, (level));                  \\\n            }, log_source, __VA_ARGS__);                                  \\\n        }                                                                 \\\n```"
  },
  {
   "t": "2024-12-14T20:29:30Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "doc/developer-notes.md",
   "commit": "5f64eab013a58967af37a59c863c2ab6d45ba6e8",
   "in_reply_to": 1655528095,
   "text": "If we were to go ahead with something close to what this PR is, I think it would be good to mention in *developer-notes.md* that `LogInfo`/`Warning`/`Error` take an optional category or source. - Or at the very least hint at there being more flexibility which is documented together with the macro implementations."
  },
  {
   "t": "2024-12-14T22:11:28Z",
   "kind": "review",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "state": "CHANGES_REQUESTED",
   "commit": "5db1958e60aef9d3604448c21e1f397e561480ee",
   "text": "Code reviewed 5db1958e60aef9d3604448c21e1f397e561480ee + 0b5cbf9ee8ca39b91c6c635d27df94ec618be5cb\n\n#### PR style\n\nI think it would be clearer to introduce the *logging_source_args*-test by itself in an initial commit without any behavioral changes to the logging system, to then have following commits demonstrate how the output changes.\n\n#### Subjective title\n\nThe PR title (and commit messages) is/are misleading/heavily subjective:\n\"Improve new LogDebug/Trace/Info/Warning/Error Macros\"\nMore objective:\n\"Make LogInfo/Warning/Error accept category and stop requiring it for LogDebug/Trace\"\n\nBut that title doesn't manage to also squeeze in what I think is the **undisputedly useful** part here - the log-source concept (required by child PRs #30342 and #30343). I wish that would be introduced without the other API changes.\n\n#### Suggested change\n\n0b5cbf9ee8ca39b91c6c635d27df94ec618be5cb disallowing categories for high priority levels does not go far enough, it is even more important that categories still be required for Debug/Trace IMO, to prevent spamming across categories. Took a stab at implementing that in additional commit ~86c7b578cb4563a09783d95e95adc437c04447bc~ cebc9e2a22892abf70f16f08a0cbfb12a98291b5. (It also resets the category for high priority levels).\n\nWith my change the PR title could more or less be changed to \"Add log source and non-global logging support\".\n\nTo me it still feels like we should live with the consciously made API decisions from #28318 a bit longer without having to change them."
  },
  {
   "t": "2025-04-03T17:30:51Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "07295ff649e72e267b6f285dcf0f670e676019ef"
  },
  {
   "t": "2025-04-03T17:36:56Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "2ebcc54b886dd7e54688bf7e0a6238e354a35236"
  },
  {
   "t": "2025-04-03T17:39:45Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1884641997,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1884641997\n\n[quoted text omitted]\nYeah, that doesn't really work here because `args` contains multiple arguments already enclosed in parentheses, so adding extra parentheses prevents them from being separated."
  },
  {
   "t": "2025-04-03T17:40:42Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1884649628,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1884649628\n\n[quoted text omitted]\nThanks, I had no idea those were reserved. Switched to a `detail` namespace for the functions and trailing underscore for the macros."
  },
  {
   "t": "2025-04-03T17:41:11Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 1884651483,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r1884651483\n\n[quoted text omitted]\nThanks that is cleaner. Switched to this approach."
  },
  {
   "t": "2025-04-03T17:53:31Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "2ebcc54b886dd7e54688bf7e0a6238e354a35236",
   "text": "Rebased 5db1958e60aef9d3604448c21e1f397e561480ee -> 07295ff649e72e267b6f285dcf0f670e676019ef ([`pr/bclog.22`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.22) -> [`pr/bclog.23`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.23), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.22-rebase..pr/bclog.23)) with suggested changes adding back #28318 restrictions.\nUpdated 07295ff649e72e267b6f285dcf0f670e676019ef -> 2ebcc54b886dd7e54688bf7e0a6238e354a35236 ([`pr/bclog.23`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.23) -> [`pr/bclog.24`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.24), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.23..pr/bclog.24)) to fix CI \"no return statement in function\" errors from GCC\nUpdated 2ebcc54b886dd7e54688bf7e0a6238e354a35236 -> 176ad35e69b2f0ba94b4db47c66a583b1bf87744 ([`pr/bclog.24`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.24) -> [`pr/bclog.25`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.25), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.24..pr/bclog.25)) to fix CI errors from older clang versions and add new unit test in separate commit as suggested.\n\nUpdated 176ad35e69b2f0ba94b4db47c66a583b1bf87744 -> 093d58e055b10a1031c97b24de5e029221f176d7 ([`pr/bclog.25`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.25) -> [`pr/bclog.26`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.26), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.25..pr/bclog.26)) with minor tweaks to declarations and commit messages.\n\n---\n\nre: https://github.com/bitcoin/bitcoin/pull/29256#pullrequestreview-2503381924\n\nThanks @hodlinator. I really appreciate you figuring out how to implement the restrictions from #28318. Even though I don't like them, I don't think they add a very big cost, so I've incorporated them to help narrow the scope of this PR and unblock it.\n\nI'm still unable to wrap my head around the appeal of a logging framework with an inconsistent API that yells at you if you supply too much context for important messages, and yells at you if you give too little context for less important messages. I can follow the logic which leads to the conclusion that the restrictions are good, but it's not compelling to me, and seems like it just makes the logging framework jankier for developers and users and different from logging frameworks that are well regarded anywhere else. But dropping the restrictions is not the main goal of this PR, so I'm ok with keeping them.\n\n[quoted text omitted]\nMissed this suggestion but will implement in the next push. Need to fix some issues happening in CI anyway. (UPDATE: Implemented this suggestion now).--\n\n---\n\nRebased 093d58e055b10a1031c97b24de5e029221f176d7 -> d032022ff59204b85b2057ab9a88f4d2842dbde9 ([`pr/bclog.26`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.26) -> [`pr/bclog.27`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.27), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.26-rebase..pr/bclog.27))\n\nUpdated d032022ff59204b85b2057ab9a88f4d2842dbde9 -> a66d1e27f11b2c061879dbee02b889fad5cc2669 ([`pr/bclog.27`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.27) -> [`pr/bclog.28`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.28), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.27..pr/bclog.28)) to fix silent conflict with #33517 (https://github.com/bitcoin/bitcoin/actions/runs/18514130088?pr=29256)\n\nUpdated a66d1e27f11b2c061879dbee02b889fad5cc2669 -> 8428899fb97ea5f71e879f958b4f10846f28e73a ([`pr/bclog.28`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.28) -> [`pr/bclog.29`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.29), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.28..pr/bclog.29)) to fix source_location print, not using location inside lambda\n\nRebased 8428899fb97ea5f71e879f958b4f10846f28e73a -> 3e4c8b9320783f2985937e9f326df3bc532e7905 ([`pr/bclog.29`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.29) -> [`pr/bclog.30`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.30), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.29-rebase..pr/bclog.30))\n\nRebased 3e4c8b9320783f2985937e9f326df3bc532e7905 -> cecf87c92a459b462d98d43c3e5c0b87286c1e4e ([`pr/bclog.30`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.30) -> [`pr/bclog.31`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.31), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.30-rebase..pr/bclog.31))\n\nRebased cecf87c92a459b462d98d43c3e5c0b87286c1e4e -> c566ebc71083e93b6898e37549fc42eb524dcf10 ([`pr/bclog.31`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.31) -> [`pr/bclog.32`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.32), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.31-rebase..pr/bclog.32))\n\nRebased c566ebc71083e93b6898e37549fc42eb524dcf10 -> 326c62d1d327549526f2975342bd64c82231a16a ([`pr/bclog.32`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.32) -> [`pr/bclog.33`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.33), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.32-rebase..pr/bclog.33)) due to conflicts\n\nUpdated 326c62d1d327549526f2975342bd64c82231a16a -> 1ceea94931b72bc1f949fbaab1f26a0ef6eb4a21 ([`pr/bclog.33`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.33) -> [`pr/bclog.34`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.34), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.33..pr/bclog.34)) to fix clang-tidy and iwyu errors https://github.com/bitcoin/bitcoin/actions/runs/21103601009\n\nRebased 1ceea94931b72bc1f949fbaab1f26a0ef6eb4a21 -> e19ce37359227849ec55d45dfd33303ccaceeccf ([`pr/bclog.34`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.34) -> [`pr/bclog.35`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.35), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.34-rebase..pr/bclog.35)) due to conflict with #34465, reimplementing macros to use new util::log::Log/ShouldLog interface and restore info/warning/error argument evaluation behavior, cherry-picking stickies verify log argument evaluation semantics test from https://github.com/bitcoin/bitcoin/pull/34465#pullrequestreview-3763887226\n\nUpdated e19ce37359227849ec55d45dfd33303ccaceeccf -> 487f7e77cf8569b15a86631e03439dd648703822 ([`pr/bclog.35`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.35) -> [`pr/bclog.36`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.36), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.35..pr/bclog.36)) to fix IWYU errors https://github.com/bitcoin/bitcoin/actions/runs/21826859168/job/62975817002?pr=29256, also updatimg commit messages\n\nRebased 487f7e77cf8569b15a86631e03439dd648703822 -> 6d91998175b40939001e01ae2cd78571bff392b7 ([`pr/bclog.36`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.36) -> [`pr/bclog.37`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.37), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.36-rebase..pr/bclog.37)) with some tweaks and update for adyshimony review https://github.com/bitcoin/bitcoin/pull/30343#pullrequestreview-3871171023"
  },
  {
   "t": "2025-04-03T19:13:06Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "176ad35e69b2f0ba94b4db47c66a583b1bf87744"
  },
  {
   "t": "2025-04-04T03:35:23Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7"
  },
  {
   "t": "2025-04-12T12:22:02Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "1) This still goes against the intent of #28318 in my opinion, by adding categories to output of `LogError`/`LogWarning`/`LogInfo` when used with context.\n\n2) This also changes behavior insofar as adding `[.*info] `-prefixes for LogInfo(), which were intentionally avoided in #28318:\n\nhttps://github.com/bitcoin/bitcoin/blob/e60fc7d5d34f23cccbff6e4f5f3d716fa8dad50c/src/test/logging_tests.cpp#L139-L149\n\nSee other comment about suggested change to `LogPrint_()` to address both above points.\n\n---\n\n3) Especially `LogInfo()` without any prefix would feel less \"naked\" if you were to import the test with `CustomLogContext` from fea5da15eef4479729aa27868277a720fdfe36e8 (#30343) into this PR to demonstrate usage. Doing so would also give a greater sense of completeness here IMO."
  },
  {
   "t": "2025-04-12T12:22:31Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "nit: Superfluous newlines here and in the other new test case below:\n```suggestion\n    LogError(log, \"error %s\", \"arg\");\n```"
  },
  {
   "t": "2025-04-12T14:49:31Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": null,
   "text": "`LogPrint_()` - Highly suggest one remaining change to maintain output behavior for `LogError`/`LogWarning`/`LogInfo` when used with context:\n```suggestion\n                    take_category ? ctx.category : BCLog::LogFlags::ALL,       \\\n                    (level));                                                  \\\n```\nOne can still use the escape hatch of `LogPrintLevel()` or `LogPrintStr()` if one wants things like `[net:info] `-prefixes.\n\nLooking back, this is a reinvention of that part of my change in cebc9e2a22892abf70f16f08a0cbfb12a98291b5 from https://github.com/bitcoin/bitcoin/pull/29256#pullrequestreview-2503381924. Curious to at least hear your thoughts. Not a definite blocker as context-support is after all something new."
  },
  {
   "t": "2025-04-12T22:08:37Z",
   "kind": "review",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "text": "Code reviewed 093d58e055b10a1031c97b24de5e029221f176d7\n\nThank you for changing the end result of this PR to abide by the API decisions of #28318!\n\n(Still think it's a bit odd to open up the gates in eaac991552abe9bfbffc22d99a8baee659ae3173 to then return to closer to master behavior in 093d58e055b10a1031c97b24de5e029221f176d7. But no blocker).\n\nWhile the API has been \"reverted\", I still think there's a shift in behavior (output) - see inline comments.\n\n(Sorry I didn't get to this sooner, somehow only registered that you had rebased before looking back at this today)."
  },
  {
   "t": "2025-10-15T00:42:14Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "d032022ff59204b85b2057ab9a88f4d2842dbde9"
  },
  {
   "t": "2025-10-16T13:37:34Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "a66d1e27f11b2c061879dbee02b889fad5cc2669"
  },
  {
   "t": "2025-10-16T14:46:28Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "8428899fb97ea5f71e879f958b4f10846f28e73a"
  },
  {
   "t": "2025-11-10T23:35:04Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "3e4c8b9320783f2985937e9f326df3bc532e7905"
  },
  {
   "t": "2025-12-12T12:19:40Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "cecf87c92a459b462d98d43c3e5c0b87286c1e4e"
  },
  {
   "t": "2025-12-16T02:10:49Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "c566ebc71083e93b6898e37549fc42eb524dcf10"
  },
  {
   "t": "2026-01-18T01:00:50Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "326c62d1d327549526f2975342bd64c82231a16a"
  },
  {
   "t": "2026-01-18T14:37:32Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "1ceea94931b72bc1f949fbaab1f26a0ef6eb4a21"
  },
  {
   "t": "2026-02-09T13:25:02Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "e19ce37359227849ec55d45dfd33303ccaceeccf"
  },
  {
   "t": "2026-02-09T14:30:56Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "487f7e77cf8569b15a86631e03439dd648703822"
  },
  {
   "t": "2026-03-02T00:50:37Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7"
  },
  {
   "t": "2026-03-02T11:45:11Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\n```suggestion\n    //! allow users to filter by category at high priority levels, and (2) wanting\n```"
  },
  {
   "t": "2026-03-02T11:46:00Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nWhy does `ShouldLog` rely on `_source.category` even when `take_category` is false?\nLater, we swap it to `.category = take_category ? source.category : BCLog::LogFlags::ALL`, so it seems cleaner to check what we will actually be logging:\n```suggestion\n        auto category{take_category ? _source.category : BCLog::LogFlags::ALL}; \\\n        if (util::log::ShouldLog(_source.logger, category, (level))) {                            \\\n```\n\nNit: the trailing `\\` are unaligned now, and my OCD is flaring up."
  },
  {
   "t": "2026-03-03T15:35:22Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nCan we use `ReadDebugLogLines` instead like we do in `logging_LogPrintStr`?\n```suggestion\n    const auto log_lines{ReadDebugLogLines()};\n    constexpr auto expected{std::to_array({\n        \"[error] error\",\n        \"[warning] warning\",\n        \"info\",\n\n        \"[error] error arg\",\n        \"[warning] warning arg\",\n        \"info arg\",\n\n        \"[net] debug\",\n        \"[net:trace] trace\",\n\n        \"[net] debug arg\",\n        \"[net:trace] trace arg\",\n    })};\n    BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end());\n```"
  },
  {
   "t": "2026-03-03T15:37:55Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nnit: we might as well include `<array>` now that we're here"
  },
  {
   "t": "2026-03-03T15:39:45Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nnit: `()` isn't needed here:\n```suggestion\n    auto side_effect = [&counter] { return ++counter; };\n```"
  },
  {
   "t": "2026-03-03T15:40:30Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nThese conditions should also hold when they are enabled. Can we try a loop instead?"
  },
  {
   "t": "2026-03-03T15:45:39Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nNit: no biggie, but it might be simpler and more conceptually symmetric to untangle this from the previous ones by resetting the counter before the run and asserting `0` here.\n\n```C++\nBOOST_FIXTURE_TEST_CASE(logging_arg_evaluation, LogSetup)\n{\n    int counter{0};\n    auto side_effect = [&counter] { return ++counter; };\n\n    for (bool enable_logger : {true, false}) {\n        LogInstance().DisconnectTestLogger();\n        if (enable_logger) {\n            BOOST_REQUIRE(LogInstance().StartLogging());\n        } else {\n            LogInstance().DisableLogging();\n        }\n        BOOST_REQUIRE_EQUAL(enable_logger, LogInstance().Enabled());\n\n        // Info or higher should always evaluate the arguments.\n        counter = 0;\n        LogError(\"error (%s)\", side_effect());\n        LogWarning(\"warning (%s)\", side_effect());\n        LogInfo(\"info (%s)\", side_effect());\n        BOOST_CHECK_EQUAL(counter, 3);\n\n        // Debug/Trace should skip argument evaluation when category is disabled.\n        counter = 0;\n        LogDebug(BCLog::NET, \"debug (%s)\", side_effect());\n        LogTrace(BCLog::NET, \"trace (%s)\", side_effect());\n        BOOST_CHECK_EQUAL(counter, 0);\n    }\n}\n```\n(applied all suggestions to the example)"
  },
  {
   "t": "2026-03-03T15:45:58Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nfor simplicity we could just use `%s` everywhere"
  },
  {
   "t": "2026-03-03T15:49:37Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nsuper-nit: `its` arguments? shouldn't it be `the(ir) arguments`?"
  },
  {
   "t": "2026-03-03T16:09:43Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "ee3fb8cf39faec7144f5727030a27d05f89c8688",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nnit:\n```suggestion\n    BOOST_REQUIRE(logger.StartLogging());\n```"
  },
  {
   "t": "2026-03-03T16:24:43Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 2040646297,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2040646297\n\n[quoted text omitted]\nThanks! These are removed now"
  },
  {
   "t": "2026-03-03T16:25:22Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/logging.h",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 2040671181,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2040671181\n\n[quoted text omitted]\nThanks! Applied change [here](https://github.com/ryanofsky/bitcoin/blob/6d91998175b40939001e01ae2cd78571bff392b7/src/util/log.h#L135)"
  },
  {
   "t": "2026-03-03T16:29:16Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "093d58e055b10a1031c97b24de5e029221f176d7",
   "in_reply_to": 2040646228,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2040646228\n\n[quoted text omitted]\nThanks! Done\n\n[quoted text omitted]\nThis makes sense, and also simplifies #30343. It's done now in the \"Add support for custom log sources\" commit."
  },
  {
   "t": "2026-03-03T17:03:36Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/logging.cpp",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nI don't get why this is needed. If the parameter is available, we always cast it. It seems like an abstraction failure."
  },
  {
   "t": "2026-03-03T17:24:35Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nThis commit is suddenly quite complicated compared to the previous ones. Can we split it up by feature? I'm not sure I understand why we suddenly have an explosion of docs/getters/casts. It seems like there are at least three sub-features here."
  },
  {
   "t": "2026-03-03T17:28:17Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nMight be cleaner to have these as a local lambda and type that cleanly just executes a lambda, instead of having to know about the exact test implementation, e.g.\n```C++\nusing Fmt1 = util::ConstevalFormatString<1>;\nstruct CustomLogSource : util::log::Source {\n    using LogFormatter = std::function<std::string(Fmt1, const char*)>;\n    LogFormatter m_fmt;\n    explicit CustomLogSource(BCLog::LogFlags s, LogFormatter fmt) : Source{s}, m_fmt{std::move(fmt)} {}\n    std::string Format(Fmt1 fmt, const char* arg) const { return m_fmt(fmt, arg); }\n};\n\nint counter{0};\nauto log = CustomLogSource{BCLog::VALIDATION, [&counter](Fmt1 fmt, const char* arg) {\n    return tfm::format(\"Custom #%d %s\", ++counter, tfm::format(fmt, arg));\n}};\n```\n\nnit1: `public` is implicit\nnit2: `explicit` is not implicit :p"
  },
  {
   "t": "2026-03-03T17:31:43Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nWe already have a `log` in this scope:\n[quoted text omitted]\n\nBut we can probably use the helper here instead:\n```C++\n    const auto log_lines{ReadDebugLogLines()};\n```"
  },
  {
   "t": "2026-03-03T17:50:43Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nI don't like that compilation passes if I change anything here. It's just an incidental interface that will simply fail the test if I rename it to `Format2`.\n\nI know that adding a `HasMemberFormat` concept is ugly, but I really dislike these accidental interfaces."
  },
  {
   "t": "2026-03-03T18:38:31Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nNit: can you please add name hints? This `true`/`false` zoo is making it harder to understand what each one does."
  },
  {
   "t": "2026-03-03T18:43:27Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nVerified each separately, and they all throw if uncommented. \ud83d\udc4d"
  },
  {
   "t": "2026-03-03T18:59:00Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": null,
   "text": "[quoted text omitted]\n\nHmm, is the intent here to require inheritance from `util::log::Source`?\n```suggestion\ntemplate <typename T>\nrequires (std::is_base_of_v<Source, std::remove_cvref_t<T>>)\nconst T& GetSource(const T& source LIFETIMEBOUND) { return source; }\n```\n\nWhich would allow the deletion of `log_source` from `Source`.\nNote: renamed the template parameter to avoid the name collision."
  },
  {
   "t": "2026-03-03T19:08:18Z",
   "kind": "review",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "state": "CHANGES_REQUESTED",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "text": "I went over the commits. I don't yet have a conceptual opinion about it. I usually go bottom-up here.\n\nThere are still a few things that I would like to be split; a few of the commits are too big for me to fully comprehend. I left lots of comments and suggestions in that area.\n\nI would also like to understand whether @ajtowns and @hodlinator still disagree with the change."
  },
  {
   "t": "2026-03-04T04:34:56Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "Just to reiterate: Concept NACK. This PR isn't solving any problems other than its author's aesthetic objection to the current logging API, which date back to when #28318 was merged.\n\n[quoted text omitted]\nIf you don't understand what you're trying to change, you shouldn't be changing it. The logging API we have is designed to be as simple as possible given our performance requirements (cf #33517), and also be simple/convenient to use. How and why that is the case has already been explained repeatedly.\n\nIt is also extremely tedious to have spent four months working on #28318 (after spending a bunch more time reviewing earlier PRs that weren't making progress), specifically [request design feedback](https://www.erisian.com.au/bitcoin-core-dev/log-2023-08-31.html#l-385) early in that process, and then, immediately upon the PR being merged, have a maintainer file an array of issues and PRs (let's see: this one, #29256, was a week after merge; then all of #30342, #30343, #30347, #30361, #30364 were end of June, with 4 of those 6 still pending about 2 years later) trying to undermine that work, and then maintain them for years after, while also limiting your response to critical feedback to remarks like \"I want to let your comment stand, and not reply in detail\". Of course, as a practical matter, just opening new PRs and ignoring objections until people stop bothering to object is quite possibly an effective way of getting your preferred aesthetic adopted; it's not a good way of making good software though."
  },
  {
   "t": "2026-03-04T08:18:30Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "@ajtowns I'm sorry for disagreements we've had in the past, and regret rude and dismissive comments I've made, and definitely think we got off on the wrong foot. But since this PR has been opened, I've adjusted it to do literally every single thing you have asked for, including things that I do not agree with (removing category information from log output, not accepting a consistent set of macro arguments) to avoid endless disagreement and focus the PR on it's primary goals (allowing separate logging streams #30342, making the use of globals optional instead of required #33847, allowing subsystems to attach context information log messages #30343).\n\nI understand you may not care about these goals, which is fine, and I hope that your last nack and comment is a helpful vent for your understandable frustrations with me as a detail-oriented and nitpicky developer. But I also hope that any reviewers and maintainers who are interested in this PR can weigh the comments here appropriately and not give undue weigh to a nack which does not mention specific downsides of a change."
  },
  {
   "t": "2026-03-04T08:44:42Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": null,
   "text": "nit: In a previous push you used the name `Context` which is less ambiguous vs `SourceLocation` which has since been introduced above.\n\nThe first commit's message still mentions \"context objects\".\n\nPersonally I prefer `Context`, but `Source` is okay."
  },
  {
   "t": "2026-03-04T08:58:38Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "fe17020b09ca223be907ed964bfc63b7a4fe8e1b",
   "in_reply_to": null,
   "text": "Would this be somewhat more correct in the final commit?\n```suggestion\n//! `LogDebug` and `LogTrace` macros require an initial category argument unless given a log source (which provides it).\n//! That enables Debug and Trace messages to be filtered by category. Higher levels do not take a category (but may be passed a log source):\n```"
  },
  {
   "t": "2026-03-04T09:14:25Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/signet.cpp",
   "commit": "7eef6bfa91d5aade1d6984a75f2a4315e0f48167",
   "in_reply_to": null,
   "text": "nit: This and the change to src/zmq/zmqutil.cpp seem unrelated?"
  },
  {
   "t": "2026-03-04T09:24:11Z",
   "kind": "review_comment",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": 2879581926,
   "text": "Would prefer avoiding extra lambdas.\n\nHere's a solution that allows making `Format()` non-`const`:\n```diff\ndiff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp\nindex 0690affd7c..430a626559 100644\n--- a/src/test/logging_tests.cpp\n+++ b/src/test/logging_tests.cpp\n@@ -210,24 +210,23 @@ BOOST_FIXTURE_TEST_CASE(logging_context_args, LogSetup)\n     BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end());\n }\n\n-struct CustomLogSource : public util::log::Source {\n-    CustomLogSource(int& counter) : Source{BCLog::VALIDATION}, m_counter{counter} {}\n+struct CustomLogSource : util::log::Source {\n+    CustomLogSource() : Source{BCLog::VALIDATION} {}\n\n     template <typename... Args>\n-    std::string Format(util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args) const\n+    std::string Format(util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)\n     {\n         return tfm::format(\"Custom #%d %s\", ++m_counter, tfm::format(fmt, args...));\n     }\n\n-    int& m_counter;\n+    int m_counter{0};\n };\n\n BOOST_FIXTURE_TEST_CASE(logging_CustomSource, LogSetup)\n {\n     LogInstance().EnableCategory(BCLog::LogFlags::ALL);\n     LogInstance().SetLogLevel(BCLog::Level::Debug);\n-    int counter{0};\n-    CustomLogSource log{counter};\n+    CustomLogSource log;\n     LogTrace(log, \"foo0: %s\", \"bar0\"); // not logged\n     LogDebug(log, \"foo1: %s\", \"bar1\");\n     LogInfo(log, \"foo2: %s\", \"bar2\");\ndiff --git a/src/util/log.h b/src/util/log.h\nindex f81f5653d8..268e1ae591 100644\n--- a/src/util/log.h\n+++ b/src/util/log.h\n@@ -97,7 +97,7 @@ namespace detail {\n //! Internal helper to get log source object from the first macro argument.\n template <bool take_category, typename Source>\n requires (Source::log_source)\n-const Source& GetSource(const Source& source LIFETIMEBOUND) { return source; }\n+Source& GetSource(Source& source LIFETIMEBOUND) { return source; }\n\n template <bool take_category>\n Source GetSource(Category category)\n@@ -158,7 +158,7 @@ void Log(Level level, bool should_ratelimit, bool take_category, SourceLocation&\n // NOLINTBEGIN(bugprone-lambda-function-name)\n #define LogPrint_(level, should_ratelimit, take_category, ...)                                     \\\n     do {                                                                                           \\\n-        const auto& _source{util::log::detail::GetSource<take_category>(FirstArg_((__VA_ARGS__)))}; \\\n+        auto&& _source{util::log::detail::GetSource<take_category>(FirstArg_((__VA_ARGS__)))};     \\\n         if (util::log::ShouldLog(_source.logger, _source.category, (level))) {                     \\\n             util::log::detail::Log((level), (should_ratelimit), take_category,                     \\\n                                    SourceLocation{__func__}, _source, __VA_ARGS__);                \\\n```"
  },
  {
   "t": "2026-03-04T10:59:30Z",
   "kind": "review",
   "who": "hodlinator",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "text": "Reviewing 6d91998175b40939001e01ae2cd78571bff392b7\n\nPublishing some comments early as one of them suggests an alternative to a recent suggestion."
  },
  {
   "t": "2026-03-04T11:16:16Z",
   "kind": "review_comment",
   "who": "l0rinc",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": 2879581926,
   "text": "[quoted text omitted]\n\nThe names should be adjusted after my suggestion; that's true (maybe `FormatHookSource`, `FormatSpy`, `FormatDelegate`). But lambdas would narrow the scope, untangle the data from the behavior in a functional style, and make it simpler to describe the intent of each participant at a higher level, since they're not doing multiple custom things. I'm also fine with your suggestions; I'll let Russ decide."
  },
  {
   "t": "2026-03-04T12:51:07Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nDisagreements are great; best thing about AI is I have someone on call 24/7 who'll argue with me about any stupid technical detail for as long as I want. What is frustrating here is not that you're not disagreeing with me, it's that you're just dismissing my concerns, and hoping you'll get enough other ACKs to get away with merging the PR anyway, and weirdly, you're happy to explicitly spell that out:\n\n[quoted text omitted]\nI can't imagine why you would think saying \"sorry\" with one breath and \"hey everyone, just ignore this guy\" in the next would come across as an attempt to get things on the right foot.\n\nAnyway, explicit downsides? As at 2026-03-04 12:08 UTC, you motivate this PR by two goals:\n\n[quoted text omitted]\nI've objected to the latter of these [earlier in this PR](https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-1899825975) writing:\n\n[quoted text omitted]\nThat's now become a +438-130 diff (+116-78 if you ignore this PR and only consider the followup), and not a single use of the new API uses anything other than LogInfo; even the single existing LogTrace entry in wallet/sqlite.cpp isn't touched. This is a lot of code churn, a bunch of additional code, and more complexity at every call site, for no benefit at all.\n\nAs for the former, adding multiple logger instances to the bitcoinkernel project still seems to be a massive design error to me: one that is far easier met by users who want independent validation instances using separate processes, and one that drives the kernel further away for the needs of the node software. I wrote about that at [2024-05-02](https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2090083022) in this PR. Your response to that was silence for a month, followed by the non-responsive \"I want to let your comment stand\", and the mass of \"LogError and LogWarning are broken\" issues/PRs.\n\nSo, no, I don't believe you've \"adjusted it to do literally every single thing you have asked for\". I think this idea is fundamentally mistaken at the conceptual level, and while I'm still willing to discuss it and bounce ideas around (cf #30386, #30355, #34729, #34730, later commits in #34038), you've burnt a lot of my potential good will on the topic, and for whatever reason you seem determined to actively continue to do so. If you want the cheat code to actually get on my good side, just skip the apologies and completely ignore any uncomfortable history and debate objective tech ideas with me."
  },
  {
   "t": "2026-03-04T15:07:14Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": 2871984987,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2871984987\n\nThanks, added \"to\""
  },
  {
   "t": "2026-03-04T15:13:15Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": 2871988320,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2871988320\n\n[quoted text omitted]\nGood point that this inconsistency does not make sense. After #34465, interpretation of category values should be happend at log-handling level, and log-generating macros should not be involved. I split off a new commit \"log refactor: Ensure categories are not logged at info and higher levels\" from the existing commit \"log refactor: Disallow category args to logging macros\" to separate the two parts of this change and implement it more cleanly.\n\n[quoted text omitted]\nFixed this too :)"
  },
  {
   "t": "2026-03-04T15:14:26Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": 2878979154,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2878979154\n\n[quoted text omitted]\nYes nice suggestion, should be done in all commits now."
  },
  {
   "t": "2026-03-04T15:14:46Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": 2878993964,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2878993964\n\n[quoted text omitted]\nAdded this"
  },
  {
   "t": "2026-03-04T15:15:14Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": 2879003459,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879003459\n\n[quoted text omitted]\nThanks, and latest version drops this lambda to simplify the test"
  },
  {
   "t": "2026-03-04T15:16:08Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": 2879007862,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879007862\n\n[quoted text omitted]\nMakes sense, applied your other [suggestion](https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879038532) adding the loop."
  },
  {
   "t": "2026-03-04T15:17:03Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": 2879038532,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879038532\n\n[quoted text omitted]\nThanks, applied your suggestion with a simplification dropping the lambda as well."
  },
  {
   "t": "2026-03-04T15:18:57Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": 2879041264,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879041264\n\n[quoted text omitted]\nThanks included this with your suggestion"
  },
  {
   "t": "2026-03-04T15:19:23Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "1987fb2fb069197edded87e4de0ea4ddd63b4b55",
   "in_reply_to": 2879062720,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879062720\n\n[quoted text omitted]\nIncluded the fix in your suggestion"
  },
  {
   "t": "2026-03-04T15:19:40Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "ee3fb8cf39faec7144f5727030a27d05f89c8688",
   "in_reply_to": 2879175494,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879175494\n\nThanks, added BOOST_REQUIRE"
  },
  {
   "t": "2026-03-04T15:48:55Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/logging.cpp",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": 2879459007,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879459007\n\n[quoted text omitted]\nIt is an abstraction, but I don't think it's a failure. The use-case for this is #34374 which drops the `BCLog::Logger` dependency from libbitcoinkernel and switches to a simpler [KernelLogger](https://github.com/stickies-v/bitcoin/blob/ebe4409b722facd7d019aa800e226e26db404f81/src/kernel/bitcoinkernel.cpp#L58-L61) class.\n\nThe idea is that the log-generating macros in `util/log.h` should not care about how log entries are formatted or where log messages are stored. Those things are the responsibility of a `Logger` class the application can direct log messages to in the `ShouldLog` and `Log` hooks it provides when the application is linked.\n\nThe `Logger` definition should be opaque, so one option could be to pass it as a `void*`. But using a base class pointer instead of a void pointer provides a little more compile-time safety for the link-time logger option.\n\nIf you think it would be better, we could keep the dependency on `BCLog::Logger` for now and get rid of the static cast as shown in the diff below. Ultimately though unless we want `BCLog::Logger` to be part of libbitcoinkernel we will need to drop this dependency.\n\ndiff\n\n```diff\n--- a/src/logging.cpp\n+++ b/src/logging.cpp\n@@ -607,13 +607,13 @@ bool BCLog::Logger::SetCategoryLogLevel(std::string_view category_str, std::stri\n\n bool util::log::ShouldLog(Logger* log, Category category, Level level)\n {\n-    auto& logger{log ? *static_cast<BCLog::Logger*>(log) : LogInstance()};\n+    auto& logger{log ? *log : LogInstance()};\n     return logger.WillLogCategoryLevel(static_cast<BCLog::LogFlags>(category), level);\n }\n\n void util::log::Log(Logger* log, Entry entry)\n {\n-    auto& logger{log ? *static_cast<BCLog::Logger*>(log) : LogInstance()};\n+    auto& logger{log ? *log : LogInstance()};\n     if (logger.Enabled()) {\n         logger.LogPrintStr(std::move(entry.message), std::move(entry.source_loc), static_cast<BCLog::LogFlags>(entry.category), entry.level, entry.should_ratelimit);\n     }\n--- a/src/logging.h\n+++ b/src/logging.h\n@@ -124,7 +124,7 @@ namespace BCLog {\n         bool SuppressionsActive() const { return m_suppression_active; }\n     };\n\n-    class Logger : public util::log::Logger\n+    class Logger\n     {\n     public:\n         struct BufferedLog {\n--- a/src/util/log.h\n+++ b/src/util/log.h\n@@ -36,12 +36,16 @@ private:\n     std::source_location m_loc;\n };\n\n+namespace BCLog {\n+class Logger;\n+} // namespace BCLog\n+\n namespace util::log {\n /** Opaque to util::log; interpreted by consumers (e.g., BCLog::LogFlags). */\n using Category = uint64_t;\n\n /** Base class inherited by log consumers. Opaque like category, used for basic type-checking. */\n-class Logger{};\n+using Logger = BCLog::Logger;\n\n //! Log level constants. Most code will not need to use these directly and can\n //! use LogTrace, LogDebug, LogInfo, LogWarning, and LogError macros defined\n```"
  },
  {
   "t": "2026-03-04T16:09:43Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
   "in_reply_to": 2879562961,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879562961\n\n[quoted text omitted]\nI tried to simplify this and split it up a little, so this might look better now.\n\nThe \"Allow log macros to accept context arguments\" commit 8517c14b77aafda9f34400f122b644b12864d3a4 is reimplementing the log macros, not incrementally adding features. I think the easiest way to understand it is to look at the [new definition of the macros](https://github.com/ryanofsky/bitcoin/blob/8517c14b77aafda9f34400f122b644b12864d3a4/src/util/log.h#L122-L151), and get an idea of how they work by themselves before trying to compare to the previous implemenation. This should be a lot easier than trying to understand how they work from diffs.\n\nIt is possible there may be ways change the header more gradually too, and I'm open to suggestions. I just suspect line-by-line diffs might ultimately not be very helpful here."
  },
  {
   "t": "2026-03-04T16:13:54Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": 2879581926,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2883218423\n\nMostly went with hodlinator's suggestion here just because my hope for this test is to show a simple working example of a custom context object, and I feel like lambdas get in the way of that goal. I made some other changes here: namely avoiding inheritance that may address l0rinc's other concerns, and definitely would be interested to know if there are other things that could be improved here."
  },
  {
   "t": "2026-03-04T16:14:23Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": 2879601912,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879601912\n\nThanks, switched to ReadDebugLogLines here as well"
  },
  {
   "t": "2026-03-04T16:16:43Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/test/logging_tests.cpp",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": 2879690314,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879690314\n\n[quoted text omitted]\nI don't actually think concepts would help with this particular problem, because it's just caused by inheritance. If you rename an overridden method in a subclass, the parent method will be called instead and this couldn't really be detected without something like an `override` keyword that works on nonvirtual methods.\n\nAddressed the problem here just by eliminating the inheritance, which wasn't really necessary."
  },
  {
   "t": "2026-03-04T16:17:12Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": 2879913500,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879913500\n\n[quoted text omitted]\nThanks, added name hints in both relevant commits"
  },
  {
   "t": "2026-03-04T16:20:04Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "a2a2bd7898a2dd190f83a248dda97dd726f91b0a",
   "in_reply_to": 2879978335,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2879978335\n\n[quoted text omitted]\nThat's not really the intent, although inheritance could be useful in some cases. Updated the test to stop using inheritance to make intent clear, and also avoid the other method naming concern you had."
  },
  {
   "t": "2026-03-04T16:21:46Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/util/log.h",
   "commit": "6d91998175b40939001e01ae2cd78571bff392b7",
   "in_reply_to": 2882533548,
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#discussion_r2882533548\n\n[quoted text omitted]\nThanks, I switched back to `Context` for now. I think the name is mostly relevant to discussion in the PR, and after that it should just be an infrequently referenced class name."
  },
  {
   "t": "2026-03-04T16:23:38Z",
   "kind": "review_comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "path": "src/signet.cpp",
   "commit": "7eef6bfa91d5aade1d6984a75f2a4315e0f48167",
   "in_reply_to": 2882661495,
   "text": "[quoted text omitted]\n\nI believe this is needed to avoid IWYU failures because the macros no longer call `Assume`"
  },
  {
   "t": "2026-03-04T16:25:39Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "fe17020b09ca223be907ed964bfc63b7a4fe8e1b"
  },
  {
   "t": "2026-03-04T16:27:07Z",
   "kind": "review",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "state": "COMMENTED",
   "commit": "fe17020b09ca223be907ed964bfc63b7a4fe8e1b",
   "text": "Thanks for the reviews and thanks for the reply AJ. I think I addressed most of the individual review comments, but there are a few things remaining and I plan to follow up soon.\n\nUpdated 6d91998175b40939001e01ae2cd78571bff392b7 -> fe17020b09ca223be907ed964bfc63b7a4fe8e1b ([`pr/bclog.37`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.37) -> [`pr/bclog.38`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.38), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.37..pr/bclog.38)) with various suggested changes.\n\nRebased fe17020b09ca223be907ed964bfc63b7a4fe8e1b -> 724b5aed21d6abe6345d8b556d7f6b4ff4a8494a ([`pr/bclog.38`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.38) -> [`pr/bclog.39`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.39), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.38-rebase..pr/bclog.39)) on top of base PR #34778 which helps simplify the changes here\n\nRebased 724b5aed21d6abe6345d8b556d7f6b4ff4a8494a -> 551a030b6fcfa5671bb0da73c66b1a7c1fd2d0a4 ([`pr/bclog.39`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.39) -> [`pr/bclog.40`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.40), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.39-rebase..pr/bclog.40)) on top of #34778 pr/relog.2\n\nRebased 551a030b6fcfa5671bb0da73c66b1a7c1fd2d0a4 -> 7eef6bfa91d5aade1d6984a75f2a4315e0f48167 ([`pr/bclog.40`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.40) -> [`pr/bclog.41`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.41), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.40-rebase..pr/bclog.41)) on top of #34778 pr/relog.4\n\nRebased 7eef6bfa91d5aade1d6984a75f2a4315e0f48167 -> b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e ([`pr/bclog.41`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.41) -> [`pr/bclog.42`](https://github.com/ryanofsky/bitcoin/commits/pr/bclog.42), [compare](https://github.com/ryanofsky/bitcoin/compare/pr/bclog.41-rebase..pr/bclog.42)) on top of #34778 pr/relog.5"
  },
  {
   "t": "2026-03-04T18:23:32Z",
   "kind": "comment",
   "who": "ryanofsky",
   "assoc": "MEMBER",
   "text": "re: https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-3997359106\n\n@ajtowns So your previous concerns which were about harms you thought this PR caused (like log categories being shown, allowing users to filter messages by category, allowing users to miss important messages they filtered) have been addressed.\n\nYour current set of concerns is not about harms this PR is causing, or about harms the followup PRs are causing (other than existing and creating code diffs), but are statements that you don't think the goals of these PRs are useful or interesting. I feel like this is ok and we can leave it at that? Not everybody needs to be interested in every PR. It's a strength of this project that different people will motivated to implement different features, and focus on different design benefits, and the project as a whole will be better off with no single person caring about every feature and benefit.\n\nI am happy to talk about benefits of these PRs, and any specific tradeoffs you see. I just feel like there is an exit ramp here, and we can each work on things we feel are useful and important without clashing unnecessarily?"
  },
  {
   "t": "2026-03-05T14:24:33Z",
   "kind": "comment",
   "who": "ajtowns",
   "assoc": "MEMBER",
   "text": "[quoted text omitted]\n\nYour original description of this PR listed a different set of goals to the current description of this PR. My early remarks were addressing the goals you claimed at the time (both in this PR and in your comments to #28318 that preceded it).\n\n[quoted text omitted]\nThat is not an accurate statement of my view.\n\n[quoted text omitted]\nNo, I believe this PR and its followups actively make the codebase worse, and any similar PR aimed at making a similar change would also make the codebase worse. That is what \"Concept NACK\" means.\n\nOr are you trying to argue that I've only objected to the followup PRs, and it would be fine to reject those but still merge this PR, and setup a new API that's merely never used? I would hope that any contributor to this codebase would Concept NACK a new internal API that has no uses.\n\n[quoted text omitted]\nIt's currently, what, 617 days since you didn't want to reply [\"right away\"](https://github.com/bitcoin/bitcoin/pull/29256#issuecomment-2189951185) to discuss one set of comments that's still applicable to these PRs. I suppose I could believe you're happy to talk about the benefits of your PRs to an uncritical audience, but you continue to give a very convincing demonstration that you don't have much interest in discussing objections to them.\n\nI said previously \"If you want the cheat code to actually get on my good side, just [..] debate objective tech ideas with me\". You're again explicitly choosing to only respond to the political/emotional aspects while ignoring the technical issues I re-raised in that comment.\n\n[quoted text omitted]\nI would rather not clash unnecessarily, which is why I've been silent on this PR since, what, 2024-06-29, and likewise why I don't bother reviewing or commenting on ArgsManager changes much anymore after [#16545](https://github.com/bitcoin/bitcoin/pull/16545#discussion_r693393118). But I was explicitly asked for my opinion, and I've also observed you rushing [another PR](https://github.com/bitcoin/bitcoin/pull/34465) through with the [explicit justification](https://github.com/bitcoin/bitcoin/pull/34374#issuecomment-3824030533) of making these code easier to get accepted. I think both the [concerns I was raising](https://github.com/bitcoin/bitcoin/pull/34374#pullrequestreview-3696923926) in that and the IPC/logging performance issue linked in my previous comment also arise from the mistaken attitude that our logging system should be some generic API, rather than one focused on precisely our needs. So it's become hard to justify continuing to be silent."
  },
  {
   "t": "2026-03-09T15:43:34Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "724b5aed21d6abe6345d8b556d7f6b4ff4a8494a"
  },
  {
   "t": "2026-04-01T18:53:24Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "551a030b6fcfa5671bb0da73c66b1a7c1fd2d0a4"
  },
  {
   "t": "2026-05-07T08:02:15Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "7eef6bfa91d5aade1d6984a75f2a4315e0f48167"
  },
  {
   "t": "2026-05-27T00:54:44Z",
   "kind": "force_push",
   "who": "ryanofsky",
   "commit": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e"
  }
 ],
 "labels_log": [
  {
   "t": "2024-01-16T23:59:53Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-01-17T18:53:31Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-01-17T19:15:20Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-01-17T22:26:37Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-01-19T10:04:35Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-01-19T13:50:48Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-01-24T20:36:44Z",
   "action": "labeled",
   "label": "Utils/log/libs",
   "who": "willcl-ark"
  },
  {
   "t": "2024-01-25T21:06:45Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-01-30T23:33:54Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-02-10T12:18:15Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-02-28T04:11:32Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-03-12T20:26:56Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-03-28T18:25:42Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-04-20T10:31:02Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-04-23T07:37:46Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2024-07-26T15:46:15Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-08-07T02:42:09Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-09-02T22:45:32Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2024-12-09T20:52:43Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-04-03T17:37:00Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2025-04-04T05:16:49Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2025-07-09T20:37:07Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-10-15T00:57:25Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-12-06T15:00:01Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-12-12T13:17:58Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-12-14T14:27:38Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-12-16T02:46:13Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2025-12-18T13:02:04Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-01-18T01:21:45Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-01-18T02:48:19Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-01-18T16:27:09Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-02-08T00:14:35Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-02-09T14:32:17Z",
   "action": "labeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-02-09T15:13:16Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-02-09T17:51:54Z",
   "action": "unlabeled",
   "label": "CI failed",
   "who": "DrahtBot"
  },
  {
   "t": "2026-03-23T03:46:21Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-01T20:28:55Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-04-23T12:55:04Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-07T09:31:15Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-22T04:22:49Z",
   "action": "labeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  },
  {
   "t": "2026-05-27T02:08:30Z",
   "action": "unlabeled",
   "label": "Needs rebase",
   "who": "DrahtBot"
  }
 ],
 "state_log": [
  {
   "t": "2024-01-17T23:41:18Z",
   "kind": "ready_for_review",
   "who": "ryanofsky"
  },
  {
   "t": "2025-04-03T17:28:27Z",
   "kind": "renamed",
   "who": "ryanofsky",
   "from": "Improve new LogDebug/Trace/Info/Warning/Error Macros",
   "to": "log, refactor: Allow log macros to accept context arguments"
  },
  {
   "t": "2026-03-09T16:49:03Z",
   "kind": "convert_to_draft",
   "who": "ryanofsky"
  }
 ],
 "text_chars": 98185,
 "text_tokens_estimate": 24546,
 "changed_paths": [
  "doc/developer-notes.md",
  "src/logging.cpp",
  "src/logging.h",
  "src/test/logging_tests.cpp",
  "src/util/log.h",
  "src/validation.cpp"
 ],
 "files": [
  {
   "path": "doc/developer-notes.md",
   "add": 1,
   "del": 2
  },
  {
   "path": "src/logging.cpp",
   "add": 18,
   "del": 24
  },
  {
   "path": "src/logging.h",
   "add": 3,
   "del": 3
  },
  {
   "path": "src/test/logging_tests.cpp",
   "add": 207,
   "del": 21
  },
  {
   "path": "src/util/log.h",
   "add": 185,
   "del": 62
  },
  {
   "path": "src/validation.cpp",
   "add": 3,
   "del": 2
  }
 ],
 "test_lines": 228,
 "git": {
  "head": "b5d3925d27468ff4d5d2e6be7e9ec0c7f8c3a05e",
  "head_matches_backup": true,
  "base": "a4157fc24a29118b1c9d1ac5b7977104217bcee9",
  "commits": [
   {
    "sha": "963ed23bc8",
    "subject": "log test: verify log argument evaluation semantics",
    "files": 1,
    "add": 26,
    "del": 0
   },
   {
    "sha": "3ea9b7cb10",
    "subject": "log test: add some test coverage on LogAcceptCategory",
    "files": 1,
    "add": 16,
    "del": 0
   },
   {
    "sha": "9c509ca53c",
    "subject": "log test: Add test for all accepted logging arguments",
    "files": 1,
    "add": 55,
    "del": 18
   },
   {
    "sha": "98f3bd6242",
    "subject": "log refactor: Ensure categories are not logged at info and higher levels",
    "files": 2,
    "add": 4,
    "del": 2
   },
   {
    "sha": "31f9929f3d",
    "subject": "log refactor: log macro rewrite",
    "files": 5,
    "add": 163,
    "del": 78
   },
   {
    "sha": "f0929e1b78",
    "subject": "log refactor: Drop Entry::should_ratelimit field",
    "files": 4,
    "add": 15,
    "del": 19
   },
   {
    "sha": "1ac1be8b15",
    "subject": "Merge branch 'pr/relog' into pr/bclog",
    "files": 6,
    "add": 275,
    "del": 113
   },
   {
    "sha": "aa37de26b0",
    "subject": "log refactor: Allow log macros to accept context arguments",
    "files": 4,
    "add": 86,
    "del": 23
   },
   {
    "sha": "1eedcb9db5",
    "subject": "doc: Add documentation about log levels and macros",
    "files": 1,
    "add": 36,
    "del": 1
   },
   {
    "sha": "b5d3925d27",
    "subject": "log refactor: Add support for custom log contexts",
    "files": 2,
    "add": 44,
    "del": 1
   }
  ],
  "patch_truncated": false
 },
 "input_hash": "f6425d2c0a558c09",
 "extracted_at": "2026-09-17T16:15:31+00:00"
}