OTLP-native observability for agent stacks. Beacon receives OpenTelemetry traces and logs from your agent, your sandbox, your egress proxy — every reasoning step, every tool call, every container exec — into a tamper-evident ledger you can query, tail, or replay. When something's wrong, you see it.
Six primitives. One endpoint. Speaks the OpenTelemetry wire protocol so anything OTEL-instrumented works without code changes.
Receives the OpenTelemetry standard wire protocol (OTLP/HTTP/JSON) at /v1/traces and /v1/logs. Any OTEL SDK works — set OTEL_EXPORTER_OTLP_ENDPOINT and you're done.
Each event holds the SHA-256 of the previous one. Tamper with any line and the chain breaks visibly. beacon verify re-walks today's chain and reports the first break.
Server-Sent Events stream of every new span and log line. beacon tail --since 5m --service fathom for the CLI; web UI subscribes the same way.
beacon trace <id> reconstructs one agent turn from a single trace ID: every iteration, every tool call, every container exec, every credentialed egress request, laid out as a timeline.
Storage is one append-only JSONL file per UTC day. Grep-friendly, jq-friendly, bulk-export trivial. Swap for ClickHouse / Loki / S3+Parquet via one interface when you outgrow it.
OTLP standard for ingest. Tiny native API for query + tail. Tiny Go SDK in pkg/sdk/go for harnesses that want tight integration. Everything else: curl.
Standalone Go binary. Listens on the OTLP/HTTP default port.
# Clone + build
$ git clone https://github.com/darklake-ai/beacon
$ cd beacon && go build -o beacon ./cmd/beacon
# Start the receiver + API
$ ./beacon serve
Auto-generated access token lands at ~/.beacon/token. Listens on 127.0.0.1:4318.
# Stream every new span + log to stdout
$ ./beacon tail --since 5m
# Replay one trace
$ ./beacon trace 0123abcd...
# Verify today's hash chain
$ ./beacon verify
CLI uses the same token + API any other client would use.
Beacon is just an OTLP/HTTP receiver. Any service or library that emits OTLP traces or logs can ship to it. Fathom, Chasm, Charon, your custom harness, off-the-shelf OTEL SDKs — all the same.
One config block. Fathom emits one span per agent iteration, with tool calls + LLM requests as child spans.
Container execs + credentialed egress requests appear as spans on the same trace as the originating agent iteration.
Python, Java, Node, .NET, Rust — set OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318, you're done.
Already running an OTEL Collector? Add a otlphttp exporter pointing at Beacon and fan out from there.
Open source. MIT-licensed. Built to bolt on, not lock in.