diff --git a/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts b/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts index 4df7f73f6c..f0e662389e 100644 --- a/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts +++ b/packages/opentelemetry-exporter-zipkin/test/common/transform.test.ts @@ -236,6 +236,40 @@ describe('transform', () => { version: '1', }); }); + it('should map OpenTelemetry constructor attributes to a Zipkin tag',()=>{ + const span = new Span( + tracer, + api.ROOT_CONTEXT, + 'my-span', + spanContext, + api.SpanKind.SERVER, + parentId, + [], + undefined, + undefined, + { + key1: 'value1', + key2: 'value2', + } + ); + const tags: zipkinTypes.Tags = _toZipkinTags( + span, + defaultStatusCodeTagName, + defaultStatusErrorTagName + ); + + assert.deepStrictEqual(tags, { + key1: 'value1', + key2: 'value2', + [SemanticResourceAttributes.SERVICE_NAME]: 'zipkin-test', + 'telemetry.sdk.language': language, + 'telemetry.sdk.name': 'opentelemetry', + 'telemetry.sdk.version': VERSION, + cost: '112.12', + service: 'ui', + version: '1', + }); + }) it('should map OpenTelemetry SpanStatus.code to a Zipkin tag', () => { const span = new Span( tracer, diff --git a/packages/opentelemetry-sdk-trace-base/src/Span.ts b/packages/opentelemetry-sdk-trace-base/src/Span.ts index 31fb1555ac..de076d6aea 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Span.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Span.ts @@ -100,13 +100,17 @@ export class Span implements APISpan, ReadableSpan { parentSpanId?: string, links: Link[] = [], startTime?: TimeInput, - _deprecatedClock?: unknown // keeping this argument even though it is unused to ensure backwards compatibility + _deprecatedClock?: unknown, // keeping this argument even though it is unused to ensure backwards compatibility + initAttributes?:SpanAttributes ) { this.name = spanName; this._spanContext = spanContext; this.parentSpanId = parentSpanId; this.kind = kind; this.links = links; + if(initAttributes){ + this.setAttributes(initAttributes); + } const now = Date.now(); this._performanceStartTime = otperformance.now(); diff --git a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts index b77a9427ec..972c226453 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Tracer.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Tracer.ts @@ -132,6 +132,12 @@ export class Tracer implements api.Tracer { return nonRecordingSpan; } + // Set initial span attributes. The attributes object may have been mutated + // by the sampler, so we sanitize the merged attributes before setting them. + const initAttributes = sanitizeAttributes( + Object.assign(attributes, samplingResult.attributes) + ); + const span = new Span( this, context, @@ -140,14 +146,10 @@ export class Tracer implements api.Tracer { spanKind, parentSpanId, links, - options.startTime - ); - // Set initial span attributes. The attributes object may have been mutated - // by the sampler, so we sanitize the merged attributes before setting them. - const initAttributes = sanitizeAttributes( - Object.assign(attributes, samplingResult.attributes) + options.startTime, + initAttributes ); - span.setAttributes(initAttributes); + return span; } diff --git a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts index 11a94ffc7c..e51254291a 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts @@ -1222,5 +1222,64 @@ describe('Span', () => { }); }); }); + + describe('when attributes are added in constructor', () => { + it('should not map undefined value', () => { + const span = new Span( + tracer, + ROOT_CONTEXT, + name, + spanContext, + SpanKind.CLIENT + ); + assert.deepStrictEqual(span.attributes,{}); + }); + + it('should map correctly sent keys', () => { + const span = new Span( + tracer, + ROOT_CONTEXT, + name, + spanContext, + SpanKind.CLIENT, + "", + [], + undefined, + undefined, + { + "key1":"value", + "key2":"value" + } + ); + assert.deepStrictEqual(span.attributes,{ + "key1":"value", + "key2":"value" + }); + }); + + it('should correctly map new keys set ', () => { + const span = new Span( + tracer, + ROOT_CONTEXT, + name, + spanContext, + SpanKind.CLIENT, + "", + [], + undefined, + undefined, + { + "key1":"value", + "key2":"value" + } + ); + span.setAttributes({"key3":"value"}); + assert.deepStrictEqual(span.attributes,{ + "key1":"value", + "key2":"value", + "key3":"value" + }); + }); + }); }); });