HMSH_TELEMETRY: "debug" | "info" = ...

Controls which OpenTelemetry spans are emitted. Spans are only captured when an OTel SDK (TracerProvider + exporter) is registered before workers start. Without an SDK, all span calls are no-ops.

Value Durable workflows YAML flows
'info' (default) WORKFLOW/START, WORKFLOW/COMPLETE, WORKFLOW/ERROR, ACTIVITY/{name} trigger + worker spans
'debug' All info spans + DISPATCH/{type}/{name}/{idx}, RETURN/{type}/{name}/{idx} + engine internals All activity types + all stream hops

Register an OpenTelemetry SDK with a trace exporter before calling Durable.Worker.create(). Any OTLP-compatible backend works (Honeycomb, Jaeger, Grafana Tempo, etc.):

import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { resourceFromAttributes } from '@opentelemetry/resources';
import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions';

const sdk = new NodeSDK({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'my-service',
}),
traceExporter: new OTLPTraceExporter({
url: 'https://api.honeycomb.io/v1/traces',
headers: { 'x-honeycomb-team': process.env.HONEYCOMB_API_KEY },
}),
});
sdk.start();

// Then start workers — spans flow automatically
await Durable.Worker.create({ ... });
# Concise: workflow lifecycle + activity execution only
HMSH_TELEMETRY=info node worker.js

# Verbose: adds per-operation DISPATCH/RETURN spans + engine internals
HMSH_TELEMETRY=debug node worker.js