diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dc1a62b0095..7580c5984251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - [apm] feat: Add a simple heartbeat check, if activities don't change in 3 beats, finish the transaction (#2478) - [apm] feat: Make use of the `performance` browser API to provide better instrumentation (#2474) - [browser] ref: Move global error handler + unhandled promise rejection to instrument (#2475) +- [apm] fix: Add trace context to all events (#2486) ## 5.13.2 diff --git a/packages/apm/src/span.ts b/packages/apm/src/span.ts index f5ae63c2ed0c..08da86bac3fc 100644 --- a/packages/apm/src/span.ts +++ b/packages/apm/src/span.ts @@ -359,13 +359,13 @@ export class Span implements SpanInterface, SpanContext { */ public getTraceContext(): object { return dropUndefinedKeys({ - data: this.data, + data: Object.keys(this.data).length > 0 ? this.data : undefined, description: this.description, op: this.op, parent_span_id: this._parentSpanId, span_id: this._spanId, status: this.tags.status, - tags: this.tags, + tags: Object.keys(this.tags).length > 0 ? this.tags : undefined, trace_id: this._traceId, }); } @@ -375,14 +375,14 @@ export class Span implements SpanInterface, SpanContext { */ public toJSON(): object { return dropUndefinedKeys({ - data: this.data, + data: Object.keys(this.data).length > 0 ? this.data : undefined, description: this.description, op: this.op, parent_span_id: this._parentSpanId, sampled: this.sampled, span_id: this._spanId, start_timestamp: this.startTimestamp, - tags: this.tags, + tags: Object.keys(this.tags).length > 0 ? this.tags : undefined, timestamp: this.timestamp, trace_id: this._traceId, transaction: this.transaction, diff --git a/packages/apm/test/span.test.ts b/packages/apm/test/span.test.ts index 2a36f1ca97ab..ee641c276426 100644 --- a/packages/apm/test/span.test.ts +++ b/packages/apm/test/span.test.ts @@ -167,11 +167,9 @@ describe('Span', () => { expect(serialized).toHaveProperty('start_timestamp'); delete (serialized as { start_timestamp: number }).start_timestamp; expect(serialized).toStrictEqual({ - data: {}, parent_span_id: 'b', sampled: false, span_id: 'd', - tags: {}, trace_id: 'c', }); }); @@ -257,9 +255,7 @@ describe('Span', () => { const spanB = new Span({ spanId: 'd', traceId: 'c' }); const context = spanB.getTraceContext(); expect(context).toStrictEqual({ - data: {}, span_id: 'd', - tags: {}, trace_id: 'c', }); }); diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index e108e5d9b9ca..66c2067fa4cf 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -332,6 +332,9 @@ export class Scope implements ScopeInterface { if (this._transaction) { event.transaction = this._transaction; } + if (this._span) { + event.contexts = { trace: this._span.getTraceContext(), ...event.contexts }; + } this._applyFingerprint(event); diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts index 3628961d0409..73f4a48e7c4f 100644 --- a/packages/hub/test/scope.test.ts +++ b/packages/hub/test/scope.test.ts @@ -245,6 +245,38 @@ describe('Scope', () => { }); }); + test('applyToEvent trace context', async () => { + expect.assertions(1); + const scope = new Scope(); + const span = { + fake: 'span', + getTraceContext: () => ({ a: 'b' }), + } as any; + scope.setSpan(span); + const event: Event = {}; + return scope.applyToEvent(event).then(processedEvent => { + expect((processedEvent!.contexts!.trace as any).a).toEqual('b'); + }); + }); + + test('applyToEvent existing trace context in event should be stronger', async () => { + expect.assertions(1); + const scope = new Scope(); + const span = { + fake: 'span', + getTraceContext: () => ({ a: 'b' }), + } as any; + scope.setSpan(span); + const event: Event = { + contexts: { + trace: { a: 'c' }, + }, + }; + return scope.applyToEvent(event).then(processedEvent => { + expect((processedEvent!.contexts!.trace as any).a).toEqual('c'); + }); + }); + test('clear', () => { const scope = new Scope(); scope.setExtra('a', 2);