2.9 KiB
otel/instruments
(no submodules)
Purpose
Wires the package's OpenTelemetry metrics surface and exposes a thin
instrument(op) helper the adapter wraps around every CRUD method. The
helper records one counter point (with outcome: "success" | "error")
plus one histogram observation per call, so dashboards can pivot on
model/operation/outcome and also see the per-operation latency
distribution.
Features
better_auth.surrealdb.operations_totalcounter — attributes:model,operation,outcome.better_auth.surrealdb.operation_duration_mshistogram — attribute:operation.- Lazy meter resolution: the meter and instruments are constructed on
first use (not at module load) so tests can install a real
MeterProviderviasetGlobalMeterProviderbefore the adapter begins issuing operations. - Universal: uses
performance.now()when available, falls back toDate.now()when running under bundlers that stripperformance. resetInstrumentsForTesting()clears the lazy cache so a re-imported test environment resolves the new provider.
Usage: Basic
import { instrument } from "@suaveplan/better-auth-surrealdb/otel";
const row = await instrument({
model: "session",
operation: "create",
run: async () => insertSessionRow(),
});
Usage: Advanced
import { instrument } from "@suaveplan/better-auth-surrealdb/otel";
import { metrics } from "@opentelemetry/api";
import { MeterProvider, PeriodicExportingMetricReader, InMemoryMetricExporter, AggregationTemporality } from "@opentelemetry/sdk-metrics";
// Install provider BEFORE first instrument() call:
const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
const reader = new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 60_000 });
const provider = new MeterProvider({ readers: [reader] });
metrics.setGlobalMeterProvider(provider);
await instrument({ model: "user", operation: "findOne", run: async () => ({ ok: true }) });
await provider.forceFlush();
const collected = exporter.getMetrics();
API Reference
instrument<T>(op): Promise<T>— wraps a() => Promise<T>with counter + histogram observations; rethrows on failure.InstrumentedOp<T>—{ model: string; operation: string; run: () => Promise<T> }.AdapterOutcome—"success" | "error".resetInstrumentsForTesting()— invalidates the lazy cache.
Implementation Notes
The lazy-init pattern is critical: importing OTel metrics at module load
returns a noop meter unless setGlobalMeterProvider has been called by the
host. Caching the meter+instruments after first use keeps subsequent calls
allocation-free. performance.now() is preferred for sub-millisecond
resolution but Date.now() is a correct fallback because the histogram
records millisecond observations regardless.