3.6 KiB
otel
(no submodules)
Purpose
otel.ts wires the @suaveplan/drive-cache meter and tracer used by every middleware intercept in @suaveplan/drive-plugin-cache. It exposes lazily-built getInstruments(), a setDriveCacheMeterProvider override (so tests can inject a stub provider), resetInstruments() for inter-test isolation, and five recordX helpers that pair a counter increment with a single short-lived span carrying the canonical drive.cache.* attributes.
The instruments are cached after the first call and rebuilt only when the provider override changes or resetInstruments() is called. This avoids re-creating instrument handles on the hot read path while still letting tests drive their own provider.
Features
drive_cache.hits_total{namespace}/misses_total{namespace}/populations_total{namespace}/invalidations_total{namespace}counters.drive_cache.errors_total{namespace, op}counter —op ∈ {"get", "set", "delete"}.drive_cache.entry_bytes{namespace}histogram observed on every population.- One-span-per-event spans with
drive.cache.namespace,drive.cache.path, anddrive.cache.outcome ∈ {"hit", "miss", "populated", "invalidated", "error"}attributes. setDriveCacheMeterProvider(provider)resets the cached instruments so tests can swap providers between cases.
Usage: Basic
import { recordHit, recordMiss, recordPopulate } from "@suaveplan/drive-plugin-cache/otel";
recordMiss("drive", "clip.mov");
recordPopulate("drive", "clip.mov", 4096);
recordHit("drive", "clip.mov");
Usage: Advanced
import {
setDriveCacheMeterProvider,
resetInstruments,
recordError,
} from "@suaveplan/drive-plugin-cache/otel";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
const provider = new MeterProvider();
setDriveCacheMeterProvider(provider);
recordError("drive", "set", "clip.mov");
// run assertions on provider's metric readers
setDriveCacheMeterProvider(undefined);
resetInstruments();
API Reference
| Export | Shape | Description |
|---|---|---|
getInstruments(force?) |
() => DriveCacheInstruments |
Lazy accessor; pass true to force-rebuild. |
resetInstruments() |
() => void |
Clear the cached bag (test-only). |
setDriveCacheMeterProvider(provider) |
(p?: MeterProvider) => void |
Swap the meter provider; auto-resets the cache. |
recordHit(namespace, path) |
(string, string) => void |
Increment hits + emit outcome="hit" span. |
recordMiss(namespace, path) |
(string, string) => void |
Increment misses + emit outcome="miss" span. |
recordPopulate(namespace, path, byteLength) |
(string, string, number) => void |
Increment populations + observe entry size + emit outcome="populated" span. |
recordInvalidate(namespace, path) |
(string, string) => void |
Increment invalidations + emit outcome="invalidated" span. |
recordError(namespace, op, path) |
(string, "get" | "set" | "delete", string) => void |
Increment errors + emit outcome="error" span with op attribute. |
Implementation Notes
Spans are created via tracer.startSpan(...).end() rather than tracer.startActiveSpan(...). The middleware does its own work inside the calling async flow; the only purpose of these spans is to carry the outcome attribute for trace-backed analysis. Long-lived active spans would force every middleware intercept to thread an OpenTelemetry.Context, which is overkill for a cache event. Counter attribute bags are constructed inline as plain objects — V8 inlines this allocation on the hot path so the impact is undetectable.