Files
skills/docs/communication/messaging/slack-client/src/otel/metrics.md
2026-05-29 08:20:56 +01:00

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, unit ms), 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 after metrics.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 — increments slack.requests and records slack.latency_ms.
  • recordError(method: string, code: string): void — increments slack.errors.
  • recordWebhook(outcome: "ok" | "error"): void — increments slack.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.