diff --git a/packages/opentelemetry-plugin-http/src/http.ts b/packages/opentelemetry-plugin-http/src/http.ts index 51263cc89e0..bf9e5714f37 100644 --- a/packages/opentelemetry-plugin-http/src/http.ts +++ b/packages/opentelemetry-plugin-http/src/http.ts @@ -380,8 +380,12 @@ export class HttpPlugin extends BasePlugin { extraOptions ); + if (utils.isOpenTelemetryRequest(optionsParsed)) { + delete optionsParsed.headers![utils.OT_REQUEST_HEADER]; + return original.apply(this, [optionsParsed, ...args]); + } + if ( - utils.isOpenTelemetryRequest(optionsParsed) || utils.isIgnored( origin + pathname, plugin._config.ignoreOutgoingUrls, diff --git a/packages/opentelemetry-plugin-http/src/utils.ts b/packages/opentelemetry-plugin-http/src/utils.ts index e97e421c460..1b492285994 100644 --- a/packages/opentelemetry-plugin-http/src/utils.ts +++ b/packages/opentelemetry-plugin-http/src/utils.ts @@ -33,6 +33,10 @@ import { AttributeNames } from './enums/AttributeNames'; import * as url from 'url'; import { Socket } from 'net'; +/** + * Specific header used by exporters to "mark" outgoing request to avoid creating + * spans for request that export them which would create a infinite loop. + */ export const OT_REQUEST_HEADER = 'x-opentelemetry-outgoing-request'; export const HTTP_STATUS_SPECIAL_CASES: SpecialHttpStatusCodeMapping = { diff --git a/packages/opentelemetry-plugin-http/test/functionals/http-enable.test.ts b/packages/opentelemetry-plugin-http/test/functionals/http-enable.test.ts index 94c9c410f60..76abea604b4 100644 --- a/packages/opentelemetry-plugin-http/test/functionals/http-enable.test.ts +++ b/packages/opentelemetry-plugin-http/test/functionals/http-enable.test.ts @@ -180,6 +180,10 @@ describe('HttpPlugin', () => { }; const result = await httpRequest.get(options); + assert( + result.reqHeaders[OT_REQUEST_HEADER] === undefined, + 'custom header should be stripped' + ); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(result.data, 'Ok'); assert.strictEqual(spans.length, 0); @@ -293,6 +297,10 @@ describe('HttpPlugin', () => { }; const result = await httpRequest.get(options); + assert( + result.reqHeaders[OT_REQUEST_HEADER] === undefined, + 'custom header should be stripped' + ); const spans = memoryExporter.getFinishedSpans(); assert.strictEqual(result.data, 'Ok'); assert.strictEqual(spans.length, 0);