# `telemetry/telemetry.ts` _(no submodules)_ ## Purpose Owns the OpenTelemetry meter for `@suaveplan/overview` and exposes the three counters and one histogram that the spec requires. The meter is constructed lazily at module import time via `metrics.getMeter("@suaveplan/overview", "0.1.0")` so a no-op OTel SDK is the default — there is no instrumentation cost on the cold path when no SDK is installed. Every metric is exported as a typed `Counter` or `Histogram` so other modules can `.add` / `.record` against them directly without going through a wrapper. ## Features - Single meter scoped to the package name + version - `overview.packages_discovered_total` — counter - `overview.records_rejected_total{reason}` — counter (reason is one of `parse_failed` | `invalid_record`) - `overview.graph_builds_total` — counter - `overview.discover_duration_ms` — histogram with millisecond unit - `RejectionReason` typed alias for the `reason` attribute ## Usage: Basic ```ts import { packagesDiscoveredTotal } from "@suaveplan/overview/telemetry"; packagesDiscoveredTotal.add(7); ``` ## Usage: Advanced ```ts import { discoverDurationMs, recordsRejectedTotal, type RejectionReason, } from "@suaveplan/overview/telemetry"; const start = performance.now(); const result = await runDiscovery(); discoverDurationMs.record(performance.now() - start); if (!result.ok) { const reason: RejectionReason = result.reason; recordsRejectedTotal.add(1, { reason }); } ``` Plug `@opentelemetry/sdk-metrics` in your runtime to harvest these metrics; no adapter glue is needed inside `@suaveplan/overview`. ## API Reference - `packagesDiscoveredTotal: Counter` - `recordsRejectedTotal: Counter` (attribute: `reason: "parse_failed" | "invalid_record"`) - `graphBuildsTotal: Counter` - `discoverDurationMs: Histogram` (unit: `ms`) - `type RejectionReason = "parse_failed" | "invalid_record"` ## Implementation Notes The meter is obtained once at module load and cached as a `const`. With the no-op SDK installed (the default in test environments without a configured OTel SDK), every `.add` and `.record` call is a fast no-op — there is no need to feature-flag instrumentation. Tests use the SDK's `InMemoryMetricReader` to assert that the counters and histogram move when discovery runs.