Skip to main content

e-volv-logs

Evolve Log Manager SDK for Python — batched log shipping, trace context and error capture against the Evolve ingest endpoint (POST /api/public/v1/logs). Companion: the Node.js SDK @e-volv/logs.

Python 3.10+.

pip install e-volv-logs

Quick start

import e_volv_logs as evolve_logs
from e_volv_logs import init, log, span, trace

init(
    key="evk_…",  # project ingest key
    url="https://your-host/api/public/v1/logs",
    service="api",
    environment="production",
    release="1.4.2",
)

log.info("order created", {"orderId": "o_1", "total": 42.5})
log.error("payment failed", {"orderId": "o_1"})

try:
    await charge()
except Exception as err:
    log.exception(err, {"orderId": "o_1"})  # exception.type/message/stack

# Traces live in contextvars — they flow across await. httpx/requests
# requests made inside a trace get a W3C traceparent header automatically.
with trace():
    with span("db.query", {"table": "orders"}):
        await db.query("SELECT …")
    await httpx.get("https://internal/svc")  # traceparent injected

If key or url is missing, init() returns a no-op client and warns once. The SDK never raises into user code.

Batching, retries, drops

  • Flushes at 200 events, 2 s (age of the oldest buffered event), or a 512 KB payload — whichever comes first. Bodies are gzipped (Content-Encoding: gzip).
  • 429 retries with exponential backoff (0.5 s doubling, capped at 10 s), up to 3 attempts. 413 halves the batch and retries.
  • When the pending buffer exceeds 2× batch size, the oldest events are dropped; losses are visible on client.dropped.
  • atexit flushes whatever is pending.

Options

init(key=, url=, service=, environment=, release=, redact_keys=[...], sample_rate=1.0, capture_excepthook=True) — redact_keys are merged into the backstop regex password|secret|token|authorization|cookie|set-cookie|api[-_]?key (case-insensitive), applied to attrs before queueing.

stdlib logging

import logging
from e_volv_logs import init, LogHandler

init(key="evk_…", url="…", service="api")
logging.getLogger("myapp").addHandler(LogHandler())

Levels map to OTel severities (DEBUG→5, INFO→9, WARNING→13, ERROR→17, CRITICAL→21). extra={...} on the log call becomes event attrs; exc_info becomes exception.* fields. sys.excepthook capture is on by default.

FastAPI / Starlette

from e_volv_logs.integrations.fastapi import EvolveLogsMiddleware

app.add_middleware(EvolveLogsMiddleware)  # one root span per request

The middleware continues the trace when the inbound request carries an x-evolve-traceparent header (Evolve backend → evolve-ai propagation), otherwise starts a fresh root trace.

LangChain and LangGraph

pip install "e-volv-logs[langchain]"
from e_volv_logs.integrations.langchain import EvolveLogsCallbackHandler

result = graph.invoke(
    {"question": "…"},
    config={"callbacks": [EvolveLogsCallbackHandler()]},
)

One span per LangChain run, nested by parent_run_id, all sharing one trace — so a LangGraph node's tool calls and model calls appear inside the node on the Evolve trace graph. Span names:

Callback Span name
on_chain_start with langgraph_node graph.<node>
on_chain_start otherwise chain.<name>
on_tool_start tool.<name>
on_llm_start / on_chat_model_start llm.<model>

Errors end the span through _log_span_error (severity error, exception.* attrs), exactly like span() raised inside a body.

Queue hops

A span on the consumer side joins the producer's trace only if the traceparent travels with the job:

from e_volv_logs import run_with_traceparent, span, traceparent

# producer
queue.enqueue(work, payload, trace=traceparent())

# consumer: the body runs as a new hop of the producer's trace.
with run_with_traceparent(job.trace), span("queue.work", {"queue": "work"}):
    handle(job)

run_with_traceparent(header) parses a W3C traceparent; an absent or malformed header starts a fresh trace, so a producer that sends nothing still yields a trace of its own.

Development

cd packages/logs-py
uv sync
uv run pytest tests/ -q

Metadata

Release files for e-volv-logs 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for e-volv-logs 0.1.0
File Size Uploaded
e_volv_logs-0.1.0.tar.gz 135.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for e-volv-logs 0.1.0
File Interpreter ABI Platform
e_volv_logs-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 151.8 kB

Release files / e_volv_logs-0.1.0.tar.gz

Download URL e_volv_logs-0.1.0.tar.gz
Size 135.6 kB
Tags Source
SHA-256 checksum
How to use checksums
39ad1f8cacd47514f2b0d05629eb713ed2d46cab917cfa192097a31b77df9fb3
BLAKE2b-256 checksum
How to use checksums
f2504ce9853ccfe77feed43d77f539e6f4468d450eb596937978177160cb68bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.0

Release files / e_volv_logs-0.1.0-py3-none-any.whl

Download URL e_volv_logs-0.1.0-py3-none-any.whl
Size 16.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
171e3273bdcd917153d5171a68d22f2456d3216e836555d6fc2c5c98b37343bd
BLAKE2b-256 checksum
How to use checksums
2fc885cbf0beec3d7c43f3b7143f831820ee8717c7a8f5803ea1e9d0ada6ae6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.0

Release history Release notifications | RSS feed

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page