Qx observability: structlog logging, OpenTelemetry tracing, Prometheus metrics, health probes
Project description
qx-observability
One-call observability setup for Qx services — structured logging (structlog), distributed tracing (OpenTelemetry), Prometheus metrics, and health probes.
What lives here
qx.observability.setup_observability— configures logging and tracing, returns a(Metrics, HealthRegistry)pair. This is the only call most services need.qx.observability.Metrics— Prometheus counter/histogram wrapper. Pass a customCollectorRegistryin tests to avoid collisions.qx.observability.HealthRegistry— register named health checks; aggregates their results for/healthzand/readyz.qx.observability.configure_logging— structlog pipeline with JSON output in production and pretty console output in development.qx.observability.configure_tracing— OpenTelemetry SDK setup; exports to an OTLP endpoint (Tempo, Jaeger, etc.) or console.qx.observability.get_logger— returns a bound structlog logger for a given name.qx.observability.get_tracer— returns an OTelTracer; use withtrace_span.qx.observability.trace_span— async context manager that wraps a block in an OTel span.qx.observability.inject_context/extract_context— propagate trace context through message headers (W3C TraceContext format).qx.observability.MetricsBehavior/TracingBehavior— Mediator pipeline behaviors that instrument every command/query automatically.
Usage
from qx.observability import setup_observability
# In application bootstrap
metrics, health = setup_observability(
settings,
otlp_endpoint="http://tempo:4317",
)
# Register a health check
@health.check("database")
async def _db_check() -> bool:
return await db.ping()
# In any module
from qx.observability import get_logger, trace_span
log = get_logger(__name__)
async def do_work() -> None:
async with trace_span("my-operation"):
log.info("doing work", key="value")
Mediator pipeline wiring
from qx.cqrs import compose
from qx.observability import MetricsBehavior, TracingBehavior
pipeline = compose(
TracingBehavior(get_tracer("mediator")),
MetricsBehavior(metrics),
)
mediator = Mediator(container, pipeline=pipeline)
Design rules
- Logging is structured (key-value) everywhere — no f-string log messages in framework code.
setup_observability()is idempotent in tests when a freshCollectorRegistryis passed viametrics_registry.- Trace context is propagated automatically via
RequestContextMiddlewareon ingress andinject_contexton egress (outbox relay, NATS publisher).
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
qx_observability-1.0.0.tar.gz
(11.7 kB
view details)
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 qx_observability-1.0.0.tar.gz.
File metadata
- Download URL: qx_observability-1.0.0.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c76dfd6de4dd9f8d889266248fd12eee9e2a050d1cc884668326b688c46aefb4
|
|
| MD5 |
41c4160e64b48cc38435a257a9c8e798
|
|
| BLAKE2b-256 |
ef4881c73a07cd3978c1d1f59da3913acf45c803eca9285735ac6877010a6fcf
|
File details
Details for the file qx_observability-1.0.0-py3-none-any.whl.
File metadata
- Download URL: qx_observability-1.0.0-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a129c02e5e26667619a85642aaa0c203f1f77d76b36e7ba973851ed66d398199
|
|
| MD5 |
5abdd5eb218d1fab11e5c30c0a3fe41b
|
|
| BLAKE2b-256 |
cbe7927001fa0fc31415109b990b32ebcc5b60fe050a587acef66433db2b9a71
|