Skip to main content

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

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bozo-0.1.0.tar.gz (129.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bozo-0.1.0-py3-none-any.whl (49.1 kB view details)

Uploaded Python 3

File details

Details for the file bozo-0.1.0.tar.gz.

File metadata

  • Download URL: bozo-0.1.0.tar.gz
  • Upload date:
  • Size: 129.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for bozo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5f39a59d39aa1ca83886543dd6228a6dca37089ad8018588c5e77ad5296ee3ed
MD5 dbc867afa6c1212c2b53363475132015
BLAKE2b-256 2c492babd70d31a740f855603cc495f7dd490d8c1dc435a62529ba183f9106aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for bozo-0.1.0.tar.gz:

Publisher: release.yml on tejus3131/bozo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bozo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: bozo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 49.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for bozo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7e2b2da1b5d1293b88175afb85983c4192109ce39187e99436653c69f5f0633f
MD5 b3be2af24eb533718e1209fab1d69399
BLAKE2b-256 a8f7ebdda2b06569598024e540133cdf2882918ae7430bff879cb35153e5a4e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for bozo-0.1.0-py3-none-any.whl:

Publisher: release.yml on tejus3131/bozo

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page