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 callclose() 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 toPeengClient(...) 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
UsePeengClient as a context manager to have close() called automatically when the block exits:
Graceful shutdown
Callflush() 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 anon_error callback to receive delivery failures without letting them surface as exceptions in your application code:
on_error handler receives one of two exception types:
peeng.PeengApiError— the server responded with an HTTP error envelope. Carriesstatus_code,message, anderror(from the server envelope). Raised for non-retryable errors (e.g.400) or after retries are exhausted (e.g. repeated5xx).requestsexception — a network-level failure with no HTTP response at all (DNS failure, connection refused), surfaced after retries are exhausted.
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.