Files
skills/docs/security-stack/security/server-keys/src/otel/instruments.md
2026-05-29 08:20:56 +01:00

3.1 KiB

otel/instruments

(no submodules)

Purpose

Registers the OpenTelemetry counter and histogram that every CLI command in @suaveplan/server-keys emits exactly once per invocation through the runFunction wrapper. The instruments live behind the global meter provider supplied by @opentelemetry/api, so production deployments can plug in any exporter (OTLP, Prometheus, Jaeger) without changing the package. Tests wire an in-memory MeterProvider in tests/setup/polyfills.ts before any source module is imported, so the meter resolved at load time is the real provider's meter, never the noop fallback.

The recordCommand(command, outcome, durationMs, errorCode?) helper is the single call site every command goes through — keeping the attribute keys consistent and the histogram unit (ms) authoritative.

Features

  • Counter server_keys.command_total{command, command.outcome[, command.error_code]}.
  • Histogram server_keys.command_duration_ms{command, command.outcome[, command.error_code]} with unit: "ms".
  • Stable attribute-key constants (ATTR_COMMAND, ATTR_OUTCOME, ATTR_ERROR_CODE) so tests can assert by name.
  • recordCommand records both instruments atomically so dashboards built on the counter and the histogram never disagree.

Usage: Basic

import { recordCommand } from "@suaveplan/server-keys/otel/instruments";

const start = performance.now();
try {
    await doWork();
    recordCommand("create-root-keys", "success", performance.now() - start);
} catch (err) {
    recordCommand("create-root-keys", "error", performance.now() - start);
    throw err;
}

Usage: Advanced

Attach the typed error code when failing, so dashboards can break down failures by reason without scraping log lines:

import { recordCommand } from "@suaveplan/server-keys/otel/instruments";
import { ServerKeysError } from "@suaveplan/server-keys/error-codes/error-codes";

try {
    await prepareFileCommand(...);
    recordCommand("prepare-file", "success", elapsed);
} catch (err) {
    const code = err instanceof ServerKeysError ? err.code : "UNKNOWN";
    recordCommand("prepare-file", "error", elapsed, code);
    throw err;
}

Or query the in-memory test exporter to assert on emitted metrics:

await flushTestMetrics(); // from tests/setup/polyfills.ts

API Reference

  • commandTotal: Counter — total CLI commands executed.
  • commandDurationMs: Histogram — per-command duration (ms).
  • ATTR_COMMAND, ATTR_OUTCOME, ATTR_ERROR_CODE — string-literal attribute keys.
  • CommandOutcome = "success" | "error".
  • recordCommand(command, outcome, durationMs, errorCode?) — record one observation on both instruments.

Implementation Notes

metrics.getMeter(name, version) returns the meter from the current global provider; if no provider is registered, the API package returns a noop meter so production code never throws on missing telemetry. Setting the meter provider AFTER instruments.ts is imported has no effect on this module's meter handle, so the test polyfill must register the provider before any import that transitively loads instruments.ts.