npm.io
0.1.1 • Published yesterday

@xemahq/observability-nest

Licence
Apache-2.0
Version
0.1.1
Deps
10
Size
49 kB
Vulns
3
Weekly
0

@xemahq/observability-nest

This package belongs to Layer 1 — SDK/runtime. It depends only on Layer‑0 concerns and npm libraries (OpenTelemetry), never on a Xema service or a higher layer.

It is the one vendor‑agnostic telemetry seam for Xema services. Service code imports withSpan / getMeter / getTracer from here and never imports @opentelemetry/* directly, so the tracing dependency lives in exactly one place. The engine underneath is OpenTelemetry; we add no telemetry data model, propagation, sampling, exporter, or UI of our own — reinventing any of that is a non‑goal.

Two swap‑seams, so you are never trapped

  1. Backend — everything exports OTLP to an OpenTelemetry Collector; point it at Jaeger, SigNoz, Datadog, Honeycomb, … via Collector config. No application code changes.
  2. SDK — a TelemetryProvider is chosen at boot. OtelTelemetryProvider starts the OTel SDK; NoopTelemetryProvider starts nothing (the OTel API's built‑in no‑op stays in place). A custom provider can replace OpenTelemetry entirely. This is what makes observability optional with zero service‑code changes.

Enabled / disabled

Resolved from env (see resolveTelemetryConfig):

Var Meaning
OTEL_EXPORTER_OTLP_ENDPOINT OTLP/HTTP base (e.g. http://otel-collector:4318). Presence turns telemetry on by default.
XEMA_TELEMETRY_ENABLED true/false to force on/off regardless of endpoint.
XEMA_TELEMETRY_SAMPLE_RATIO Head sample ratio in [0,1] (default 1).

Enabled but no endpoint → fails fast (never starts blind). Endpoint set but unreachable → OTel logs export errors (visible, non‑fatal). Disabled → no SDK, no overhead.

Usage

// main.ts — FIRST statement, before NestFactory / Prisma / http server load,
// so auto-instrumentation can patch them.
import { startTelemetry } from '@xemahq/observability-nest';
startTelemetry({ serviceName: 'agent-session-api', serviceVersion: version });

// app.module.ts — DI handle + graceful-shutdown flush.
import { ObservabilityModule } from '@xemahq/observability-nest';
@Module({ imports: [ObservabilityModule.forRoot({ serviceName: 'agent-session-api' })] })
export class AppModule {}

// anywhere — instrument a unit of work.
import { withSpan } from '@xemahq/observability-nest';
await withSpan('session.launch.resolve-config', async (span) => {
  span.setAttributes({ 'session.id': sessionId });
  return resolveConfig();
});

withSpan opens an active span (nested spans + auto‑instrumentation parent to it), records exceptions + ERROR status on throw, and always ends the span. When telemetry is off it is a near‑zero‑cost pass‑through.