Reported by a React on Rails Pro customer who runs the renderer on ECS with their own OpenTelemetry setup, including AWS instrumentation and resource detectors.
Two gaps
1. init() accepts no custom instrumentations or resource detectors.
OpenTelemetryInitOptions currently takes serviceName, fastify, tracing, exporter, spanProcessor, resourceAttributes and shutdownTimeoutMs. There is no way to add instrumentations beyond the built-in HttpInstrumentation + FastifyOtelInstrumentation pair, and no way to pass resource detectors.
resourceAttributes and OTEL_RESOURCE_ATTRIBUTES cover simple cases such as container identity, but only if the caller resolves the values themselves. The standard answer for "which ECS container is this renderer on" is a resource detector, and today it cannot be plugged in.
2. Bringing your own SDK is all-or-nothing.
init() calls trace.setGlobalTracerProvider() and, if another SDK already owns the global, shuts its provider down and returns early:
https://github.com/shakacode/react_on_rails/blob/main/packages/react-on-rails-pro-node-renderer/src/integrations/opentelemetry.ts#L269-L277
The bail-out itself is correct, it avoids patching modules under a tracer we do not own. The problem is what it costs: setupTracing / setupSubSpan never install either, so an app that bootstraps its own OpenTelemetry SDK first (a --require preload, for instance) loses every ror.* SSR span, not just the exporter wiring. Users then have to choose between their existing observability stack and the renderer's span taxonomy, when the two should compose.
Proposed scope
- Add
instrumentations?: Instrumentation[] to OpenTelemetryInitOptions, merged with the built-in HTTP + Fastify pair rather than replacing it.
- Add resource-detector support, feeding
@opentelemetry/resources detection into the resource alongside the existing resourceAttributes merge.
- Add a supported path for attaching to an already-registered provider instead of bailing out, so the
ror.* unit-of-work spans still install when the host application owns the global tracer provider.
- Document all three in the OpenTelemetry section of
docs/pro/node-renderer.md, including the ECS resource-detector case.
Additive throughout. Existing init() callers should see no behaviour change.
Reported by a React on Rails Pro customer who runs the renderer on ECS with their own OpenTelemetry setup, including AWS instrumentation and resource detectors.
Two gaps
1.
init()accepts no custom instrumentations or resource detectors.OpenTelemetryInitOptionscurrently takesserviceName,fastify,tracing,exporter,spanProcessor,resourceAttributesandshutdownTimeoutMs. There is no way to add instrumentations beyond the built-inHttpInstrumentation+FastifyOtelInstrumentationpair, and no way to pass resource detectors.resourceAttributesandOTEL_RESOURCE_ATTRIBUTEScover simple cases such as container identity, but only if the caller resolves the values themselves. The standard answer for "which ECS container is this renderer on" is a resource detector, and today it cannot be plugged in.2. Bringing your own SDK is all-or-nothing.
init()callstrace.setGlobalTracerProvider()and, if another SDK already owns the global, shuts its provider down and returns early:https://github.com/shakacode/react_on_rails/blob/main/packages/react-on-rails-pro-node-renderer/src/integrations/opentelemetry.ts#L269-L277
The bail-out itself is correct, it avoids patching modules under a tracer we do not own. The problem is what it costs:
setupTracing/setupSubSpannever install either, so an app that bootstraps its own OpenTelemetry SDK first (a--requirepreload, for instance) loses everyror.*SSR span, not just the exporter wiring. Users then have to choose between their existing observability stack and the renderer's span taxonomy, when the two should compose.Proposed scope
instrumentations?: Instrumentation[]toOpenTelemetryInitOptions, merged with the built-in HTTP + Fastify pair rather than replacing it.@opentelemetry/resourcesdetection into the resource alongside the existingresourceAttributesmerge.ror.*unit-of-work spans still install when the host application owns the global tracer provider.docs/pro/node-renderer.md, including the ECS resource-detector case.Additive throughout. Existing
init()callers should see no behaviour change.