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

2.3 KiB

OpenTelemetry instrumentation

(no submodules)

Purpose

Defines the four OpenTelemetry instruments emitted by @suaveplan/imessage-adapter and the helpers that record onto them. Instruments are resolved against the package-named Meter (@suaveplan/imessage-adapter / 0.1.0) so consumers can filter to just this package in their dashboards. refreshIMessageMeters() re-binds every instrument against the current global MeterProvider, which tests use to redirect emissions to an in-memory exporter.

Features

  • Counter imessage.messages_emitted_total with {chat_type, from_me} attributes — incremented once per parsed message yielded by IMessageWatcher.poll().
  • Counter imessage.attachments_emitted_total with {mime_family} — incremented once per parsed attachment.
  • Counter imessage.poll_errors_total with {code} — incremented on every poll-loop error, attributed by IMESSAGE.* code.
  • Histogram imessage.poll_duration_ms with {outcome} (ok / error / aborted) — records the wall-clock duration of every completed (or cancelled) poll tick in milliseconds.

Usage: Basic

import {
    recordMessageEmitted,
    recordPollDuration,
} from "@suaveplan/imessage-adapter/otel";

recordMessageEmitted("direct", false);
recordPollDuration(42, "ok");

Usage: Advanced

import { metrics } from "@opentelemetry/api";
import { refreshIMessageMeters } from "@suaveplan/imessage-adapter";

metrics.setGlobalMeterProvider(meterProvider);
refreshIMessageMeters(); // re-resolve so subsequent records land on this provider

API Reference

  • recordMessageEmitted(chatType: "direct" | "group", fromMe: boolean): void
  • recordAttachmentEmitted(mimeFamily: string): void
  • recordPollError(code: string): void
  • recordPollDuration(durationMs: number, outcome: "ok" | "error" | "aborted"): void
  • refreshIMessageMeters(): void — re-bind every instrument against the current global MeterProvider.

Implementation Notes

The instruments are stored in mutable module-level bindings so refreshIMessageMeters() can swap them in-place; this is the canonical pattern used by slack-client and the other messaging clients. The mime_family attribute is computed by the caller (typically the watcher) as the first segment of the MIME type so cardinality stays bounded.