Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
# `telemetry`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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.