Skip to main content
The official Peeng Python SDK (pip install peeng) is a thread-safe client that delivers logs to Peeng in the background via a daemon thread. Every log call enqueues the entry and returns immediately — the SDK handles batching, retries, and idempotency automatically — so logging never blocks your application or crashes it when Peeng is unavailable.
MIT licensed. Requires Python 3.8+. The only runtime dependency is requests.

Install

Quick start

Construct a client, call any logging method, and call close() when you’re done:
If you never call close() explicitly, it still runs automatically at process exit via atexit — but calling it yourself gives you a deterministic shutdown point.

Why use the SDK

Non-blocking

Log calls enqueue onto an in-memory buffer and return immediately. A background daemon thread flushes it — every flush_interval seconds, or as soon as the buffer hits max_batch_size.

Automatic retries

Network errors, 429s, and 5xxs are retried with exponential backoff and jitter, reusing one Idempotency-Key per batch so retries can’t double-insert.

Never crashes your app

Delivery failures are reported through on_error (or written to stderr) instead of raising out of a logging call.

Thread-safe

Safe to call from multiple threads simultaneously — the internal buffer is protected by a lock.

Constructor parameters

Pass keyword arguments to PeengClient(...) to configure the client.

Logging methods

The SDK exposes one convenience method per log level — debug, info, warn, error, and fatal — plus a generic log() form for dynamic level selection:
status_code is required on every call (100–599). The following keyword arguments are optional: service, metadata (any JSON-serializable dict), stack_trace, hostname, request_id, user_id, and timestamp (a datetime object or an ISO-8601 string). See the field reference for what each one means.

Context manager

Use PeengClient as a context manager to have close() called automatically when the block exits:

Graceful shutdown

Call flush() to block until currently buffered logs are sent, and close() to stop the background thread and flush any remaining logs:
Call close() (or use the context manager) before your process exits for a deterministic delivery guarantee — the atexit hook is a safety net, not a replacement for explicit shutdown in long-running services.

Custom batching configuration

Override the default batching and retry behaviour at construction time:

Error handling

Supply an on_error callback to receive delivery failures without letting them surface as exceptions in your application code:
Your on_error handler receives one of two exception types:
  • peeng.PeengApiError — the server responded with an HTTP error envelope. Carries status_code, message, and error (from the server envelope). Raised for non-retryable errors (e.g. 400) or after retries are exhausted (e.g. repeated 5xx).
  • requests exception — a network-level failure with no HTTP response at all (DNS failure, connection refused), surfaced after retries are exhausted.
Retry behaviour: 429, 5xx, and network/connection errors are retried up to max_retries times with exponential backoff and jitter, reusing the same Idempotency-Key on every retry of a given batch. Any other 4xx (e.g. a 400 validation error) is non-retryable and reported to on_error immediately. See Errors for the full retryable/non-retryable rules.