@@ -36,7 +36,8 @@ export interface OtelSettings {
3636 /** Resource service.name. Env OTEL_SERVICE_NAME overrides. */
3737 serviceName ?: string ;
3838 /**
39- * Extra resource attributes (merged; env keys win). Non-secret labels only.
39+ * Extra resource attributes. Non-secret labels only. Replaced wholesale by
40+ * OTEL_RESOURCE_ATTRIBUTES when the env var is set; never merged per-key.
4041 */
4142 resourceAttributes ?: Record < string , string > ;
4243}
@@ -212,8 +213,9 @@ function validateStringMap(
212213 * - endpoint: env > settings
213214 * - headers: env list fully replaces settings when set; else settings
214215 * - serviceName: env > settings.serviceName > attrs["service.name"] > default
215- * - resourceAttributes: settings then env (env wins on conflict); after merge,
216- * attrs["service.name"] is synced to the resolved serviceName
216+ * - resourceAttributes: env list fully replaces settings when OTEL_RESOURCE_ATTRIBUTES
217+ * is set; else settings. After resolution, attrs["service.name"] is synced
218+ * to the resolved serviceName
217219 *
218220 * No endpoint → disabled (ok); invalid or malformed → not ok.
219221 */
@@ -294,19 +296,6 @@ export function resolveOtelExportConfig(
294296 }
295297
296298 let resourceAttributes : Record < string , string > = { } ;
297- const settingsAttrs = validateStringMap (
298- otel ?. resourceAttributes ,
299- "settings.otel.resourceAttributes" ,
300- ) ;
301- if ( ! settingsAttrs . ok ) {
302- return {
303- ok : false ,
304- code : OTEL_CONFIG_INVALID ,
305- message : settingsAttrs . message ,
306- } ;
307- }
308- resourceAttributes = { ...settingsAttrs . value } ;
309-
310299 if ( envResourceAttrsRaw !== undefined ) {
311300 const parsed = parseOtelKeyValueList (
312301 envResourceAttrsRaw ,
@@ -315,7 +304,20 @@ export function resolveOtelExportConfig(
315304 if ( ! parsed . ok ) {
316305 return { ok : false , code : OTEL_CONFIG_INVALID , message : parsed . message } ;
317306 }
318- resourceAttributes = { ...resourceAttributes , ...parsed . value } ;
307+ resourceAttributes = parsed . value ;
308+ } else {
309+ const settingsAttrs = validateStringMap (
310+ otel ?. resourceAttributes ,
311+ "settings.otel.resourceAttributes" ,
312+ ) ;
313+ if ( ! settingsAttrs . ok ) {
314+ return {
315+ ok : false ,
316+ code : OTEL_CONFIG_INVALID ,
317+ message : settingsAttrs . message ,
318+ } ;
319+ }
320+ resourceAttributes = settingsAttrs . value ;
319321 }
320322
321323 // Sync attrs["service.name"] to the resolved name so the two never diverge.
0 commit comments