Skip to main content

bozo

Production-grade structured logging with optional real-time web viewer.

Python 3.13+ MIT License Tests Passing Code Coverage

Simple. One function to set up structured logging. Powerful. File, JSON, HTTP, console—all at once. Developer-Friendly. Type-safe, zero-config defaults.


Features

✨ Structured Logging Context-aware, nested logging with built-in support for sensitive data redaction.

📊 Multiple Outputs Simultaneously log to console (colored), text files, JSON files, and HTTP endpoints.

🌐 Web Viewer (Optional) Real-time log streaming dashboard. Perfect for development and debugging.

🛠 Production-Ready Automatic log rotation, third-party library suppression, and thread-safe operations.

🔍 Full Type Safety Fully typed with Python 3.13+ support. Works great with type checkers.

⚙️ Smart Defaults Intelligent log file management, automatic cleanup, and sensible configuration presets.


Quick Start

Installation

# Core library
pip install bozo

# With web viewer support
pip install bozo[viewer]

Basic Usage

import bozo

# Initialize once at startup
bozo.setup("myapp")
log = bozo.get(__name__)

# Log with structured data
log.info("user_login", user_id=42, email="user@example.com")
log.warning("slow_query", query_time=1.5, threshold=1.0)
log.error("payment_failed", amount=99.99, reason="insufficient_funds")

Output (console, file, JSON—simultaneously):

2026-02-04 10:23:45 | INFO     | myapp.main | user_login
2026-02-04 10:23:46 | WARNING  | myapp.main | slow_query
2026-02-04 10:23:47 | ERROR    | myapp.main | payment_failed

Sensitive Data

Automatically redact passwords, tokens, and secrets:

log.info(
    "auth_attempt",
    username="alice",
    password=bozo.redact("secret123")  # Will log as [REDACTED]
)

Context Management

Attach request context that persists across async/threaded operations:

with bozo.log_context(request_id="abc-123", user_id=42):
    log.info("processing")  # request_id and user_id added automatically
    await some_async_operation()
    log.info("completed")  # context still present

Web Viewer

View logs in real-time from a beautiful dashboard:

# Enable during setup
bozo.setup(
    "myapp",
    enable_viewer=True,
    viewer_port=8080
)

# Or start it manually
bozo.start_viewer(open_browser=True)  # Opens http://127.0.0.1:8080

Configuration

Development vs. Production

# Development: Pretty-printed, colored console output
bozo.setup("myapp", environment=bozo.Environment.DEVELOPMENT)

# Production: Plain text, structured JSON, minimal console
bozo.setup("myapp", environment=bozo.Environment.PRODUCTION)

Output Handlers

Control what gets logged and where:

bozo.setup(
    "myapp",
    # Console
    enable_console=True,
    console_level=bozo.LogLevel.INFO,
    # Text files
    enable_file=True,
    file_level=bozo.LogLevel.DEBUG,
    enable_error_file=True,  # Separate ERROR+ logs
    # JSON files (for log aggregation)
    enable_json=True,
    json_level=bozo.LogLevel.DEBUG,
    # HTTP shipping (for external platforms)
    enable_http=True,
)

Log Directory

Logs are organized by run:

~/.local/share/bozo/myapp/          # macOS/Linux (or platform-specific)
├── current/                         # Latest run
│   ├── 2026-02-04_10-23-45.log
│   ├── 2026-02-04_10-23-45.error
│   └── 2026-02-04_10-23-45.json
├── 2026-02-03_18-15-22/             # Previous runs
│   ├── 2026-02-03_18-15-22.log
│   ├── 2026-02-03_18-15-22.error
│   └── 2026-02-03_18-15-22.json
└── ...

Automatically cleaned up (configurable):

bozo.setup("myapp", max_runs_to_keep=10)  # Keep only 10 most recent runs

Advanced Usage

Capturing Python Warnings

Route Python warnings through bozo:

import warnings

bozo.setup("myapp", capture_warnings=True)

warnings.warn("deprecated feature")  # Will be logged

