diff --git a/packages/dd-trace/src/format.js b/packages/dd-trace/src/format.js index 3009ab571da..ccb81c0208b 100644 --- a/packages/dd-trace/src/format.js +++ b/packages/dd-trace/src/format.js @@ -7,9 +7,6 @@ const { isError } = require('./util') const { registerExtraService } = require('./service-naming/extra-services') const SAMPLING_PRIORITY_KEY = constants.SAMPLING_PRIORITY_KEY -const SAMPLING_RULE_DECISION = constants.SAMPLING_RULE_DECISION -const SAMPLING_LIMIT_DECISION = constants.SAMPLING_LIMIT_DECISION -const SAMPLING_AGENT_DECISION = constants.SAMPLING_AGENT_DECISION const SPAN_SAMPLING_MECHANISM = constants.SPAN_SAMPLING_MECHANISM const SPAN_SAMPLING_RULE_RATE = constants.SPAN_SAMPLING_RULE_RATE const SPAN_SAMPLING_MAX_PER_SECOND = constants.SPAN_SAMPLING_MAX_PER_SECOND @@ -17,7 +14,6 @@ const SAMPLING_MECHANISM_SPAN = constants.SAMPLING_MECHANISM_SPAN const { MEASURED, BASE_SERVICE, ANALYTICS } = tags const ORIGIN_KEY = constants.ORIGIN_KEY const HOSTNAME_KEY = constants.HOSTNAME_KEY -const TOP_LEVEL_KEY = constants.TOP_LEVEL_KEY const PROCESS_ID = constants.PROCESS_ID const ERROR_MESSAGE = constants.ERROR_MESSAGE const ERROR_STACK = constants.ERROR_STACK @@ -37,8 +33,6 @@ function format (span) { extractSpanLinks(formatted, span) extractSpanEvents(formatted, span) - extractRootTags(formatted, span) - extractChunkTags(formatted, span) extractTags(formatted, span) return formatted @@ -179,30 +173,6 @@ function extractTags (formattedSpan, span) { addTag(formattedSpan.meta, formattedSpan.metrics, HOSTNAME_KEY, hostname) } -function extractRootTags (formattedSpan, span) { - const context = span.context() - const isLocalRoot = span === context._trace.started[0] - const parentId = context._parentId - - if (!isLocalRoot || (parentId && parentId.toString(10) !== '0')) return - - addTag({}, formattedSpan.metrics, SAMPLING_RULE_DECISION, context._trace[SAMPLING_RULE_DECISION]) - addTag({}, formattedSpan.metrics, SAMPLING_LIMIT_DECISION, context._trace[SAMPLING_LIMIT_DECISION]) - addTag({}, formattedSpan.metrics, SAMPLING_AGENT_DECISION, context._trace[SAMPLING_AGENT_DECISION]) - addTag({}, formattedSpan.metrics, TOP_LEVEL_KEY, 1) -} - -function extractChunkTags (formattedSpan, span) { - const context = span.context() - const isLocalRoot = span === context._trace.started[0] - - if (!isLocalRoot) return - - for (const [key, value] of Object.entries(context._trace.tags)) { - addTag(formattedSpan.meta, formattedSpan.metrics, key, value) - } -} - function extractError (formattedSpan, error) { if (!error) return diff --git a/packages/dd-trace/src/opentracing/span.js b/packages/dd-trace/src/opentracing/span.js index 41c0988c82f..8439d13a3ec 100644 --- a/packages/dd-trace/src/opentracing/span.js +++ b/packages/dd-trace/src/opentracing/span.js @@ -77,9 +77,8 @@ class DatadogSpan { getIntegrationCounter('spans_created', this._integrationName).inc() - this._spanContext = this._createContext(parent, fields) + this._spanContext = this._createContext(parent, fields, tags) this._spanContext._name = operationName - this._spanContext._tags = tags this._spanContext._hostname = hostname this._spanContext._trace.started.push(this) @@ -328,7 +327,7 @@ class DatadogSpan { return sanitizedAttributes } - _createContext (parent, fields) { + _createContext (parent, fields, tags) { let spanContext let startTime @@ -343,6 +342,7 @@ class DatadogSpan { if (!spanContext._trace.startTime) { startTime = dateNow() } + Object.assign(spanContext._tags, tags) } else if (parent) { spanContext = new SpanContext({ traceId: parent._traceId, @@ -351,7 +351,8 @@ class DatadogSpan { sampling: parent._sampling, baggageItems: { ...parent._baggageItems }, trace: parent._trace, - tracestate: parent._tracestate + tracestate: parent._tracestate, + tags }) if (!spanContext._trace.startTime) { @@ -362,7 +363,8 @@ class DatadogSpan { startTime = dateNow() spanContext = new SpanContext({ traceId: spanId, - spanId + spanId, + tags }) spanContext._trace.startTime = startTime diff --git a/packages/dd-trace/src/opentracing/span_context.js b/packages/dd-trace/src/opentracing/span_context.js index b6d37164dbe..930edafb517 100644 --- a/packages/dd-trace/src/opentracing/span_context.js +++ b/packages/dd-trace/src/opentracing/span_context.js @@ -3,9 +3,28 @@ const util = require('util') const { AUTO_KEEP } = require('../../../../ext/priority') +const { + SAMPLING_RULE_DECISION, + SAMPLING_LIMIT_DECISION, + SAMPLING_AGENT_DECISION, + TOP_LEVEL_KEY +} = require('../constants'); + // the lowercase, hex encoded upper 64 bits of a 128-bit trace id, if present const TRACE_ID_128 = '_dd.p.tid' +function getChunkRoot (self) { + return self._trace.started[0]?.context() || self +} + +function assignRootTag (self, prop, val) { + const chunkRoot = getChunkRoot(self) + if (!chunkRoot._parentId || chunkRoot._parentId.toString(10) === '0') { + chunkRoot._tags[SAMPLING_RULE_DECISION] = val + chunkRoot._tags[TOP_LEVEL_KEY] = 1 + } +} + class DatadogSpanContext { constructor (props) { props = props || {} @@ -24,14 +43,35 @@ class DatadogSpanContext { this._traceparent = props.traceparent this._tracestate = props.tracestate this._noop = props.noop || null + const self = this this._trace = props.trace || { started: [], finished: [], - tags: {} + set [SAMPLING_RULE_DECISION] (val) { + assignRootTag(self, SAMPLING_RULE_DECISION, val) + }, + set [SAMPLING_LIMIT_DECISION] (val) { + assignRootTag(self, SAMPLING_LIMIT_DECISION, val) + }, + set [SAMPLING_AGENT_DECISION] (val) { + assignRootTag(self, SAMPLING_AGENT_DECISION, val) + } + } + if (!props.trace) { + Object.defineProperty(this._trace, 'tags', { + enumerable: true, + get () { + return (self._trace.started[0]?.context() || self)._tags + } + }) } this._otelSpanContext = undefined } + setChunkTag (name, val) { + this._trace.started[0].setTag(name, val) + } + [util.inspect.custom] () { return { ...this, diff --git a/packages/dd-trace/test/format.spec.js b/packages/dd-trace/test/format.spec.js index e1b3a5517c8..52a8301f83b 100644 --- a/packages/dd-trace/test/format.spec.js +++ b/packages/dd-trace/test/format.spec.js @@ -15,9 +15,6 @@ const SAMPLING_PRIORITY_KEY = constants.SAMPLING_PRIORITY_KEY const MEASURED = tags.MEASURED const ORIGIN_KEY = constants.ORIGIN_KEY const HOSTNAME_KEY = constants.HOSTNAME_KEY -const SAMPLING_AGENT_DECISION = constants.SAMPLING_AGENT_DECISION -const SAMPLING_LIMIT_DECISION = constants.SAMPLING_LIMIT_DECISION -const SAMPLING_RULE_DECISION = constants.SAMPLING_RULE_DECISION const SPAN_SAMPLING_MECHANISM = constants.SPAN_SAMPLING_MECHANISM const SPAN_SAMPLING_RULE_RATE = constants.SPAN_SAMPLING_RULE_RATE const SPAN_SAMPLING_MAX_PER_SECOND = constants.SPAN_SAMPLING_MAX_PER_SECOND @@ -180,35 +177,6 @@ describe('format', () => { expect(trace.resource).to.equal('resource') }) - it('should extract Datadog specific root tags', () => { - spanContext._parentId = null - spanContext._trace[SAMPLING_AGENT_DECISION] = 0.8 - spanContext._trace[SAMPLING_LIMIT_DECISION] = 0.2 - spanContext._trace[SAMPLING_RULE_DECISION] = 0.5 - - trace = format(span) - - expect(trace.metrics).to.include({ - [SAMPLING_AGENT_DECISION]: 0.8, - [SAMPLING_LIMIT_DECISION]: 0.2, - [SAMPLING_RULE_DECISION]: 0.5 - }) - }) - - it('should not extract Datadog specific root tags from non-root spans', () => { - spanContext._trace[SAMPLING_AGENT_DECISION] = 0.8 - spanContext._trace[SAMPLING_LIMIT_DECISION] = 0.2 - spanContext._trace[SAMPLING_RULE_DECISION] = 0.5 - - trace = format(span) - - expect(trace.metrics).to.not.have.keys( - SAMPLING_AGENT_DECISION, - SAMPLING_LIMIT_DECISION, - SAMPLING_RULE_DECISION - ) - }) - it('should always add single span ingestion tags from options if present', () => { spanContext._spanSampling = { maxPerSecond: 5, @@ -287,40 +255,6 @@ describe('format', () => { }]) }) - it('should extract trace chunk tags', () => { - spanContext._trace.tags = { - chunk: 'test', - count: 1 - } - - trace = format(span) - - expect(trace.meta).to.include({ - chunk: 'test' - }) - - expect(trace.metrics).to.include({ - count: 1 - }) - }) - - it('should extract empty tags', () => { - spanContext._trace.tags = { - foo: '', - count: 1 - } - - trace = format(span) - - expect(trace.meta).to.include({ - foo: '' - }) - - expect(trace.metrics).to.include({ - count: 1 - }) - }) - it('should discard user-defined tags with name HOSTNAME_KEY by default', () => { spanContext._tags[HOSTNAME_KEY] = 'some_hostname' diff --git a/packages/dd-trace/test/opentracing/propagation/log.spec.js b/packages/dd-trace/test/opentracing/propagation/log.spec.js index 81371ed75d7..4d0ba0abda6 100644 --- a/packages/dd-trace/test/opentracing/propagation/log.spec.js +++ b/packages/dd-trace/test/opentracing/propagation/log.spec.js @@ -182,12 +182,8 @@ describe('LogPropagator', () => { expect(spanContext).to.deep.equal(new SpanContext({ traceId: id('1234567812345678', 16), spanId: id('456', 10), - trace: { - started: [], - finished: [], - tags: { - '_dd.p.tid': '8765432187654321' - } + tags: { + '_dd.p.tid': '8765432187654321' } })) }) diff --git a/packages/dd-trace/test/opentracing/propagation/text_map.spec.js b/packages/dd-trace/test/opentracing/propagation/text_map.spec.js index 077788d3a27..ac021b1d371 100644 --- a/packages/dd-trace/test/opentracing/propagation/text_map.spec.js +++ b/packages/dd-trace/test/opentracing/propagation/text_map.spec.js @@ -30,18 +30,21 @@ describe('TextMapPropagator', () => { let telemetryMetrics const createContext = (params = {}) => { - const trace = { started: [], finished: [], tags: {} } - const spanContext = new SpanContext({ + const options = { traceId: id('123', 10), spanId: id('456', 10), isRemote: params.isRemote === undefined ? true : params.isRemote, baggageItems, ...params, - trace: { + } + if (params.trace) { + const trace = { started: [], finished: [], tags: {} } + options.trace = { ...trace, ...params.trace } - }) + } + const spanContext = new SpanContext(options) return spanContext } @@ -1201,10 +1204,8 @@ describe('TextMapPropagator', () => { expect(spanContext).to.deep.equal(createContext({ traceId: id('00000000000002340000000000000123', 16), spanId: id('456', 16), - trace: { - tags: { - '_dd.p.tid': '0000000000000234' - } + tags: { + '_dd.p.tid': '0000000000000234' } })) }) diff --git a/packages/dd-trace/test/opentracing/span_context.spec.js b/packages/dd-trace/test/opentracing/span_context.spec.js index c29d2ccd779..905f7a1f7e5 100644 --- a/packages/dd-trace/test/opentracing/span_context.spec.js +++ b/packages/dd-trace/test/opentracing/span_context.spec.js @@ -86,6 +86,9 @@ describe('SpanContext', () => { _trace: { started: [], finished: [], + '_dd.rule_psr': undefined, + '_dd.limit_psr': undefined, + '_dd.agent_psr': undefined, tags: {} }, _traceparent: undefined,