A thread-safe, asynchronous observability toolkit for Python.
Project description
sentinel-trace
A thread-safe, asynchronous observability toolkit for Python. Drops structured JSONL logs to disk from a background worker so your hot path stays fast.
Install
pip install sentinel-trace
Usage
from sentinel import AsyncLogger, SentinelConfig, TimeBlock, trace
logger = AsyncLogger(SentinelConfig(log_file="app.jsonl"))
@trace(logger)
def fetch_user(user_id: int) -> dict:
...
@trace(logger, label="checkout") # group records under a domain term
def run(order_id: int) -> None:
...
@trace(logger)
async def fetch_user_async(user_id: int) -> dict:
...
def crunch():
with TimeBlock(logger, label="data_crunching"):
...
logger.flush() # block until queue drained
logger.shutdown() # idempotent; also runs at interpreter exit
@trace() (no args) uses a process-wide default logger that writes to
sentinel_logs.jsonl in the working directory.
Log format
One JSON object per line:
{"timestamp": "2026-04-29T17:00:00+00:00", "function": "fetch_user", "duration_ms": 12.3, "status": "success", "error_type": null}
When @trace is given a label, it's appended to the function name in brackets:
{"timestamp": "2026-04-29T17:00:00+00:00", "function": "run[checkout]", "duration_ms": 12.3, "status": "success", "error_type": null}
When to use this — and when not to
Sentinel is a thin, single-process, file-backed timing logger. Pick it when:
- You want microsecond-overhead
@trace/TimeBlockon a service or batch job. - You're happy to grep /
jq/ load JSONL into DuckDB or pandas after the fact. - You don't want to operate an OpenTelemetry collector, Datadog Agent, or Prometheus exporter for this workload.
Reach for something else when:
- You need distributed tracing across services with span propagation — use OpenTelemetry.
- You need real-time metrics with PromQL queries — use Prometheus + a metrics library.
- You need full-fidelity APM (DB query plans, code-level profiling, user-session replay) — that's what Datadog / New Relic / Sentry exist for.
Known limitations
- No log rotation. The file grows unbounded. Use
logrotateexternally or pass a date-stampedlog_filepath. - No multi-process aggregation. Each process writes its own file. If
multiple processes share a
log_file, writes are not arbitrated — one of them will lose lines. - Worker self-heal does not auto-restart. I/O failures are detected and
surfaced via
logger.is_healthy(); the worker refuses further records rather than silently dropping them. Restart the process to recover. - No backpressure by default (
enqueue_timeout=0.0). Saturating the queue drops records with a warning. Setenqueue_timeout > 0if you'd rather block producers than drop. - No trace ID / span propagation, no automatic argument capture, no resource (memory/CPU) metrics yet — see the roadmap.
Operational tips
- Call
logger.flush(timeout=...)before forking or before invoking external processes that depend on the log being on disk. - Catch
is_healthy() == Falsein long-running services and alert / restart. - For high-throughput services, increase
max_queue_sizeproportionally to your peak per-second log rate × peak worker write latency.
Development
pip install -e ".[dev]"
ruff check sentinel tests examples
ruff format --check sentinel tests examples
mypy sentinel
bandit -r sentinel -ll
pytest --cov=sentinel --cov-report=term-missing
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 sentinel_trace-0.1.0.tar.gz.
File metadata
- Download URL: sentinel_trace-0.1.0.tar.gz
- Upload date:
- Size: 14.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
850a9a79b7ca705ec8d93ae29492dbe298d8e120c6fe7aaa676b8ec5e539450e
|
|
| MD5 |
d5991e730e95e80e80e6ccc58afe279f
|
|
| BLAKE2b-256 |
9768a5ef2a8bfa431975d6125b8abe5d1789174325150dd636fe937af30a57fb
|
File details
Details for the file sentinel_trace-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sentinel_trace-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80abe776f3988b34a0ebfc3b1677a3241132ae86c4952acc8c94b5e594d9fe57
|
|
| MD5 |
2e4f20357be57d57a0de4a8b93dc5987
|
|
| BLAKE2b-256 |
c14f4b522aec7f7a22b4ccc4e4b1ef199b04c6a7e53c9cdf827d00ec6b3549a4
|