diff --git a/packages/core/src/tracing/instrumentation/protocols/http2Client.js b/packages/core/src/tracing/instrumentation/protocols/http2Client.js index 7d327e4527..dbbde25207 100644 --- a/packages/core/src/tracing/instrumentation/protocols/http2Client.js +++ b/packages/core/src/tracing/instrumentation/protocols/http2Client.js @@ -14,12 +14,12 @@ const { mergeExtraHeadersFromNormalizedObjectLiteral } = require('./captureHttpHeadersUtil'); const readSymbolProperty = require('../../../util/readSymbolProperty'); +const tracingHeaders = require('../../tracingHeaders'); const tracingUtil = require('../../tracingUtil'); const { sanitizeUrl, splitAndFilter } = require('../../../util/url'); let extraHttpHeadersToCapture; let isActive = false; -let disableW3cPropagation; const originS = 'Symbol(origin)'; const sentHeadersS = 'Symbol(sent-headers)'; @@ -30,17 +30,14 @@ const HTTP2_HEADER_STATUS = http2.constants.HTTP2_HEADER_STATUS; exports.init = function init(config) { instrument(http2); extraHttpHeadersToCapture = config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = config.tracing.disableW3cPropagation; }; exports.updateConfig = config => { extraHttpHeadersToCapture = config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = config.tracing.disableW3cPropagation; }; exports.activate = function activate(_config) { extraHttpHeadersToCapture = _config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = _config.tracing.disableW3cPropagation; isActive = true; }; @@ -155,7 +152,9 @@ function addTraceLevelHeader(headers, level, w3cTraceContext) { return; } headers[constants.traceLevelHeaderName] = level; - addW3cHeaders(headers, w3cTraceContext); + tracingHeaders.addW3cHeaders((name, value) => { + headers[name] = value; + }, w3cTraceContext); } function addHeaders(headers, span, w3cTraceContext) { @@ -170,17 +169,7 @@ function addHeaders(headers, span, w3cTraceContext) { headers[constants.spanIdHeaderName] = span.s; headers[constants.traceIdHeaderName] = span.t; headers[constants.traceLevelHeaderName] = '1'; - addW3cHeaders(headers, w3cTraceContext); -} - -function addW3cHeaders(headers, w3cTraceContext) { - if (disableW3cPropagation) { - return; - } - if (w3cTraceContext) { - headers[constants.w3cTraceParent] = w3cTraceContext.renderTraceParent(); - if (w3cTraceContext.hasTraceState()) { - headers[constants.w3cTraceState] = w3cTraceContext.renderTraceState(); - } - } + tracingHeaders.addW3cHeaders((name, value) => { + headers[name] = value; + }, w3cTraceContext); } diff --git a/packages/core/src/tracing/instrumentation/protocols/http2Server.js b/packages/core/src/tracing/instrumentation/protocols/http2Server.js index 30cfefc4e3..1ee2a779df 100644 --- a/packages/core/src/tracing/instrumentation/protocols/http2Server.js +++ b/packages/core/src/tracing/instrumentation/protocols/http2Server.js @@ -76,10 +76,10 @@ function shimEmit(realEmit) { cls.ns.bindEmitter(stream); } - const processedHeaders = tracingHeaders.fromHeaders(headers); - const w3cTraceContext = processedHeaders.w3cTraceContext; + const incomingHeaders = tracingHeaders.fromHeaders(headers); + const w3cTraceContext = incomingHeaders.w3cTraceContext; - if (typeof processedHeaders.level === 'string' && processedHeaders.level.indexOf('0') === 0) { + if (typeof incomingHeaders.level === 'string' && incomingHeaders.level.indexOf('0') === 0) { cls.setTracingLevel('0'); if (w3cTraceContext) { w3cTraceContext.disableSampling(); @@ -119,12 +119,12 @@ function shimEmit(realEmit) { const span = cls.startSpan({ spanName: exports.spanName, kind: constants.ENTRY, - traceId: processedHeaders.traceId, - parentSpanId: processedHeaders.parentId, + traceId: incomingHeaders.traceId, + parentSpanId: incomingHeaders.parentId, w3cTraceContext: w3cTraceContext, spanData }); - tracingHeaders.setSpanAttributes(span, processedHeaders); + tracingHeaders.setSpanAttributes(span, incomingHeaders); if (!headers['x-instana-t']) { // In cases where we have started a fresh trace (that is, there is no X-INSTANA-T in the incoming request diff --git a/packages/core/src/tracing/instrumentation/protocols/httpClient.js b/packages/core/src/tracing/instrumentation/protocols/httpClient.js index 392fa76277..9444c72a87 100644 --- a/packages/core/src/tracing/instrumentation/protocols/httpClient.js +++ b/packages/core/src/tracing/instrumentation/protocols/httpClient.js @@ -18,12 +18,12 @@ const { const constants = require('../../constants'); const cls = require('../../cls'); const hook = require('../../../util/hook'); +const tracingHeaders = require('../../tracingHeaders'); const URL = url.URL; let extraHttpHeadersToCapture; let logger; let isActive = false; -let disableW3cPropagation; exports.init = function init(config) { logger = config.logger; @@ -31,7 +31,6 @@ exports.init = function init(config) { instrument(coreHttpModule, false); instrument(coreHttpsModule, true); extraHttpHeadersToCapture = config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = config.tracing.disableW3cPropagation; hook.onModuleLoad('request', logDeprecatedWarning); }; @@ -43,12 +42,10 @@ function logDeprecatedWarning() { } exports.updateConfig = function updateConfig(config) { extraHttpHeadersToCapture = config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = config.tracing.disableW3cPropagation; }; exports.activate = function activate(_config) { extraHttpHeadersToCapture = _config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = _config.tracing.disableW3cPropagation; isActive = true; }; @@ -195,7 +192,9 @@ function instrument(coreModule, forceHttps) { removeInstanaHeadersFromOpts(options); if (skipTracingResult.suppressed && !traceLevelHeaderHasBeenAdded) { clientRequest.setHeader(constants.traceLevelHeaderName, '0'); - setW3cHeadersOnRequest(clientRequest, w3cTraceContext); + tracingHeaders.addW3cHeaders((name, value) => { + clientRequest.setHeader(name, value); + }, w3cTraceContext); } return clientRequest; @@ -398,7 +397,9 @@ function tryToAddHeadersToOpts(options, span, w3cTraceContext) { options.headers[constants.spanIdHeaderName] = span.s; options.headers[constants.traceIdHeaderName] = span.t; options.headers[constants.traceLevelHeaderName] = '1'; - tryToAddW3cHeaderToOpts(options, w3cTraceContext); + tracingHeaders.addW3cHeaders((name, value) => { + options.headers[name] = value; + }, w3cTraceContext); return true; } @@ -408,24 +409,14 @@ function tryToAddHeadersToOpts(options, span, w3cTraceContext) { function tryToAddTraceLevelAddHeaderToOpts(options, level, w3cTraceContext) { if (hasHeadersOption(options)) { options.headers[constants.traceLevelHeaderName] = level; - tryToAddW3cHeaderToOpts(options, w3cTraceContext); + tracingHeaders.addW3cHeaders((name, value) => { + options.headers[name] = value; + }, w3cTraceContext); return true; } return false; } -function tryToAddW3cHeaderToOpts(options, w3cTraceContext) { - if (disableW3cPropagation) { - return; - } - if (w3cTraceContext) { - options.headers[constants.w3cTraceParent] = w3cTraceContext.renderTraceParent(); - if (w3cTraceContext.hasTraceState()) { - options.headers[constants.w3cTraceState] = w3cTraceContext.renderTraceState(); - } - } -} - function hasHeadersOption(options) { return options && typeof options === 'object' && options.headers && typeof options.headers === 'object'; } @@ -446,26 +437,18 @@ function setHeadersOnRequest(clientRequest, span, w3cTraceContext) { if (span.shouldSuppressDownstream) { // Suppress trace propagation to downstream services. clientRequest.setHeader(constants.traceLevelHeaderName, '0'); - setW3cHeadersOnRequest(clientRequest, w3cTraceContext); + tracingHeaders.addW3cHeaders((name, value) => { + clientRequest.setHeader(name, value); + }, w3cTraceContext); return; } clientRequest.setHeader(constants.spanIdHeaderName, span.s); clientRequest.setHeader(constants.traceIdHeaderName, span.t); clientRequest.setHeader(constants.traceLevelHeaderName, '1'); - setW3cHeadersOnRequest(clientRequest, w3cTraceContext); -} - -function setW3cHeadersOnRequest(clientRequest, w3cTraceContext) { - if (disableW3cPropagation) { - return; - } - if (w3cTraceContext) { - clientRequest.setHeader(constants.w3cTraceParent, w3cTraceContext.renderTraceParent()); - if (w3cTraceContext.hasTraceState()) { - clientRequest.setHeader(constants.w3cTraceState, w3cTraceContext.renderTraceState()); - } - } + tracingHeaders.addW3cHeaders((name, value) => { + clientRequest.setHeader(name, value); + }, w3cTraceContext); } function captureRequestHeaders(options, clientRequest, response) { diff --git a/packages/core/src/tracing/instrumentation/protocols/httpServer.js b/packages/core/src/tracing/instrumentation/protocols/httpServer.js index 5ebc25227c..21f8417b05 100644 --- a/packages/core/src/tracing/instrumentation/protocols/httpServer.js +++ b/packages/core/src/tracing/instrumentation/protocols/httpServer.js @@ -58,10 +58,10 @@ function shimEmit(realEmit) { if (res && res.on && res.addListener && res.emit) { cls.ns.bindEmitter(res); } - const headers = tracingHeaders.fromHttpRequest(req); - const w3cTraceContext = headers.w3cTraceContext; + const incomingHeaders = tracingHeaders.fromHttpRequest(req); + const w3cTraceContext = incomingHeaders.w3cTraceContext; - if (typeof headers.level === 'string' && headers.level.indexOf('0') === 0) { + if (typeof incomingHeaders.level === 'string' && incomingHeaders.level.indexOf('0') === 0) { cls.setTracingLevel('0'); if (w3cTraceContext) { w3cTraceContext.disableSampling(); @@ -99,13 +99,13 @@ function shimEmit(realEmit) { const span = cls.startSpan({ spanName: exports.spanName, kind: constants.ENTRY, - traceId: headers.traceId, - parentSpanId: headers.parentId, + traceId: incomingHeaders.traceId, + parentSpanId: incomingHeaders.parentId, w3cTraceContext: w3cTraceContext, spanData }); - tracingHeaders.setSpanAttributes(span, headers); + tracingHeaders.setSpanAttributes(span, incomingHeaders); if (!req.headers['x-instana-t']) { // In cases where we have started a fresh trace (that is, there is no X-INSTANA-T in the incoming request diff --git a/packages/core/src/tracing/instrumentation/protocols/nativeFetch.js b/packages/core/src/tracing/instrumentation/protocols/nativeFetch.js index bfcbe9434d..56be6c7689 100644 --- a/packages/core/src/tracing/instrumentation/protocols/nativeFetch.js +++ b/packages/core/src/tracing/instrumentation/protocols/nativeFetch.js @@ -14,6 +14,7 @@ const { getExtraHeadersCaseInsensitive, mergeExtraHeadersFromFetchHeaders } = require('./captureHttpHeadersUtil'); +const tracingHeaders = require('../../tracingHeaders'); const tracingUtil = require('../../tracingUtil'); const { sanitizeUrl, splitAndFilter } = require('../../../util/url'); @@ -21,7 +22,6 @@ const originalFetch = global.fetch; let extraHttpHeadersToCapture; let isActive = false; -let disableW3cPropagation; // This determines whether we need to apply a workaround for a bug in Node.js fetch implementation (or rather, the // underlying dependency undici). @@ -48,12 +48,10 @@ exports.init = function init(config) { instrument(); extraHttpHeadersToCapture = config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = config.tracing.disableW3cPropagation; }; exports.updateConfig = function updateConfig(config) { extraHttpHeadersToCapture = config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = config.tracing.disableW3cPropagation; }; exports.activate = function activate(_config) { @@ -63,7 +61,6 @@ exports.activate = function activate(_config) { } extraHttpHeadersToCapture = _config.tracing.http.extraHttpHeadersToCapture; - disableW3cPropagation = _config.tracing.disableW3cPropagation; isActive = true; }; @@ -210,7 +207,9 @@ function injectTraceCorrelationHeaders(originalArgs, span, w3cTraceContext) { [constants.spanIdHeaderName]: span.s, [constants.traceLevelHeaderName]: '1' }; - addW3cTraceContextHeaders(headersToAdd, w3cTraceContext); + tracingHeaders.addW3cHeaders((name, value) => { + headersToAdd[name] = value; + }, w3cTraceContext); injectHeaders(originalArgs, headersToAdd); } @@ -218,22 +217,12 @@ function injectSuppressionHeader(originalArgs, w3cTraceContext) { const headersToAdd = { [constants.traceLevelHeaderName]: '0' }; - addW3cTraceContextHeaders(headersToAdd, w3cTraceContext); + tracingHeaders.addW3cHeaders((name, value) => { + headersToAdd[name] = value; + }, w3cTraceContext); injectHeaders(originalArgs, headersToAdd); } -function addW3cTraceContextHeaders(headersToAdd, w3cTraceContext) { - if (disableW3cPropagation) { - return; - } - if (w3cTraceContext) { - headersToAdd[constants.w3cTraceParent] = w3cTraceContext.renderTraceParent(); - if (w3cTraceContext.hasTraceState()) { - headersToAdd[constants.w3cTraceState] = w3cTraceContext.renderTraceState(); - } - } -} - function injectHeaders(originalArgs, headersToAdd) { // Headers can be present in the second parameter to fetch (the options object) as well as in the first parameter if // the first parameter is a Fetch API Request object (and not a string or a URL object). If headers are present in diff --git a/packages/core/src/tracing/tracingHeaders.js b/packages/core/src/tracing/tracingHeaders.js index dfe6fe3090..61bb6ea3a9 100644 --- a/packages/core/src/tracing/tracingHeaders.js +++ b/packages/core/src/tracing/tracingHeaders.js @@ -15,6 +15,7 @@ const w3c = require('./w3c_trace_context'); let logger; let disableW3cCorrelation = false; +let disableW3cPropagation = false; /** * @param {import('../config').InstanaConfig} config @@ -24,6 +25,7 @@ exports.init = function (config) { w3c.init(config); disableW3cCorrelation = config.tracing.disableW3cCorrelation; + disableW3cPropagation = config.tracing.disableW3cPropagation; }; /** @@ -31,6 +33,7 @@ exports.init = function (config) { */ exports.activate = function (config) { disableW3cCorrelation = config.tracing.disableW3cCorrelation; + disableW3cPropagation = config.tracing.disableW3cPropagation; }; /** @@ -421,3 +424,20 @@ exports.setSpanAttributes = function (span, tracingHeaders) { span.sy = true; } }; + +/** + * Writes traceparent, tracestate and baggage headers using the provided setter function. + * @param {(key: string, value: string) => void} set + * @param {import('./w3c_trace_context/W3cTraceContext')} w3cTraceContext + */ +exports.addW3cHeaders = function addW3cHeaders(set, w3cTraceContext) { + if (disableW3cPropagation) { + return; + } + if (w3cTraceContext) { + set(constants.w3cTraceParent, w3cTraceContext.renderTraceParent()); + if (w3cTraceContext.hasTraceState()) { + set(constants.w3cTraceState, w3cTraceContext.renderTraceState()); + } + } +};