first commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# OTel instruments — `@suaveplan/api-auth-bearer-static`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
The telemetry module owns the single OpenTelemetry counter this package
|
||||
emits — `api.auth.bearer_static_match_total` — partitioned by the
|
||||
documented `outcome` attribute. Every call to a resolver's `resolve()`
|
||||
method increments this counter exactly once with one of four label values.
|
||||
|
||||
The instrument is bound lazily against `metrics.getMeter(...)` so the
|
||||
package is safe to import on the cold path before the host installs a
|
||||
`MeterProvider`. Resetting the cached bundle (via
|
||||
`resetBearerStaticInstruments`) is required in test setup to bind against
|
||||
a freshly-installed in-memory exporter.
|
||||
|
||||
## Features
|
||||
|
||||
- Single counter — `api.auth.bearer_static_match_total`.
|
||||
- Four `outcome` label values: `match`, `no-token`, `unknown-token`,
|
||||
`mtls-required`.
|
||||
- Lazy meter resolution — module load does not trigger an OTel side
|
||||
effect.
|
||||
- Idempotent reset hook for test isolation.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { recordMatchOutcome } from "@suaveplan/api-auth-bearer-static/src/telemetry";
|
||||
|
||||
// Inside a resolver's resolve() body:
|
||||
recordMatchOutcome("unknown-token");
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
getBearerStaticInstruments,
|
||||
resetBearerStaticInstruments,
|
||||
} from "@suaveplan/api-auth-bearer-static/src/telemetry";
|
||||
|
||||
// In a vitest setup file that has installed an in-memory MeterProvider
|
||||
// upstream:
|
||||
beforeEach(() => {
|
||||
resetBearerStaticInstruments();
|
||||
});
|
||||
|
||||
it("emits the outcome attribute we expect", async () => {
|
||||
const inst = getBearerStaticInstruments();
|
||||
inst.matchTotal.add(1, { outcome: "match" });
|
||||
// ...then flush + assert on the exporter
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `interface BearerStaticInstruments { matchTotal: Counter }`
|
||||
- `type BearerStaticMatchOutcome = "match" | "no-token" | "unknown-token" | "mtls-required"`
|
||||
- `getBearerStaticInstruments(): BearerStaticInstruments`
|
||||
- `resetBearerStaticInstruments(): void`
|
||||
- `recordMatchOutcome(outcome: BearerStaticMatchOutcome): void`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The instrument name uses dotted notation per OpenTelemetry semantic
|
||||
conventions; the attribute key is `outcome` rather than the host-wide
|
||||
`auth.outcome` since this counter is adapter-scoped and dashboards aggregate
|
||||
across adapters by metric name, not attribute. The `description` field is
|
||||
human-readable only — OTel collectors do not interpret it. The cached bundle
|
||||
exists per process and is intentionally global; resolvers do not own
|
||||
instruments because every concrete resolver in a chain would otherwise
|
||||
double-publish the same counter under the same scope.
|
||||
Reference in New Issue
Block a user