Add spdlog CLI integration with --log-level flag (issue #184, PR B) - #186
Conversation
Wires the crypto_log hook to spdlog's stderr colour sink via a new --log-level option (env: SCLI_LOG_LEVEL, default: warn). Early argv pre-scan ensures the logger is live before CLI11 subcommand callbacks run, so debug/info output is correctly emitted during operations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Blocking finding on latest head f6e114b:
Repro:
The fix should keep operational/library logging disabled at Other verification so far:
Not ready to merge until the silent-error path is fixed. |
When --log-level off was set, spdlog dropped the error() call and the fallback std::cerr path was never reached, producing a silent exit 1. Fatal CLI errors must always be visible, so write to stderr directly first then also forward to spdlog (for formatted/sink output) when the logger exists. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Re-reviewed latest head db4efc3. The previous silent-error blocker is fixed for There is still a user-visible blocker before merge: fatal errors are duplicated at the default/warn logging level because Repro:
Suggested shape: emit through spdlog when the logger will actually emit the error, otherwise fall back to Verification run on latest head:
CI is still pending on several jobs, so I did not merge. |
The previous fix wrote to std::cerr unconditionally and then also called logger->error(), producing two lines at warn/default level. Use logger->should_log(spdlog::level::err) to decide the path: when spdlog will emit the message, route through it only; when the logger is off or absent, fall back to std::cerr. Preserves visibility at --log-level off without duplicating output at normal levels. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Re-reviewed latest head 35c99b1. The duplicate fatal-error output blocker is fixed: default/warn/debug now emit one spdlog error line, and --log-level off plus SCLI_LOG_LEVEL=off emit one direct Error: line. Verification:
I do not see a remaining code blocker from this review. GitHub would not allow me to approve because this account owns the PR. CI still has pending jobs, so I did not merge. |
Summary
cmake/PermSpdlog.cmake— FetchContent for spdlog v1.15.3 (header-only, no tests/examples/install)cmake/PermNlohmannJson.cmake— FetchContent for nlohmann/json v3.11.3safe-crypto-cli/cli_logging.hpp— maps a level string to both spdlog threshold andCryptoLogLevel; registers a lambda sink that forwards library log events into spdlog's"scli"stderr colour logger; also providescli_init_logging_from_config()for JSON-driven sink selection--log-leveltop-level CLI option (env:SCLI_LOG_LEVEL, default:warn) so users can enable diagnostic output without recompiling--log-config <path>top-level CLI option — reads a JSON file to configure sinks and level; wins over--log-levelwhen both are suppliedstderr(default),stdout,file(rotating, configurablemax_size_mb/max_files)safe-crypto-cli/cli_error.hpp—die()routes through spdlog when the logger will emit at error level, otherwise falls back tostd::cerr; fatal errors are always visible including at--log-level offargvinmain()before CLI11 parsing so the logger is live when subcommand callbacks execute insideCLI11_PARSETests (41 new, all passing)
Library hook (
safe-crypto-lib-test/crypto_log_tests.hpp, 13 tests):nullptrsink disables loggingmsg()helper formats 1/2/3 key-value pairs correctlysha()emits entry and success debug events; no events when sink is null; error-only threshold suppresses debug from successful operationsCLI
--log-level(safe-crypto-cli-test/logging_tests.hpp, 9 tests):warnproduce no stderr on success--log-level debugemits entry/success trace lines--log-level=valueequals syntax acceptedSCLI_LOG_LEVELenv var triggers debug traceSCLI_LOG_LEVEL=offsilences operational output--log-level offstill emits fatal error messages--log-level warnemits fatal error exactly once (no duplicate)warnJSON config (
safe-crypto-cli-test/log_config_tests.hpp, 9 tests):stderrsink with debug level emits tracestderrsink with warn level is silent on success--log-configwins over--log-levelsinkskey defaults to stderrfilesink writes log entries to the filefilesink withoutpathproduces an errorDepends on
PR #185 (pluggable
crypto_loghook) — already merged to main.JSON config example
{ "level": "debug", "sinks": [ { "type": "stderr" }, { "type": "file", "path": "/var/log/scli.log", "max_size_mb": 10, "max_files": 3 } ] }🤖 Generated with Claude Code