roz-logs
Structured logging for Python with optional OpenTelemetry (OTLP) export to providers like Seq.
roz-logs is a thin, dependency-free wrapper over the standard library
logging module. It gives you:
- Structured fields — pass
key=valuepairs to any log call, rendered as readablekey=valuetext or as JSON. - Context binding —
log.bind(device="pi-01")returns a child logger that stamps every record with that context. - One-call setup —
configure()installs handlers/formatters and reads sensible defaults from environment variables. - Opt-in cloud export — set
ROZ_LOGS_OTLP_ENDPOINTto ship logs to any OTLP/HTTP collector (Seq, Grafana, an OpenTelemetry Collector, …). With no endpoint set, it logs to the console and has zero heavy dependencies — ideal for offline/embedded use such as the Raspberry Pi card sorter.
Install
pip install roz-logs # console logging, no extra deps
pip install "roz-logs[otlp]" # + OpenTelemetry OTLP export
Usage
from roz_logs import configure, get_logger
configure(service_name="card-sorter") # call once at startup
log = get_logger(__name__)
log.info("sorted card", card="Black Lotus", bin=3)
# 2026-06-24T19:40:00+00:00 INFO [card-sorter] __main__: sorted card card="Black Lotus" bin=3
job = log.bind(job_id="abc123") # bound context
job.warning("reject bin full", bin=9)
try:
risky()
except Exception:
log.exception("operation failed", op="sort") # includes traceback
JSON output (great for log shippers):
configure(service_name="card-sorter", json_output=True)
# {"timestamp": "...", "level": "INFO", "service": "card-sorter", "logger": "...", "message": "sorted card", "card": "Black Lotus", "bin": 3}
Configuration
Every configure() argument falls back to an environment variable, so you can
deploy without touching code:
| Argument | Environment variable | Default |
|---|---|---|
service_name |
ROZ_LOGS_SERVICE_NAME |
app |
level |
ROZ_LOGS_LEVEL |
INFO |
json_output |
ROZ_LOGS_JSON |
false |
otlp_endpoint |
ROZ_LOGS_OTLP_ENDPOINT |
(unset → console only) |
otlp_headers |
ROZ_LOGS_OTLP_HEADERS |
(unset) |
ROZ_LOGS_JSON accepts any of 1, true, yes, on (case-insensitive) to
switch from the human-readable TextFormatter to the line-delimited
JsonFormatter; anything else keeps text output.
OTLP export (shipping to Seq and other collectors)
The core library has zero runtime dependencies and only ever writes to the
console. Cloud/collector export is opt-in through the otlp extra, which pulls
in the OpenTelemetry SDK and the OTLP/HTTP log exporter:
pip install "roz-logs[otlp]"
Once installed, setting an OTLP endpoint makes configure() attach a second
handler (in addition to the console) that batches log records and exports them
over OTLP/HTTP:
export ROZ_LOGS_OTLP_ENDPOINT="http://localhost:5341/ingest/otlp/v1/logs"
export ROZ_LOGS_OTLP_HEADERS="X-Seq-ApiKey=<your-api-key>"
Under the hood build_otlp_handler() wires up an OpenTelemetry
LoggerProvider (tagged with service.name = your service_name), a
BatchLogRecordProcessor, and an OTLPLogExporter pointed at your endpoint,
then returns a stdlib logging.Handler bridging the two. Records flow:
log.info(...) → stdlib logging → OTLP LoggingHandler → BatchLogRecordProcessor
→ OTLPLogExporter (HTTP) → Seq / OTel Collector / Grafana / …
For Seq the endpoint is
http://<host>:5341/ingest/otlp/v1/logs and the API key travels in a header
(X-Seq-ApiKey). Any OTLP/HTTP logs endpoint works the same way.
Graceful degradation: if you request an endpoint but the otlp extra is
not installed, roz-logs logs a warning and keeps console logging working
rather than crashing — so the same code runs on a constrained device (console
only) and a server (console + OTLP) with no changes.
Development
pip install pytest pytest-cov
pytest # runs unit tests with a 90% coverage gate
# to exercise the OTLP code paths, install the extra into your test env:
pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
License
MIT
Metadata
Release files for roz-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)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| roz_logs-0.1.0.tar.gz | 12.1 kB | Without provenance | Details for roz_logs-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| roz_logs-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for roz_logs-0.1.0-py3-none-any.whl |
Total release size: 25.7 kB
Release files / roz_logs-0.1.0.tar.gz
| Download URL | roz_logs-0.1.0.tar.gz |
|---|---|
| Size | 12.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b2b25e5ace8587b158ff854040a15cde3a04e42a193c39255f082879bc4ea74e
|
|
BLAKE2b-256 checksum How to use checksums |
97bc08a3361314670063e881cb716ca60f558d40706546d78bf95d836de98d75
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.04","id":"plucky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / roz_logs-0.1.0-py3-none-any.whl
| Download URL | roz_logs-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c95e4ab25fd9fd543241fe9b2b5d5a1e1ef586049a67567862afbe6b64a9fa5
|
|
BLAKE2b-256 checksum How to use checksums |
d8bf0b7ca71322175c941d013b70feac87daeb98d96a348eab502eefd0bda6ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.04","id":"plucky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for roz-logs 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.