Lightweight log collection and transport library for Python
Project description
Mihari Logger
Lightweight log collection and transport library for Python.
Mihari Logger collects structured log entries and ships them to an HTTP API with
automatic batching, gzip compression, retry with exponential backoff, and
graceful shutdown. It works as a standalone client or as a drop-in
logging.Handler for Python's standard library.
Features
- Structured JSON log entries with ISO 8601 timestamps
- Automatic batching (configurable batch size and flush interval)
- Gzip compression (enabled by default)
- Retry with exponential backoff on transient failures
- Thread-safe background flushing
- Graceful shutdown via
atexit - Auto-captured metadata: hostname, PID, Python version, platform
- Python
logging.Handlerintegration - Built on
httpxfor modern HTTP support
Installation
pip install mihari-logger
Quick Start
Standalone Client
from mihari import Mihari
client = Mihari(
token="your-api-token",
endpoint="https://logs.example.com",
)
client.info("Application started", version="1.2.0", port=8080)
client.warn("Cache miss rate high", rate=0.42)
client.error("Connection failed", host="db.local", retries=3)
client.debug("Query executed", sql="SELECT ...", duration_ms=12)
client.fatal("Out of memory", heap_mb=1024)
# Logs are flushed automatically on exit, or call:
client.close()
With Python's logging Module
import logging
from mihari import MihariHandler
handler = MihariHandler(
token="your-api-token",
endpoint="https://logs.example.com",
)
logging.basicConfig(handlers=[handler], level=logging.INFO)
logger = logging.getLogger("myapp")
logger.info("Server started")
logger.warning("Disk usage at 85%%")
logger.error("Request failed", extra={"path": "/api/users", "status": 500})
With structlog
import structlog
import logging
from mihari import MihariHandler
handler = MihariHandler(
token="your-api-token",
endpoint="https://logs.example.com",
)
logging.basicConfig(handlers=[handler], level=logging.DEBUG, format="%(message)s")
structlog.configure(
processors=[
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.StackInfoRenderer(),
structlog.dev.set_exc_info,
structlog.processors.TimeStamper(fmt="iso"),
structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
],
logger_factory=structlog.stdlib.LoggerFactory(),
)
log = structlog.get_logger()
log.info("payment.processed", amount=99.99, currency="USD")
Configuration
Client Options
from mihari import Mihari
client = Mihari(
token="your-api-token",
endpoint="https://logs.example.com",
transport_config={
"batch_size": 10, # Entries per batch (default: 10)
"flush_interval": 5.0, # Seconds between flushes (default: 5.0)
"max_retries": 3, # Retry attempts (default: 3)
"base_delay": 1.0, # Initial retry delay in seconds (default: 1.0)
"max_delay": 30.0, # Maximum retry delay in seconds (default: 30.0)
"gzip": True, # Enable gzip compression (default: True)
"timeout": 10.0, # HTTP timeout in seconds (default: 10.0)
},
default_meta={ # Attached to every log entry
"service": "payment-api",
"env": "production",
},
)
Handler Options
from mihari import MihariHandler
import logging
handler = MihariHandler(
token="your-api-token",
endpoint="https://logs.example.com",
level=logging.WARNING, # Only forward WARNING+ to Mihari
transport_config={...}, # Same options as above
default_meta={"service": "web"},
)
Log Entry Format
Each log entry is sent as JSON:
{
"dt": "2024-01-15T10:30:00.123456Z",
"level": "info",
"message": "Request handled",
"hostname": "web-01",
"pid": "12345",
"python_version": "3.12.1",
"platform": "linux",
"method": "GET",
"path": "/api/users"
}
API Specification
- Auth: Bearer token in
Authorizationheader - Endpoint:
POST {base_url}/logs - Content-Type:
application/json - Content-Encoding:
gzip(when enabled) - Success (202):
{"status": "accepted", "count": N} - Auth Error (401):
{"error": "Invalid or missing authentication token"}
Development
# Clone and install in development mode
git clone https://github.com/mihari/mihari-logger-python.git
cd mihari-logger-python
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=mihari_logger --cov-report=term-missing
# Lint
ruff check src/ tests/
# Type check
mypy src/
License
MIT
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 mihari_logger-0.1.0.tar.gz.
File metadata
- Download URL: mihari_logger-0.1.0.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f5e9ab79bc71f8fef354fdba295caf39b337f2419925ca5b5fe78410c43f544
|
|
| MD5 |
d3ba853293f914b4f3dda675f17c17f9
|
|
| BLAKE2b-256 |
d9025e4f0fb8d31d437574a7e08c8de98ff22ae36df5071ed3a9255be86dc89d
|
File details
Details for the file mihari_logger-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mihari_logger-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
361ccc21f682a521b195b07830d06ba4398aa6f3fa2d802246fa544d5fb98c45
|
|
| MD5 |
8e71c93434e2df82331475419ffe7244
|
|
| BLAKE2b-256 |
a12fd5775a85f82ac721b5ef887478a8e0571b99a1ba8dae96b697c38c01ec65
|