diff --git a/packages/datadog-instrumentations/src/helpers/register.js b/packages/datadog-instrumentations/src/helpers/register.js index 2ef9d199f99..4b4185423c0 100644 --- a/packages/datadog-instrumentations/src/helpers/register.js +++ b/packages/datadog-instrumentations/src/helpers/register.js @@ -22,6 +22,15 @@ const disabledInstrumentations = new Set( DD_TRACE_DISABLED_INSTRUMENTATIONS ? DD_TRACE_DISABLED_INSTRUMENTATIONS.split(',') : [] ) +// Check for DD_TRACE__ENABLED environment variables +for (const [key, value] of Object.entries(process.env)) { + const match = key.match(/^DD_TRACE_(.+)_ENABLED$/) + if (match && (value.toLowerCase() === 'false' || value === '0')) { + const integration = match[1].toLowerCase() + disabledInstrumentations.add(integration) + } +} + const loadChannel = channel('dd-trace:instrumentation:load') // Globals diff --git a/packages/dd-trace/src/config.js b/packages/dd-trace/src/config.js index e827d1b6d0f..1a5eeb61d03 100644 --- a/packages/dd-trace/src/config.js +++ b/packages/dd-trace/src/config.js @@ -520,7 +520,7 @@ class Config { this._setValue(defaults, 'reportHostname', false) this._setValue(defaults, 'runtimeMetrics', false) this._setValue(defaults, 'sampleRate', undefined) - this._setValue(defaults, 'sampler.rateLimit', undefined) + this._setValue(defaults, 'sampler.rateLimit', 100) this._setValue(defaults, 'sampler.rules', []) this._setValue(defaults, 'sampler.spanSamplingRules', []) this._setValue(defaults, 'scope', undefined) @@ -541,6 +541,7 @@ class Config { this._setValue(defaults, 'telemetry.heartbeatInterval', 60000) this._setValue(defaults, 'telemetry.logCollection', false) this._setValue(defaults, 'telemetry.metrics', true) + this._setValue(defaults, 'traceEnabled', true) this._setValue(defaults, 'traceId128BitGenerationEnabled', true) this._setValue(defaults, 'traceId128BitLoggingEnabled', false) this._setValue(defaults, 'tracePropagationExtractFirst', false) @@ -627,6 +628,7 @@ class Config { DD_TRACE_AGENT_PROTOCOL_VERSION, DD_TRACE_CLIENT_IP_ENABLED, DD_TRACE_CLIENT_IP_HEADER, + DD_TRACE_ENABLED, DD_TRACE_EXPERIMENTAL_EXPORTER, DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED, DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED, @@ -713,6 +715,7 @@ class Config { this._setBoolean(env, 'dsmEnabled', DD_DATA_STREAMS_ENABLED) this._setBoolean(env, 'dynamicInstrumentationEnabled', DD_DYNAMIC_INSTRUMENTATION_ENABLED) this._setString(env, 'env', DD_ENV || tags.env) + this._setBoolean(env, 'traceEnabled', DD_TRACE_ENABLED) this._setBoolean(env, 'experimental.enableGetRumData', DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED) this._setString(env, 'experimental.exporter', DD_TRACE_EXPERIMENTAL_EXPORTER) this._setBoolean(env, 'experimental.runtimeId', DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED) @@ -1155,7 +1158,11 @@ class Config { } if (typeof value === 'string') { - value = value.split(',') + value = value.split(',').map(item => { + // Trim each item and remove whitespace around the colon + const [key, val] = item.split(':').map(part => part.trim()) + return val !== undefined ? `${key}:${val}` : key + }) } if (Array.isArray(value)) { diff --git a/packages/dd-trace/src/opentracing/tracer.js b/packages/dd-trace/src/opentracing/tracer.js index 37b1c68a635..2d854442cc3 100644 --- a/packages/dd-trace/src/opentracing/tracer.js +++ b/packages/dd-trace/src/opentracing/tracer.js @@ -52,8 +52,15 @@ class DatadogTracer { ? getContext(options.childOf) : getParent(options.references) + // as per spec, allow the setting of service name through options const tags = { - 'service.name': this._service + 'service.name': options?.tags?.service ? String(options.tags.service) : this._service + } + + // As per unified service tagging spec if a span is created with a service name different from the global + // service name it will not inherit the global version value + if (options?.tags?.service && options.tags.service !== this._service) { + options.tags.version = undefined } const span = new Span(this, this._processor, this._prioritySampler, { diff --git a/packages/dd-trace/src/telemetry/index.js b/packages/dd-trace/src/telemetry/index.js index 612c23b7ca1..7988cae5ec2 100644 --- a/packages/dd-trace/src/telemetry/index.js +++ b/packages/dd-trace/src/telemetry/index.js @@ -314,7 +314,15 @@ function updateConfig (changes, config) { logInjection: 'DD_LOG_INJECTION', headerTags: 'DD_TRACE_HEADER_TAGS', tags: 'DD_TAGS', - 'sampler.rules': 'DD_TRACE_SAMPLING_RULES' + 'sampler.rules': 'DD_TRACE_SAMPLING_RULES', + traceEnabled: 'DD_TRACE_ENABLED', + url: 'DD_TRACE_AGENT_URL', + 'sampler.rateLimit': 'DD_TRACE_RATE_LIMIT', + queryStringObfuscation: 'DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP', + version: 'DD_VERSION', + env: 'DD_ENV', + service: 'DD_SERVICE', + clientIpHeader: 'DD_TRACE_CLIENT_IP_HEADER' } const namesNeedFormatting = new Set(['DD_TAGS', 'peerServiceMapping', 'serviceMapping']) diff --git a/packages/dd-trace/test/config.spec.js b/packages/dd-trace/test/config.spec.js index 6558485b529..75a3e51c685 100644 --- a/packages/dd-trace/test/config.spec.js +++ b/packages/dd-trace/test/config.spec.js @@ -215,6 +215,7 @@ describe('Config', () => { expect(config).to.have.property('runtimeMetrics', false) expect(config.tags).to.have.property('service', 'node') expect(config).to.have.property('plugins', true) + expect(config).to.have.property('traceEnabled', true) expect(config).to.have.property('env', undefined) expect(config).to.have.property('reportHostname', false) expect(config).to.have.property('scope', undefined) @@ -350,7 +351,8 @@ describe('Config', () => { { name: 'reportHostname', value: false, origin: 'default' }, { name: 'runtimeMetrics', value: false, origin: 'default' }, { name: 'sampleRate', value: undefined, origin: 'default' }, - { name: 'sampler.rateLimit', value: undefined, origin: 'default' }, + { name: 'sampler.rateLimit', value: 100, origin: 'default' }, + { name: 'traceEnabled', value: true, origin: 'default' }, { name: 'sampler.rules', value: [], origin: 'default' }, { name: 'scope', value: undefined, origin: 'default' }, { name: 'service', value: 'node', origin: 'default' }, @@ -495,6 +497,7 @@ describe('Config', () => { process.env.DD_INSTRUMENTATION_INSTALL_TYPE = 'k8s_single_step' process.env.DD_INSTRUMENTATION_INSTALL_TIME = '1703188212' process.env.DD_INSTRUMENTATION_CONFIG_ID = 'abcdef123' + process.env.DD_TRACE_ENABLED = 'true' // required if we want to check updates to config.debug and config.logLevel which is fetched from logger reloadLoggerAndConfig() @@ -518,6 +521,7 @@ describe('Config', () => { expect(config).to.have.property('dynamicInstrumentationEnabled', true) expect(config).to.have.property('env', 'test') expect(config).to.have.property('sampleRate', 0.5) + expect(config).to.have.property('traceEnabled', true) expect(config).to.have.property('traceId128BitGenerationEnabled', true) expect(config).to.have.property('traceId128BitLoggingEnabled', true) expect(config).to.have.property('spanAttributeSchema', 'v1') @@ -1633,7 +1637,7 @@ describe('Config', () => { }, true) expect(config).to.have.deep.nested.property('sampler', { spanSamplingRules: [], - rateLimit: undefined, + rateLimit: 100, rules: [ { resource: '*', diff --git a/packages/dd-trace/test/config/disabled_instrumentations.spec.js b/packages/dd-trace/test/config/disabled_instrumentations.spec.js index d54ee38f677..c7f9b935fb5 100644 --- a/packages/dd-trace/test/config/disabled_instrumentations.spec.js +++ b/packages/dd-trace/test/config/disabled_instrumentations.spec.js @@ -1,11 +1,23 @@ 'use strict' -process.env.DD_TRACE_DISABLED_INSTRUMENTATIONS = 'express' - require('../setup/tap') describe('config/disabled_instrumentations', () => { it('should disable loading instrumentations completely', () => { + process.env.DD_TRACE_DISABLED_INSTRUMENTATIONS = 'express' + const handleBefore = require('express').application.handle + const tracer = require('../../../..') + const handleAfterImport = require('express').application.handle + tracer.init() + const handleAfterInit = require('express').application.handle + + expect(handleBefore).to.equal(handleAfterImport) + expect(handleBefore).to.equal(handleAfterInit) + delete process.env.DD_TRACE_DISABLED_INSTRUMENTATIONS + }) + + it('should disable loading instrumentations using DD_TRACE__ENABLED', () => { + process.env.DD_TRACE_EXPRESS_ENABLED = 'false' const handleBefore = require('express').application.handle const tracer = require('../../../..') const handleAfterImport = require('express').application.handle @@ -14,5 +26,6 @@ describe('config/disabled_instrumentations', () => { expect(handleBefore).to.equal(handleAfterImport) expect(handleBefore).to.equal(handleAfterInit) + delete process.env.DD_TRACE_EXPRESS_ENABLED }) }) diff --git a/packages/dd-trace/test/opentracing/tracer.spec.js b/packages/dd-trace/test/opentracing/tracer.spec.js index 1a6ae261f0b..31e3df79a33 100644 --- a/packages/dd-trace/test/opentracing/tracer.spec.js +++ b/packages/dd-trace/test/opentracing/tracer.spec.js @@ -245,6 +245,40 @@ describe('Tracer', () => { expect(span.addTags).to.have.been.calledWith(fields.tags) }) + it('If span is granted a service name that differs from the global service name' + + 'ensure spans `version` tag is undefined.', () => { + config.tags = { + foo: 'tracer', + bar: 'tracer' + } + + fields.tags = { + bar: 'span', + baz: 'span', + service: 'new-service' + + } + + tracer = new Tracer(config) + const testSpan = tracer.startSpan('name', fields) + + expect(span.addTags).to.have.been.calledWith(config.tags) + expect(span.addTags).to.have.been.calledWith({ ...fields.tags, version: undefined }) + expect(Span).to.have.been.calledWith(tracer, processor, prioritySampler, { + operationName: 'name', + parent: null, + tags: { + 'service.name': 'new-service' + }, + startTime: fields.startTime, + hostname: undefined, + traceId128BitGenerationEnabled: undefined, + integrationName: undefined, + links: undefined + }) + expect(testSpan).to.equal(span) + }) + it('should start a span with the trace ID generation configuration', () => { config.traceId128BitGenerationEnabled = true tracer = new Tracer(config)