CHIME/FRB telemetry wrapper around HelixObs — traces and logs via OTLP.
Project description
CHIME Logger
CHIME Logger is a CHIME/FRB telemetry wrapper around HelixObs. It ships traces and logs to the HelixObs herald via OTLP, writes a local rotating file log, and automatically injects CHIME context (resource_name, resource_type, pipeline, site) into every log record — without any boilerplate.
How it works
CHIME Logger wraps the HelixObs Python client with a CHIME-specific CHIMETracer. When you enter an operate() or create() block, the tracer stamps the span with CHIME attributes (chime.resource_type, chime.pipeline, chime.site). A log-record factory — installed at the root logger level, the same way HelixObs injects trace context — reads those attributes from the active span and stamps them onto every LogRecord at creation time, before any handler sees it. This means any logger in the process automatically carries resource_name, resource_type, pipeline, and site inside an operate() or create() block, regardless of its name.
Spans flow to the HelixObs herald, which writes entity rows to TimescaleDB, links provenance, and drives notifications and dashboards. See the HelixObs documentation for the full entity model, provenance DAG, and herald architecture.
Installation
pip install chime_logger
# or
poetry add chime_logger
# or
uv add chime_logger
Usage
Setup
Call setup() once at process start. It returns a CHIMETracer singleton wired to the HelixObs herald.
import chime_logger
import logging
tel = chime_logger.setup(pipeline="datatrail-registration")
log = logging.getLogger(__name__) # any logger name works
Logger name: you can use any logger —
logging.getLogger(__name__),logging.getLogger("CHIME"), or anything else. CHIME context fields are injected at record-creation time via a root-level factory, so the name does not matter for context enrichment or OTLP log shipping. The only distinction is that records from loggers named"CHIME"or"CHIME.*"are also written to the local rotating file.
Creating new entities — create()
Use create() when a new entity enters the pipeline for the first time — a new beam candidate, a new baseband acquisition, a new FRB event. This registers the entity in the HelixObs provenance DAG, making it discoverable in the Entity Inspector and linkable to its parents.
with tel.create("l1-search", resource_name=beam_id, resource_type="n2_acquisition", parents=[block_id]) as token:
log.info("Processing beam") # resource_name, resource_type, pipeline, site auto-injected
parents links this entity to its upstream origins. The herald resolves those links into a navigable provenance DAG — so you can trace an FRB event back to the raw data block it came from. See the HelixObs provenance guide for details.
Processing existing entities — operate()
Use operate() when performing a pipeline stage on an entity that already exists — registering it in a catalog, replicating its data, converting its format. Each operate() call creates an operation row in HelixObs, giving you a timestamped history of every stage an entity passed through.
with tel.operate("register", resource_name=event_id, resource_type="event") as token:
log.info("Registering event")
register_in_catalog(event_id)
The full operation timeline is visible per-entity in the HelixObs Entity Inspector dashboard.
Marking scientifically notable signals — add_event()
token.add_event() records a named helix event on the entity. Unlike a log line, helix events are stored in a structured entity_events table in TimescaleDB and are queryable across all entities. Use them for domain signals that matter beyond the log stream.
with tel.operate("classify", resource_name=event_id, resource_type="event") as token:
classification = classify(event_id)
token.add_event("helix.event.classified", {"classification": classification, "dm": str(dm)})
Helix events appear in the Entity Inspector's event timeline and can be used to drive notifications (see below).
Recording errors — add_error() and error()
These are not log lines — they are helix error events. When the herald receives a helix.error event, it:
- Marks the entity with
has_error = truein the database. - Surfaces it in the Error Entities Grafana dashboard for immediate visibility.
- Triggers a Slack notification and opens a GitHub issue for diagnosis (if configured for your instrument).
- Deduplicates repeated occurrences and updates the issue body with running statistics rather than spamming a new alert each time.
token.add_error() — records a recoverable error. The span stays open so the operation can continue or attempt recovery.
with tel.operate("replicate", resource_name=event_id, resource_type="event") as token:
for dest in destinations:
try:
replicate_to(dest)
except TimeoutError as e:
token.add_error({"destination": dest, "reason": str(e)})
log.warning(f"Replication to {dest} timed out, continuing")
# span completes normally after the loop
token.error() — records the error and immediately closes the span as failed. Use this when the operation cannot recover.
with tel.operate("register", resource_name=event_id, resource_type="event") as token:
try:
register_in_catalog(event_id)
except Exception as e:
token.error({"reason": str(e)}) # closes span as failed
raise
Note: The context manager calls
token.error()automatically if an unhandled exception escapes thewithblock, so explicittoken.error()is only needed when you want to attach structured metadata to the error.
Child spans
Use child_span() for internal steps that should appear in the Tempo trace view but don't need their own entity row in HelixObs.
with tel.operate("register", resource_name=event_id, resource_type="event") as token:
with tel.child_span("catalog-lookup"):
result = lookup_catalog(event_id)
with tel.child_span("db-write"):
write_to_db(result)
This keeps the Tempo trace detailed without polluting the entity provenance DAG with internal implementation steps.
Automatic log context injection
Inside any operate() or create() block, every log call from any logger in the process automatically carries:
| Field | Source |
|---|---|
resource_name |
helix.entity.id from the active span |
resource_type |
chime.resource_type from the active span |
pipeline |
chime.pipeline from the active span, then CHIME_LOGGER_PIPELINE_NAME |
site |
chime.site from the active span, then CHIME_LOGGER_SITE |
Outside any span, logging still works — context fields fall back to the environment variables above, then to unknown_name / unknown_type / unknown_pipeline / unknown_site.
Accessing the singleton
tel = chime_logger.get_tracer() # None if setup() has not been called yet
Configuration
All connection and site parameters come from environment variables.
| Variable | Default | Description |
|---|---|---|
HERALD_ENDPOINT |
localhost:4317 |
OTLP gRPC address for traces |
LOGS_ENDPOINT |
localhost:4317 |
OTLP gRPC address for logs |
CHIME_LOGGER_SITE |
(unset) | Site name: chime, kko, gbo, hco |
CHIME_LOGGER_PIPELINE_NAME |
(unset) | Pipeline name fallback when not passed to setup() |
CHIME_LOGGER_FILE_LOG_PATH |
logs/chime_pipeline.log |
Path for the rotating file log |
HERALD_INSECURE |
true |
Set to false for TLS connections |
HERALD_CREDENTIAL |
(unset) | Registration secret or existing JWT |
HERALD_AUTH_ENDPOINT |
(unset) | Herald /auth/token URL (required when HERALD_CREDENTIAL is set) |
License
See LICENSE for details.
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 chime_logger-1.1.0.tar.gz.
File metadata
- Download URL: chime_logger-1.1.0.tar.gz
- Upload date:
- Size: 9.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.9.25 Linux/6.17.0-1015-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0422dd616814d4b6e0f537dc71d6357e3858c64633578e47a7bbc4f327034da5
|
|
| MD5 |
09332a263731cae3549a53e13ecaefcf
|
|
| BLAKE2b-256 |
d38b9e3f02d158921b5d6ab53af0d486353085fc9e151e1122cfc54d5a348a88
|
File details
Details for the file chime_logger-1.1.0-py3-none-any.whl.
File metadata
- Download URL: chime_logger-1.1.0-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.9.25 Linux/6.17.0-1015-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2fb42000fa5eecadb240cf5bc238b137f14e523c7d8adcfd5d939b0e8832fc0
|
|
| MD5 |
93c19d8cdfcf83a116652038b2b6e94d
|
|
| BLAKE2b-256 |
cafa4329c068d14d83fe0a0ab7cd4cbc11766ec335c1c9b4593bab655e872864
|