Skip to content

@relaybus/otel ​

@relaybus/otel is the OpenTelemetry integration of relaybus, a reliable, storage-agnostic event bus for NestJS and Node.js: messaging metrics after the OpenTelemetry semantic conventions, outbox backlog gauges, and one trace from publish in one service to the handler in another.

sh
pnpm add @relaybus/otel @opentelemetry/api

It depends only on @opentelemetry/api (peer, ^1.3.0); the SDK, exporters and collector are yours.

ts
import { relayBusOpenTelemetry } from '@relaybus/otel';

const otel = relayBusOpenTelemetry(); // global meter and tracer providers, W3C propagation

const bus = new RelayBus({
  store,
  observers: [otel.observer], // metrics
  tracer: otel.tracer, // spans + traceparent/tracestate in event headers
  backlogInterval: '30s', // feeds the backlog gauges
});

In NestJS pass the same three options to RelayBusModule.forRoot.

OptionDefaultWhat it does
meterProvidermetrics.getMeterProvider()Where the metrics are created.
tracerProvidertrace.getTracerProvider()Where the spans are created.
propagatorW3C Trace Context (built in)Writes and reads the trace context of events. Pass propagation from @opentelemetry/api for the SDK's.

Traces ​

SpanKindParentIn which process
publish <event type>producerthe caller's active spanthe publisher, inside publish
send <destination>producerthe publish span (from the stored event), linkedthe publisher, when a route sends it
process <event type>consumerthe context the event arrived with (send or publish)the consumer, around the handler

The publish span's context is stored with the event (traceparent, tracestate headers), so the trace survives the outbox, retries and restarts. A route sends the event with the send span's context; the consumer's process span continues from it, and whatever the handler does or publishes joins that span. Without a tracer the headers are still readable with traceContextOf from @relaybus/core.

Metrics ​

Durations are in seconds. error.type is the relaybus error code (RELAYBUS_*) when there is one, else the error's class name; it is present only on failures.

MetricTypeUnitAttributes
messaging.client.operation.durationhistogramsmessaging.system, messaging.operation.name (publish, claim, send, receive), messaging.operation.type, messaging.destination.name, error.type
messaging.client.sent.messagescounter{message}messaging.system, messaging.destination.name, messaging.operation.name, messaging.operation.type, error.type
messaging.client.consumed.messagescounter{message}as above, plus relaybus.receive.outcome (accepted, duplicate, ignored, invalid, error)
messaging.process.durationhistogramsmessaging.system, messaging.destination.name (event type), messaging.consumer.group.name (handler id), messaging.operation.*, error.type
relaybus.messages.invalidcounter{message}messaging.system, messaging.destination.name, error.type (inbound messages a transport could not decode; they never reach receive)
relaybus.events.publishedcounter{event}messaging.system, messaging.destination.name (event type), error.type
relaybus.claim.deliverieshistogram{delivery}messaging.system, messaging.operation.*
relaybus.claim.laneshistogram{lane}messaging.system, messaging.operation.*
relaybus.end_to_end.latencyhistogramsmessaging.system, messaging.destination.name, messaging.consumer.group.name, relaybus.delivery.kind (handler, route)
relaybus.deliveries.retriedcounter{delivery}messaging.system, messaging.destination.name, messaging.consumer.group.name, error.type
relaybus.deliveries.dead_letteredcounter{delivery}as above
relaybus.lease.lostcounter{delivery}messaging.system, messaging.destination.name, messaging.consumer.group.name
relaybus.deliveries.pendinggauge{delivery}none (needs backlogInterval)
relaybus.deliveries.oldest_agegaugesnone (needs backlogInterval)
relaybus.failurescounter{failure}relaybus.failure.stage (claim, complete, purge, backlog, ...), error.type

messaging.system is relaybus for work on the outbox (publish, claim, process) and the transport's system (kafka, rabbitmq) for sends and receives. The full guide, with a collector, Prometheus and alert rules, is the Observability page.

License ​

MIT

Released under the MIT License.