bozo
Production-grade structured logging with optional real-time web viewer.
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)
| File | Size | Uploaded | |
|---|---|---|---|
| bozo-0.1.0.tar.gz | 129.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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