# otel-config.schema _(no submodules)_ ## Purpose Provides the Zod schemas and inferred TypeScript types that define the complete OpenTelemetry SDK configuration contract for `@suaveplan/opentelemetry`. All runtime configuration objects are validated against these schemas before they reach any SDK lifecycle code, ensuring that schema violations surface as structured `OpenTelemetryError` instances rather than silent misbehavior or runtime crashes. The schemas serve as the single source of truth for what constitutes a valid `OtelConfig`. Any change to the accepted configuration shape is made here first, and all downstream code (e.g. `createSdk`, test fixtures) derives from these exports. ## Features - **`ExporterTypeSchema`** — enum of the four supported exporter backends: `console`, `otlp-http`, `otlp-grpc`, and `noop`. - **`SamplerTypeSchema`** — enum of four trace-sampling strategies: `always-on`, `always-off`, `trace-id-ratio`, and `parent-based`. - **`PropagatorTypeSchema`** — enum of four context-propagation formats: `w3c-tracecontext`, `baggage`, `b3`, and `b3-multi`. - **`TracesConfigSchema`** — optional per-signal object covering exporter, URL, sampler type and rate, propagators list, batch size, and flush interval. - **`MetricsConfigSchema`** — optional metrics signal object covering exporter, URL, and export interval. - **`LogsConfigSchema`** — optional logs signal object covering exporter and URL. - **`OtelConfigSchema`** — top-level schema requiring `serviceName` and allowing optional `serviceVersion`, `environment`, and per-signal sub-configs. - **Inferred TypeScript types** — all schemas export a corresponding `z.infer<>` type alias so callers can use fully-typed config objects without re-declaring shapes. ## Usage: Basic Example ```ts import { OtelConfigSchema } from "@suaveplan/opentelemetry"; const result = OtelConfigSchema.safeParse({ serviceName: "my-service", serviceVersion: "1.0.0", environment: "production", }); if (!result.success) { console.error(result.error.issues); } else { const config = result.data; // typed as OtelConfig console.log(config.serviceName); // "my-service" } ``` ## Usage: Advanced Example Using the schema to validate a rich configuration that covers all three signals, then feeding the validated data into `createSdk`: ```ts import { createSdk, OtelConfigSchema, type OtelConfig } from "@suaveplan/opentelemetry"; const raw: unknown = { serviceName: "payment-service", serviceVersion: "2.3.1", environment: "staging", traces: { exporter: "otlp-http", exporterUrl: "https://otel.example.com/v1/traces", sampler: "trace-id-ratio", sampleRate: 0.25, propagators: ["w3c-tracecontext", "baggage"], batchSize: 512, flushInterval: 5000, }, metrics: { exporter: "otlp-http", exporterUrl: "https://otel.example.com/v1/metrics", exportIntervalMs: 30000, }, logs: { exporter: "console", }, }; const parsed = OtelConfigSchema.parse(raw); // throws ZodError on failure const sdk = createSdk(parsed as OtelConfig); await sdk.start(); ``` You can also validate individual sub-schemas independently: ```ts import { TracesConfigSchema } from "@suaveplan/opentelemetry"; const tracesResult = TracesConfigSchema.safeParse({ exporter: "noop", sampler: "always-off", }); // tracesResult.success === true ``` ## API Reference ### `ExporterTypeSchema` `z.ZodEnum` — validates that a value is one of `"console" | "otlp-http" | "otlp-grpc" | "noop"`. ### `SamplerTypeSchema` `z.ZodEnum` — validates that a value is one of `"always-on" | "always-off" | "trace-id-ratio" | "parent-based"`. ### `PropagatorTypeSchema` `z.ZodEnum` — validates that a value is one of `"w3c-tracecontext" | "baggage" | "b3" | "b3-multi"`. ### `TracesConfigSchema` `z.ZodObject` — all fields optional: - `exporter?: ExporterType` - `exporterUrl?: string` (validated as URL) - `sampler?: SamplerType` - `sampleRate?: number` (0.0–1.0 inclusive) - `propagators?: PropagatorType[]` - `batchSize?: number` (positive integer) - `flushInterval?: number` (positive integer, milliseconds) ### `MetricsConfigSchema` `z.ZodObject` — all fields optional: - `exporter?: ExporterType` - `exporterUrl?: string` (validated as URL) - `exportIntervalMs?: number` (positive integer, milliseconds) ### `LogsConfigSchema` `z.ZodObject` — all fields optional: - `exporter?: ExporterType` - `exporterUrl?: string` (validated as URL) ### `OtelConfigSchema` `z.ZodObject` — top-level config schema: - `serviceName: string` (required, minimum length 1) - `serviceVersion?: string` - `environment?: string` - `traces?: TracesConfig` - `metrics?: MetricsConfig` - `logs?: LogsConfig` ### Type Aliases - `OtelConfig` — `z.infer` - `TracesConfig` — `z.infer` - `MetricsConfig` — `z.infer` - `LogsConfig` — `z.infer` - `ExporterType` — `z.infer` - `SamplerType` — `z.infer` - `PropagatorType` — `z.infer` ## Implementation Notes The schema file is intentionally kept free of business logic — it contains only Zod definitions and their `z.infer<>` type exports. Validation errors from `OtelConfigSchema.safeParse` are surfaced to callers by `createSdk`, which maps them into `OpenTelemetryError` instances with the `OTEL.INVALID_CONFIG` code. The `sampleRate` field uses `z.number().min(0).max(1)` with both bounds inclusive so that `0.0` (never sample) and `1.0` (always sample) are valid — these boundary values are important for feature-flag-driven sampling. All URL fields use `z.string().url()` rather than a looser regex to ensure that only well-formed absolute URLs are accepted, preventing misconfigured exporter endpoints from reaching the network layer at runtime. The enum schemas (`ExporterTypeSchema`, `SamplerTypeSchema`, `PropagatorTypeSchema`) are exported as named constants rather than inlined inside the parent schemas so that they can be reused independently for validation of partial configs or for driving UI option lists without pulling in the full parent schema.