# `telemetry` _(no submodules)_ ## Purpose OpenTelemetry surface for `@suaveplan/pdf`. PDF generation is a load-bearing primitive in any system that emits invoices, receipts, or financial reports, so the package needs first-class observability — counters for throughput / failure-rate, histograms for latency and output size, all tagged with stable `PDF.*` codes. The `createPdfObservability` factory constructs the bundle once at module load and binds to the global no-op meter / tracer when no telemetry pipeline is wired up, so the recording helpers are always safe to call from the hot path. ## Features - Six instruments on the `@suaveplan/pdf` meter: - `pdf_documents_rendered_total` — counter tagged `success`. - `pdf_pages_emitted_total` — counter. - `pdf_render_errors_total` — counter tagged `code`. - `pdf_validation_failures_total` — counter tagged `code`. - `pdf_render_duration_ms` — histogram (ms). - `pdf_document_size_bytes` — histogram (bytes). - `createPdfObservability(opts?)` factory accepting either an explicit bundle (`opts.observability`), an explicit meter + tracer pair, or nothing (binds to the no-op providers). - Six matching `record*` helpers so call sites do not have to know the attribute keys. ## Usage: Basic ```ts import { createPdfObservability, recordDocumentRendered } from "@suaveplan/pdf/telemetry"; const obs = createPdfObservability(); recordDocumentRendered(obs, { success: true }); ``` ## Usage: Advanced In tests, supply a meter from a `MeterProvider` configured with a metric reader to assert exact recorded values: ```ts import { MeterProvider } from "@opentelemetry/sdk-metrics"; import { createPdfObservability, recordRenderDuration, recordRenderError, } from "@suaveplan/pdf/telemetry"; const provider = new MeterProvider(); const meter = provider.getMeter("test"); const obs = createPdfObservability({ meter }); recordRenderError(obs, { code: "PDF.RENDER_FAILED" }); recordRenderDuration(obs, 42); ``` In production, install the OTLP / Prometheus exporter once at process start-up; every call site in `@suaveplan/pdf` will then surface metrics to your collector automatically because `createPdfObservability()` (no args) reads from the global `metrics`/`trace` API providers. ## API Reference - `createPdfObservability(opts?: PdfObservabilityOptions): PdfObservability` — factory returning `{ meter, tracer, counters, histograms }`. - `recordDocumentRendered(obs, { success })` — adds `1` to the documents-rendered counter tagged with `success` as the string `"true"` / `"false"`. - `recordPagesEmitted(obs, count)` — adds `count` to the pages-emitted counter. - `recordRenderError(obs, { code })` — adds `1` to the render-errors counter tagged with the `PDF.*` code. - `recordValidationFailure(obs, { code })` — adds `1` to the validation-failures counter tagged with the `PDF.*` code. - `recordRenderDuration(obs, ms)` — records a sample on the render-duration histogram. - `recordDocumentSize(obs, bytes)` — records a sample on the document-size histogram. ## Implementation Notes - `createCounter` / `createHistogram` come from `@suaveplan/opentelemetry`; they wrap the standard `Meter.createCounter` / `Meter.createHistogram` so the no-op meter is picked up automatically when no `MeterProvider` is installed. - Histogram units follow the OpenTelemetry convention: `"ms"` for durations, `"By"` for byte sizes. - Attribute values are stringified at the call-site (`success` becomes `"true"` / `"false"`) because OTel SDKs reject boolean attribute values in some backends; sticking to strings is the portable form. - `createPdfObservability({ observability })` short-circuits because call sites embedded inside a larger service want to pass through the bundle their caller already built, avoiding duplicate counter registration warnings on the OTel SDK side. - Each record helper is its own export — colocating them with the bundle factory lets call sites tree-shake unused recorders without pulling the entire factory.