Relationships
#1084 Tracing ignores OTEL_RESOURCE_ATTRIBUTES — only service.name reaches the Resource
Opened by kneel · 7/11/2026· Shipped 7/11/2026
Summary
When OTel tracing is enabled, swamp builds its span Resource from scratch with just
service.name and service.version. It never merges the SDK default / env-detected
resource, so the standard OTEL_RESOURCE_ATTRIBUTES environment variable is silently
dropped. No custom resource attributes (e.g. deployment.environment, host.name, a
site label) can be attached to spans, even though every other OpenTelemetry SDK honors
that variable via the built-in env resource detector.
(Note: a few dotted identifiers below are written with a * or in prose to avoid the
Lab's hostname redactor mangling them — the first submission turned telemetry.sdk.*
into [HOST-n].)
Environment
- swamp
20260709.014917.0-sha.3da10c76 - OTLP/HTTP exporter (
OTEL_TRACES_EXPORTER=otlp,OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf) - Backend: Grafana Tempo (verified the received Resource)
Steps to reproduce
OTEL_TRACES_EXPORTER=console \
OTEL_SERVICE_NAME=swamp \
OTEL_RESOURCE_ATTRIBUTES="site=bed,deployment.environment=prod" \
swamp model method run <any-instance> <method>Inspect the emitted span's resource attributes (console exporter, or query the backend).
Expected
The resource includes the OTEL_RESOURCE_ATTRIBUTES keys alongside the defaults:
service.name=swamp, site=bed, deployment.environment=prod, plus the telemetry.sdk.*
attributes.
Actual
Only the hand-set attributes survive; the OTEL_RESOURCE_ATTRIBUTES keys are absent.
The full resource is exactly:
service.name=swampservice.version=devtelemetry.sdk.*= languagenodejs, nameopentelemetry, version1.30.1
Root cause
src/infrastructure/tracing/otel_init.ts (~lines 71-76) constructs the Resource directly
and never merges Resource.default() or the env detector, so the OTel envDetector that
parses OTEL_RESOURCE_ATTRIBUTES never runs:
// serviceName <- OTEL_SERVICE_NAME env var (default "swamp")
// serviceVersion <- SWAMP_VERSION env var (default "dev")
const resource = new Resource({
[ATTR_SERVICE_NAME]: serviceName,
[ATTR_SERVICE_VERSION]: serviceVersion,
});
const provider = new BasicTracerProvider({ resource });Suggested fix
Merge the default + env-detected resource, letting swamp's explicit service.name /
service.version win on conflict (@opentelemetry/resources@^1.30.1 exports
envDetectorSync):
const { Resource, envDetectorSync } = await import("@opentelemetry/resources");
// ...
const resource = Resource.default()
.merge(envDetectorSync.detect()) // reads OTEL_RESOURCE_ATTRIBUTES + OTEL_SERVICE_NAME
.merge(new Resource({
[ATTR_SERVICE_NAME]: serviceName,
[ATTR_SERVICE_VERSION]: serviceVersion,
}));Impact / workaround
Traces can't be tagged with the resource dimensions (host, deployment.environment, a
site/tenant label) needed to correlate them with metrics/logs that already carry those
labels. The only current workaround is to overload service.name (e.g. swamp-<site>),
which pollutes the service inventory and still can't express host.
Shipped
Click a lifecycle step above to view its details.