Files
suaveplan/packages/observability/monitor/opentelemetry/src/schemas/otel-config.schema.md
2026-05-27 23:47:53 +01:00

6.1 KiB
Raw Blame History

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

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:

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:

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<typeof OtelConfigSchema>
  • TracesConfig — z.infer<typeof TracesConfigSchema>
  • MetricsConfig — z.infer<typeof MetricsConfigSchema>
  • LogsConfig — z.infer<typeof LogsConfigSchema>
  • ExporterType — z.infer<typeof ExporterTypeSchema>
  • SamplerType — z.infer<typeof SamplerTypeSchema>
  • PropagatorType — z.infer<typeof PropagatorTypeSchema>

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.