3.3 KiB
OpenTelemetry wiring
(no submodules)
Purpose
otel.ts exposes the tracer, meter, and instrument bag that every read
path in @suaveplan/storage-uri-plugin-bundle records against. It mirrors
the convention used by @suaveplan/storage-uri/otel and
@suaveplan/storage-plugin-cache/otel: lazy instrument acquisition,
test-injectable MeterProvider, and a single recordOp entry point that
emits the histogram, the success/error counter, and the per-op span in one
call so the call site never forgets one of the three.
The module also carries the small helpers that the rest of the package
relies on for span-attribute hygiene: sanitiseRelPathAttr strips
query strings and truncates to 256 chars, and classifyRootKind maps
a URL to the file | http | data | blob | other label used on every
span and counter.
Features
bundle_uri.op_duration_ms{op, root_kind, outcome}histogram.bundle_uri.reads_total{root_kind, outcome}counter.bundle_uri.errors_total{root_kind, code}counter.bundle_uri.range_fallback_total{root_kind}counter.bundle_uri.cache_hits_total{root_kind}andbundle_uri.cache_misses_total{root_kind}counters.- Per-op span on the
@suaveplan/storage-uri-plugin-bundletracer withbundle.package,bundle.rel_path,bundle.root_kind,bundle.outcomeattributes. setBundleUriMeterProvider(provider)+resetInstruments()for deterministic test injection.
Usage: Basic
import { recordOp } from "@suaveplan/storage-uri-plugin-bundle";
recordOp({
op: "get",
rootKind: "http",
outcome: "success",
durationMs: 12,
packageSlug: "my-pkg",
relPath: "assets/x.wav",
});
Usage: Advanced
import {
setBundleUriMeterProvider,
resetInstruments,
} from "@suaveplan/storage-uri-plugin-bundle";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
const provider = new MeterProvider({});
setBundleUriMeterProvider(provider);
resetInstruments();
// …run instrumented code, then drain `provider` to read observations.
API Reference
getInstruments(force?)— lazy-build the bag;force=truerebuilds.setBundleUriMeterProvider(provider | undefined)— test injection.resetInstruments()— drop the cached bag.recordOp(input)— one-call emission of histogram + counter + span.recordRangeFallback(rootKind)— increment fallback counter.recordCacheHit(rootKind)/recordCacheMiss(rootKind)— cache-path counters.sanitiseRelPathAttr(relPath)— strip query + truncate to 256 chars.classifyRootKind(rootUrl)—URL→BundleUriRootKind.BundleUriOp,BundleUriOutcome,BundleUriInstruments,RecordOpInput— supporting types.
Implementation Notes
The instrument bag is held in a module-private let so the same
instruments persist across calls. resetInstruments is the test-only
escape hatch that drops the cache so the next getInstruments rebinds
against the freshly-installed MeterProvider. The 256-char clip is
applied after the query strip — query-string lengths are not counted
against the attribute size budget. classifyRootKind is a switch over
URL.protocol (which always ends with :); the default case covers
bundler-virtual schemes (virtual:, ~asset:, \0…) so coverage
includes the "other" branch.