degenbot.logging ================ .. py:module:: degenbot.logging .. autoapi-nested-parse:: Logging configuration for the degenbot package. This module owns two concerns: 1. The package logger (``degenbot.logging``) for Python-side records. 2. The **Rust bridge** loggers that the Rust core's ``tracing`` subscriber forwards records into. Rust ``tracing`` events — and ``log::`` records, bridged into ``tracing`` by ``tracing_log::LogTracer`` — are forwarded to Python ``logging`` by the ``PythonLogLayer`` installed by ``init_logging_subscriber`` in ``rust/crates/shells/degenbot-python/src/python_log_layer.rs`` during the explicit ``driver_boot()`` call (module init registers symbols only, and ``Bot`` triggers the boot at construction). The layer derives each record's Python logger name from the Rust target (``::`` → ``.``): an event for ``degenbot_bot::bot_core::block_pump`` lands on the Python logger ``degenbot_bot.bot_core.block_pump``. Without base config those records are silent: the crate-root loggers (``degenbot_bot``, ``degenbot_core``, ``degenbot_rs``, ``degenbot_rpc``, ``degenbot_decoders``, ``degenbot_uniswap``) inherit the root logger's default ``WARNING`` level and have no handler, so every forwarded ``INFO``/``DEBUG`` record is dropped at the Python logger-level gate *before* reaching a handler (and ``WARN``/``ERROR`` only escape via stdlib ``lastResort`` on stderr, bypassing this module's stdout handler and format). The fix lives here, in the base config that runs at ``import degenbot`` time — *before* any Rust code logs (Rust logs fire only once a pump/verify/register operation runs, never during import). Configuring the crate-root loggers up front at the lowered level makes forwarded records visible with no caller wiring. The Rust-side ``tracing`` ``EnvFilter`` (``RUST_LOG``) is the first gate; Python ``logging`` is the second. The level that base config installs is decided by :func:`base_log_level` when :func:`apply_base_log_level` runs, not frozen into a module constant, so the import installs the process default and a later caller can install another. Module Contents --------------- .. py:data:: logger .. py:data:: RUST_BRIDGE_LOGGER_NAMES :value: ('degenbot_bot', 'degenbot_core', 'degenbot_rs', 'degenbot_rpc', 'degenbot_decoders',... .. py:data:: PY_PACKAGE_ROOT_LOGGER_NAMES :value: ('degenbot',) .. py:function:: set_log_level(level: int) -> None Set the degenbot + Rust-bridge log level from one knob. Mirrors the historical conftest behaviour of bumping the package logger to ``DEBUG`` for the test run, extended to cover the Rust bridge loggers so Rust ``debug!`` records are not left behind by the base level applied at import. Lowering the level here is effective because no Rust path logs at import time. The queued handler keeps whatever level the base config gave it (see :func:`apply_base_log_level`); only the knob path lowers that too. .. py:function:: base_log_level() -> int Resolve the console level this process asks for, when it is asked for. ``DEGENBOT_DEBUG`` is a logging-plumbing signal, the same class as ``RUST_LOG``: it says where records go, not how the bot is configured. It used to be read into a module constant, which left the level decided before any caller could speak and no way to change it afterwards; reading it here makes the answer belong to whoever applies the level. :returns: ``logging.DEBUG`` when the knob is set to a true word, else ``logging.INFO``. .. py:function:: apply_base_log_level() -> None Install the ``DEGENBOT_DEBUG``-derived level on every degenbot logger. Runs once at import -- before any Rust record can exist, since ``log::`` fires at pump/verify/register time and never during import -- and again for any caller that changes the environment afterwards. The queued handler's level moves with the loggers': it is the ceiling every record passes on its way to the listener, so a logger-only level would leave the import-time ceiling standing and the knob a no-op for the records it names.