3.0 KiB
observability/metrics
Purpose
OpenTelemetry meter + instrument registry for @suaveplan/crypto-rsa. Stage 1
defines the full instrument set the proposal pins (so dashboards and SLOs can
be authored ahead of Stages 2-4) and wires up the parse/serialise duration
histograms and the typed-error counter — the only paths that have a hot
production call site at this stage.
The instruments are lazily constructed on first use to keep the module
import-side-effect-free; this matters because some downstream consumers
import the package without ever installing a MeterProvider, and constructing
real instruments against the no-op global meter is harmless but unnecessary.
Features
- Lazy
meter()andinstruments()accessors — first access constructs, subsequent accesses reuse cached instruments. resetMetricsForTesting()— drops the caches so a freshMeterProviderinstalled by a test takes effect.recordParseDuration(format, ms),recordSerializeDuration(format, ms),recordError(code)— production helpers wrapping the instrument calls.getInstrumentsForTesting()— exposes the bag for test assertions.- Full instrument set (8 histograms + 6 counters) declared up-front so the metric names cannot drift between Stages.
Usage: Basic Example
import {
recordError,
recordParseDuration,
} from "@suaveplan/crypto-rsa/observability";
const start = performance.now();
try {
parse();
recordParseDuration("pkcs1", performance.now() - start);
} catch (error) {
recordError(error.code);
throw error;
}
Usage: Advanced Example
import {
getInstrumentsForTesting,
resetMetricsForTesting,
} from "@suaveplan/crypto-rsa/observability";
import { metrics } from "@opentelemetry/api";
import { MeterProvider } from "@opentelemetry/sdk-metrics";
resetMetricsForTesting();
metrics.setGlobalMeterProvider(new MeterProvider({ readers: [reader] }));
const bag = getInstrumentsForTesting();
// bag.errorsTotal, bag.outcomeTotal, …
API Reference
recordParseDuration(format: string, durationMs: number): voidrecordSerializeDuration(format: string, durationMs: number): voidrecordError(code: string): voidresetMetricsForTesting(): voidgetInstrumentsForTesting(): InstrumentBag
The instrument bag carries (counters): errorsTotal, outcomeTotal,
engineSelectedTotal, fingerprintTotal, profileViolationTotal,
blindingDisabledTotal; (histograms): verifyDurationMs, signDurationMs,
encryptDurationMs, decryptDurationMs, keygenDurationMs,
modpowDurationMs, parseDurationMs, serializeDurationMs.
Implementation Notes
The instruments are declared even though most are not yet wired into production paths because the proposal pins them as the canonical observable surface; declaring them lets dashboards reference the metric names by build time, not by feature-arrival time, and prevents naming drift when Stages 2-4 wire them up.
resetMetricsForTesting is the documented seam for swapping
MeterProviders under test. Production code should never call it.