3.0 KiB
otel/metrics — OpenTelemetry instrumentation
(no submodules)
Purpose
metrics.ts registers four OpenTelemetry instruments under the meter name @suaveplan/slack-client and exports the helper functions every production path uses to record observations: recordRequest, recordError, recordWebhook. The module intentionally retrieves the meter once at module load AND exposes refreshSlackMeters() so tests can rewire the meter against a real in-memory MeterProvider after configuring the global provider. This keeps the production hot path free of MeterProvider lookups while still permitting getMetrics() assertions in the test suite.
Features
- Four instruments:
slack.requests(Counter),slack.errors(Counter),slack.latency_ms(Histogram, unitms),slack.webhook_sends(Counter). - Attributes —
{ method, outcome }on requests,{ method, code }on errors,{ outcome }on webhook sends. - Module-load resolution against
metrics.getMeter("@suaveplan/slack-client", "0.1.0"). refreshSlackMeters()for tests to rebind aftermetrics.setGlobalMeterProvider(...).
Usage: Basic
import { recordRequest } from "@suaveplan/slack-client/otel/metrics";
recordRequest("chat.postMessage", "ok", 142);
Usage: Advanced
import { metrics } from "@opentelemetry/api";
import {
AggregationTemporality,
InMemoryMetricExporter,
MeterProvider,
PeriodicExportingMetricReader,
} from "@opentelemetry/sdk-metrics";
import { refreshSlackMeters } from "@suaveplan/slack-client/otel/metrics";
const exporter = new InMemoryMetricExporter(AggregationTemporality.CUMULATIVE);
const provider = new MeterProvider({
readers: [
new PeriodicExportingMetricReader({
exporter,
exportIntervalMillis: 60_000,
}),
],
});
metrics.setGlobalMeterProvider(provider);
refreshSlackMeters();
// ... run code that records ...
await provider.forceFlush();
const observed = exporter.getMetrics();
API Reference
recordRequest(method: string, outcome: "ok" | "error", latencyMs: number): void— incrementsslack.requestsand recordsslack.latency_ms.recordError(method: string, code: string): void— incrementsslack.errors.recordWebhook(outcome: "ok" | "error"): void— incrementsslack.webhook_sends.refreshSlackMeters(): void— re-resolves every instrument against the current global meter provider.
Implementation Notes
The instruments are held in module-scope let bindings (not const) because refreshSlackMeters() rebinds them after a test wires a fresh MeterProvider. This is the standard pattern for packages that exercise OTel in tests via a real in-memory exporter — the alternative (proxying every call through a getter) adds a per-call indirection on the production hot path. Instrument names follow the <domain>.<metric> convention seen in the wider ecosystem; the histogram unit is set to "ms" so dashboards render correctly without a unit-conversion step.