Skip to main content

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.Handler integration
  • Built on httpx for 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 Authorization header
  • 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


Download files

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

Source Distribution

mihari_logger-0.1.0.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

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

mihari_logger-0.1.0-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

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

Hashes for mihari_logger-0.1.0.tar.gz
Algorithm Hash digest
SHA256 7f5e9ab79bc71f8fef354fdba295caf39b337f2419925ca5b5fe78410c43f544
MD5 d3ba853293f914b4f3dda675f17c17f9
BLAKE2b-256 d9025e4f0fb8d31d437574a7e08c8de98ff22ae36df5071ed3a9255be86dc89d

See more details on using hashes here.

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

Hashes for mihari_logger-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 361ccc21f682a521b195b07830d06ba4398aa6f3fa2d802246fa544d5fb98c45
MD5 8e71c93434e2df82331475419ffe7244
BLAKE2b-256 a12fd5775a85f82ac721b5ef887478a8e0571b99a1ba8dae96b697c38c01ec65

See more details on using hashes here.

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