ADR-0018: Telemetry through the OpenTelemetry API¶
Status: Accepted Date: 2026-10-12 Deciders: Alex Nodeland
Context¶
Lattice RFC-0001 asks for spans for checks over a threshold, counters of allowed and refused checks by action, and a copy of each audit event in telemetry. The libraries record through the OpenTelemetry API, the port, and configure no SDK.
Decision¶
- grantr records through the API only, under the
grantrscope, and needs no extra; with no SDK configured, recording is a no-op. grantr.checkscounts checks bygrantr.action,grantr.outcomeand, for a refusal,grantr.reason(unknown_action,no_grantorstore_unreadable). An action in no catalog is counted asunknown, so a caller of/checkscan't add series by asking about made-up actions. Tenants and subjects are never metric attributes.- A check slower than
slow_check(50 ms by default) is a span,grantr.check, recorded after it ends, from when it started, with its tenant and the action as asked. A fast check leaves no span. - Each audit entry is logged as JSON at the info level on the
grantr.auditlogger, once its change commits, so the stack's logs hold a copy.
Options considered¶
| Option | For | Against |
|---|---|---|
| A span only for a slow check (chosen) | What the RFC asks; checks stay cheap | A slow check's span starts in the past |
| A span for every check | Every check in traces | A span per command and read on every surface |
| Audit entries as log records (chosen) | The stack's logs collect them with no SDK in grantr | Not a trace |
Consequences¶
- Easier: a dashboard shows refusals by action and reason without a cardinality surprise.
- Harder: an action from a large custom catalog is still one series per action.