Skip to main content

dazzle-loglib

PyPI Release Date PyPI Downloads Python License: MIT GitHub Discussions Platform

Channel/verbosity-aware CLI output management -- the diagnostic-output member of the perpendicular tier of the DazzleLib stack.

One signed verbosity axis crossed with consumer-defined named channels, so a program can answer how loud is each channel of my self-narration, and where does each message go? — per subsystem, independently, from one -v-stacking CLI surface.

pip install dazzle-loglib

What this owns (and what it doesn't)

Owns Does not own
The verbosity gate — one integer comparison, and no message is formatted unless it passes Color and rich formatting (supply a renderer callable; the hook is built in)
The channel registry each program declares for itself Your channel vocabulary — there is no built-in "correct" channel set
Where a message goes (per-manager, per-channel, or per-message destinations) Durable structured logs; this is on-demand interactive detail, not the audit record
Env/CLI resolution with defined precedence Reading the environment implicitly — you name your own variables
A hint registry (runtime, context-filtered, session-deduplicated) Help-surface content — that's dazzle-helplib's TIPs, a deliberately separate mechanism

The model: verbosity x channel

One signed verbosity axis (a dazzle_lib.Continuum with an invariant zero):

<-- quieter -------------------- default --------------------------- louder -->
-4       -3       -2       -1       0      1       2       3        4        5
wall  errors warnings  minimal default extra diagnostics config lite-debug debug

A message at level shows when level <= threshold; at -4 (the hard wall) nothing shows at all. -v steps warmer, -q steps colder, and they compose (-vv -q = 1).

Channels are the orthogonal dimension, and each program declares its own:

from dazzle_loglib import init_output, get_output, ChannelDef

init_output(
    verbosity=args.verbose - args.quiet,
    strict_channels=True,
    channel_defs=[
        ChannelDef("liveness", "Session liveness verification"),
        ChannelDef("git",      "Git operations"),
        ChannelDef("scan",     "Discovery and scanning"),
        ChannelDef("vals",     "Value annotations on results", opt_in=True),
    ],
    channels=args.show,          # e.g. ["liveness:diagnostics", "scan:2"]
)

out = get_output()
out.emit(1, "scanned {n} sessions", channel="scan", n=count)
out.emit(2, "entry={id} pid={pid} in_by_pid={hit} -> reject({rung})",
         channel="liveness", id=entry_id, pid=pid, hit=hit, rung=rung)

Each channel can be pinned independently of the global level, so --show liveness:debug floods one subsystem without drowning the rest. Named rungs work anywhere integers do, opt-in channels stay cold until raised, and the channels x verbosity crossing is a real ContinuumSpace (out.verbosity_space()) — so further axes compose rather than bolt on.

Status

0.3.x, alpha — and deliberately still flexible. This library ships mid-development of the wider DazzleLib stack: its first real consumer has not landed yet, and adoption is what usually reshapes an API. So the promise here is no silent drift rather than no change — docs/api-stability.md enumerates the tracked surface (pinned by an import-stability canary), the parts explicitly excluded from any promise, and, honestly, where movement is still expected. Changes land in CHANGELOG.md with a version bump, never quietly.

Usage

Zero cost when gated

emit() never formats a message that will not show — keyword arguments are interpolated only after the gate passes. For expensive collection, ask first:

if out.is_level_active(2, "liveness"):
    rows = expensive_enumeration()        # skipped entirely at default verbosity
    out.emit(2, "rows={n}", channel="liveness", n=len(rows))

Resolution with defined precedence

from dazzle_loglib import resolve_verbosity, resolve_channel_specs

verbosity = resolve_verbosity(args.verbose, args.quiet,
                              explicit=args.verbosity,     # --verbosity N wins outright
                              env_var="MYAPP_VERBOSITY")   # consulted only when the CLI is silent
specs = resolve_channel_specs(args.show, env_var="MYAPP_SHOW")

Precedence is explicit > CLI counts > environment > default, and CLI counts count as expressed whenever either is nonzero — -v -q nets to zero but still beats the environment. Hooks, schedulers, and other non-interactive contexts turn detail up by setting the variables; nothing edits scripts.

Injecting an emitter (the std-swappable seam)

Libraries that should never depend on a logging package can still speak:

from dazzle_loglib.protocols import EmitterProtocol, NullEmitter

def verify_tree(root, emitter: EmitterProtocol = None):
    emitter = emitter or NullEmitter()     # silent by default
    if emitter.is_level_active(2, "verify"):
        emitter.emit(2, "checking {p}", channel="verify", p=root)

EmitterProtocol is structural: a real OutputManager satisfies it, and so does a four-line shim over print (or CallableEmitter(logging.getLogger(__name__).info)). The contract travels down the stack; the implementation stays out of your dependency tree.

Renderers, hints, and tracing

emit() resolves a renderer in layers — per-call render=, per-channel renderer, global default_renderer, then plain print() to the resolved destination (stderr by default; 'stdout'/'stderr' sentinels resolve at emit time, so rebound streams are honored). Color belongs in a renderer callable (init_output(renderer=console.print)), never in the core. Also included: a Hint registry (context-filtered, session-deduplicated, routed through the same gate) and a @trace decorator (function entry/exit at full debug on the trace channel).

Installation

pip install dazzle-loglib

From source

git clone https://github.com/DazzleLib/dazzle-loglib.git
cd dazzle-loglib
pip install -e ".[dev]"

Documentation

Migrating from a vendored log_lib

Projects carrying the ancestral copy: 0.2.0 re-runged the verbosity scale (config 2→3, debug 3→5, timing renamed extra) and replaced module-set channel registration with channel_defs=. The legacy module sets still import but warn on mutation and are excluded from the API-stability guarantee. See DazzleTools/dazzlecmd#118 for the cutover playbook.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

python -m venv .venv
source .venv/bin/activate   # or .venv\Scripts\activate on Windows
pip install -e ".[dev]"

# Run tests
python -m pytest tests/ -v

# Install git hooks
bash scripts/repokit-common/install-hooks.sh

Two house rules this library lives by:

  • Dependencies point down only. The perpendicular tier consumes the bedrock and nothing else — never a consumer, never a sibling. dazzle-loglib and dazzle-helplib do not import each other.
  • The public surface changes loudly or not at all. The symbols and behaviors listed in docs/api-stability.md are pinned by tests/test_import_stability.py, so drift fails a test rather than reaching a consumer. While the stack is mid-development the surface is still expected to move; the discipline is that it moves deliberately, versioned, and documented.

Like the project?

"Buy Me A Coffee"

Part of DazzleLib

dazzle-loglib sits in the perpendicular tier: usable from any layer, depending only on the dazzle-lib bedrock.

Related Projects

License

dazzle-loglib, Copyright (C) 2026 Dustin Darcy

Licensed under the MIT License -- see LICENSE. The whole DazzleLib stack is MIT-licensed.

Metadata

Release files for dazzle-loglib 0.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dazzle-loglib 0.3.3
File Size Uploaded
dazzle_loglib-0.3.3.tar.gz 41.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dazzle-loglib 0.3.3
File Interpreter ABI Platform
dazzle_loglib-0.3.3-py3-none-any.whl Python 3 none any Details

Total release size: 72.7 kB

Release files / dazzle_loglib-0.3.3.tar.gz

Download URL dazzle_loglib-0.3.3.tar.gz
Size 41.0 kB
Tags Source
SHA-256 checksum
How to use checksums
098bd03d1106516bdbe31b6621b5cef0b151bf51aea117317a27896d3c77f7bd
BLAKE2b-256 checksum
How to use checksums
ed3cec13498bdf6b99377cc7af8c0af382ec5083edad394e8283c6407edec765
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 16, 2026.

Transparency log

Release files / dazzle_loglib-0.3.3-py3-none-any.whl

Download URL dazzle_loglib-0.3.3-py3-none-any.whl
Size 31.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0b5f6222edc6b020ff9ca8e4d71a7b40fe6865ae2d557133eb046893baa6ee9
BLAKE2b-256 checksum
How to use checksums
f6ce2476b51e49457c5a93db0344a3c8f2806aeaacc8389d30fce8626e7cb5fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.3 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page