Third-Party Library Suppression

Reduce noise from verbose libraries:

bozo.setup("myapp", suppress_third_party=True)
# Automatically reduces verbosity for: urllib3, httpx, httpcore, etc.

Programmatic Context

# Set context that persists
bozo.set_context(request_id="req-123")
log.info("operation_started")  # Has request_id

# Clear specific context
bozo.clear_context()

Logging Levels

All standard levels are supported:

log.debug("verbose_info")
log.info("important_event")
log.warning("potential_issue")
log.error("something_failed", error=str(exception))

Type Safety

Full IDE autocomplete and type checking:

import bozo
from bozo import BoundLogger, LogLevel, Environment

log: BoundLogger = bozo.get(__name__)
env: Environment = bozo.Environment.PRODUCTION
level: LogLevel = bozo.LogLevel.DEBUG

Common Patterns

Web Framework Integration

FastAPI:

from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
import bozo

bozo.setup("api", environment=bozo.Environment.PRODUCTION)
log = bozo.get(__name__)

@app.middleware("http")
async def log_requests(request: Request, call_next):
    with bozo.log_context(
        method=request.method,
        path=request.url.path,
        client=request.client.host
    ):
        response = await call_next(request)
        log.info("request", status_code=response.status_code)
        return response

Django:

# settings.py
import bozo

bozo.setup(
    "myproject",
    environment=bozo.Environment.PRODUCTION,
    enable_viewer=False,
)

LOGGING = {"version": 1, "disable_existing_loggers": False}

Database Operations

with bozo.log_context(operation="user_insert"):
    try:
        db.insert_user(user_data)
        log.info("user_created", user_id=user_data["id"])
    except Exception as e:
        log.error("insert_failed", error=str(e), data=user_data)
        raise

Background Tasks

import asyncio

async def process_queue():
    while True:
        item = await queue.get()
        with bozo.log_context(job_id=item["id"]):
            try:
                await process_item(item)
                log.info("job_completed")
            except Exception as e:
                log.error("job_failed", error=str(e))
                await queue.put(item)  # Retry
            await asyncio.sleep(1)

Performance

  • Minimal overhead: Structured logging is negligible vs. application logic
  • Thread-safe: All operations are safe for concurrent use
  • Bounded memory: Web viewer queue has configurable limits
  • Efficient rotation: Automatic file rotation prevents disk bloat

Troubleshooting

Q: Where are my log files?

A: Check ~/.local/share/bozo/yourapp/current/ (or the path printed at startup)

Q: Web viewer not working?

A: Install viewer dependencies: pip install bozo[viewer]

Q: How do I disable file logging?

A: bozo.setup("app", enable_file=False, enable_json=False)

Q: Can I use bozo with existing logging setup?

A: bozo replaces your logging setup. Call bozo.setup() once at startup.


Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines.


License

MIT License - see LICENSE for details.


Support

Made with ❤️ by Tejus Gupta

Metadata

Release files for bozo 0.1.0

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

Source distribution (sdist)

Source distribution for bozo 0.1.0
File Size Uploaded
bozo-0.1.0.tar.gz 129.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bozo 0.1.0
File Interpreter ABI Platform
bozo-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 178.6 kB

Release files / bozo-0.1.0.tar.gz

Download URL bozo-0.1.0.tar.gz
Size 129.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5f39a59d39aa1ca83886543dd6228a6dca37089ad8018588c5e77ad5296ee3ed
BLAKE2b-256 checksum
How to use checksums
2c492babd70d31a740f855603cc495f7dd490d8c1dc435a62529ba183f9106aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 4, 2026.

Transparency log

Release files / bozo-0.1.0-py3-none-any.whl

Download URL bozo-0.1.0-py3-none-any.whl
Size 49.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e2b2da1b5d1293b88175afb85983c4192109ce39187e99436653c69f5f0633f
BLAKE2b-256 checksum
How to use checksums
a8f7ebdda2b06569598024e540133cdf2882918ae7430bff879cb35153e5a4e3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Feb 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 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