diff --git a/packages/dd-trace/src/opentracing/span.js b/packages/dd-trace/src/opentracing/span.js index 10c81a1eb95..8492c333978 100644 --- a/packages/dd-trace/src/opentracing/span.js +++ b/packages/dd-trace/src/opentracing/span.js @@ -34,7 +34,7 @@ const integrationCounters = { const startCh = channel('dd-trace:span:start') const finishCh = channel('dd-trace:span:finish') -function getIntegrationCounter (event, integration) { +function getIntegrationCounter (event, integration, version) { const counters = integrationCounters[event] if (integration in counters) { @@ -43,7 +43,9 @@ function getIntegrationCounter (event, integration) { const counter = tracerMetrics.count(event, [ `integration_name:${integration.toLowerCase()}`, - `otel_enabled:${OTEL_ENABLED}` + `otel_enabled:${OTEL_ENABLED}`, + `dependency_name:${integration}`, + `dependency_version:${version}` ]) integrationCounters[event][integration] = counter @@ -75,7 +77,7 @@ class DatadogSpan { this._name = operationName this._integrationName = fields.integrationName || 'opentracing' - getIntegrationCounter('spans_created', this._integrationName).inc() + getIntegrationCounter('spans_created', this._integrationName, tags['_dd.dependency_version']).inc() this._spanContext = this._createContext(parent, fields) this._spanContext._name = operationName @@ -239,7 +241,7 @@ class DatadogSpan { log.error('Finishing invalid span: %s', this) } - getIntegrationCounter('spans_finished', this._integrationName).inc() + getIntegrationCounter('spans_finished', this._integrationName, this._spanContext._tags['_dd.dependency_version']).inc() this._spanContext._tags['_dd.integration'] = this._integrationName if (DD_TRACE_EXPERIMENTAL_SPAN_COUNTS && finishedRegistry) { diff --git a/packages/dd-trace/src/opentracing/tracer.js b/packages/dd-trace/src/opentracing/tracer.js index 87f96d9b45a..77a69eb1dc1 100644 --- a/packages/dd-trace/src/opentracing/tracer.js +++ b/packages/dd-trace/src/opentracing/tracer.js @@ -54,7 +54,8 @@ class DatadogTracer { // as per spec, allow the setting of service name through options const tags = { - 'service.name': options?.tags?.service ? String(options.tags.service) : this._service + 'service.name': options?.tags?.service ? String(options.tags.service) : this._service, + ...options.tags } // As per unified service tagging spec if a span is created with a service name different from the global @@ -75,7 +76,6 @@ class DatadogTracer { }, this._debug) span.addTags(this._config.tags) - span.addTags(options.tags) return span } diff --git a/packages/dd-trace/src/plugins/tracing.js b/packages/dd-trace/src/plugins/tracing.js index f012f5546c8..d83a9c441a2 100644 --- a/packages/dd-trace/src/plugins/tracing.js +++ b/packages/dd-trace/src/plugins/tracing.js @@ -4,6 +4,7 @@ const Plugin = require('./plugin') const { storage } = require('../../../datadog-core') const analyticsSampler = require('../analytics_sampler') const { COMPONENT } = require('../constants') +const { detectedDependencyToVersion } = require('../telemetry/dependencies') class TracingPlugin extends Plugin { constructor (...args) { @@ -125,6 +126,8 @@ class TracingPlugin extends Plugin { childOf = store.span } + const dependencyVersion = detectedDependencyToVersion[this.component] + const span = tracer.startSpan(name, { startTime, childOf, @@ -134,6 +137,8 @@ class TracingPlugin extends Plugin { 'resource.name': resource, 'span.kind': kind, 'span.type': type, + '_dd.dependency_name': this.component, + '_dd.dependency_version': dependencyVersion, ...meta, ...metrics }, diff --git a/packages/dd-trace/src/telemetry/dependencies.js b/packages/dd-trace/src/telemetry/dependencies.js index 27c2f707921..5d6bf971e5d 100644 --- a/packages/dd-trace/src/telemetry/dependencies.js +++ b/packages/dd-trace/src/telemetry/dependencies.js @@ -12,6 +12,7 @@ const { isTrue } = require('../../src/util') const savedDependenciesToSend = new Set() const detectedDependencyKeys = new Set() const detectedDependencyVersions = new Set() +const detectedDependencyToVersion = {} const FILE_URI_START = 'file://' const moduleLoadStartChannel = dc.channel('dd-trace:moduleLoadStart') @@ -119,6 +120,7 @@ function onModuleLoad (data) { if (!detectedDependencyVersions.has(dependencyAndVersion)) { savedDependenciesToSend.add(`${dependencyAndVersion} ${initialLoad}`) detectedDependencyVersions.add(dependencyAndVersion) + detectedDependencyToVersion[name] = version waitAndSend(config, application, host) } @@ -171,4 +173,4 @@ function stop () { moduleLoadStartChannel.unsubscribe(onModuleLoad) } } -module.exports = { start, stop } +module.exports = { start, stop, detectedDependencyToVersion } diff --git a/packages/dd-trace/test/plugins/agent.js b/packages/dd-trace/test/plugins/agent.js index 0d992b10a6a..f6bb1ab59c8 100644 --- a/packages/dd-trace/test/plugins/agent.js +++ b/packages/dd-trace/test/plugins/agent.js @@ -9,6 +9,7 @@ const ritm = require('../../src/ritm') const { storage } = require('../../../datadog-core') const { assertObjectContains } = require('../../../../integration-tests/helpers') const { expect } = require('chai') +const { detectedDependencyToVersion } = require('../../src/telemetry/dependencies') const traceHandlers = new Set() const statsHandlers = new Set() @@ -247,6 +248,16 @@ function assertIntegrationName (args) { `Expected span to have "_dd.integration" tag "${currentIntegrationName}" but found "${span.meta['_dd.integration']}" for span ID ${span.span_id}` ) + expect(span.meta['_dd.dependency_version']).to.equal( + detectedDependencyToVersion[span.meta['_dd.dependency_name']], + `Expected span to have "_dd.dependency_version" tag "${detectedDependencyToVersion[span.meta['_dd.dependency_name']]}" + but found "${span.meta['_dd.dependency_version']}" for span ID ${span.span_id}` + ) + expect(span.meta['_dd.dependency_name']).to.equal( + span.meta['_dd.integration'], + `Expected span to have "_dd.dependency_name" tag "${span.meta['_dd.integration']}" + but found "${span.meta['_dd.dependency_name']}" for span ID ${span.span_id}` + ) } }) }