Production-grade structured logging with optional real-time web viewer
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f39a59d39aa1ca83886543dd6228a6dca37089ad8018588c5e77ad5296ee3ed
|
|
| MD5 |
dbc867afa6c1212c2b53363475132015
|
|
| BLAKE2b-256 |
2c492babd70d31a740f855603cc495f7dd490d8c1dc435a62529ba183f9106aa
|
Provenance
The following attestation bundles were made for bozo-0.1.0.tar.gz:
Publisher:
release.yml on tejus3131/bozo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bozo-0.1.0.tar.gz -
Subject digest:
5f39a59d39aa1ca83886543dd6228a6dca37089ad8018588c5e77ad5296ee3ed - Sigstore transparency entry: 914734106
- Sigstore integration time:
-
Permalink:
tejus3131/bozo@6c2bd430068a7218af23eb9f5b2b324d259282a1 -
Branch / Tag:
refs/tags/v0.1.0-release - Owner: https://github.com/tejus3131
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6c2bd430068a7218af23eb9f5b2b324d259282a1 -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e2b2da1b5d1293b88175afb85983c4192109ce39187e99436653c69f5f0633f
|
|
| MD5 |
b3be2af24eb533718e1209fab1d69399
|
|
| BLAKE2b-256 |
a8f7ebdda2b06569598024e540133cdf2882918ae7430bff879cb35153e5a4e3
|
Provenance
The following attestation bundles were made for bozo-0.1.0-py3-none-any.whl:
Publisher:
release.yml on tejus3131/bozo
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bozo-0.1.0-py3-none-any.whl -
Subject digest:
7e2b2da1b5d1293b88175afb85983c4192109ce39187e99436653c69f5f0633f - Sigstore transparency entry: 914734146
- Sigstore integration time:
-
Permalink:
tejus3131/bozo@6c2bd430068a7218af23eb9f5b2b324d259282a1 -
Branch / Tag:
refs/tags/v0.1.0-release - Owner: https://github.com/tejus3131
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6c2bd430068a7218af23eb9f5b2b324d259282a1 -
Trigger Event:
push
-
Statement type: