Skip to content

Commit b8c8b65

Browse files
committed
Remove SDK-side enrichment and redundant op/origin backfill
1 parent d0cb9d0 commit b8c8b65

2 files changed

Lines changed: 7 additions & 202 deletions

File tree

packages/core/src/tracing/spans/spanJsonToStreamedSpan.ts

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,11 @@
11
import type { RawAttributes } from '../../attributes';
2-
import type { Client } from '../../client';
3-
import {
4-
SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT,
5-
SEMANTIC_ATTRIBUTE_SENTRY_OP,
6-
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
7-
SEMANTIC_ATTRIBUTE_SENTRY_RELEASE,
8-
SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME,
9-
SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION,
10-
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID,
11-
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,
12-
SEMANTIC_ATTRIBUTE_USER_EMAIL,
13-
SEMANTIC_ATTRIBUTE_USER_ID,
14-
SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS,
15-
SEMANTIC_ATTRIBUTE_USER_USERNAME,
16-
} from '../../semanticAttributes';
17-
import type { Event } from '../../types-hoist/event';
182
import type { SerializedStreamedSpan, SpanJSON, StreamedSpanJSON } from '../../types-hoist/span';
193
import { streamedSpanJsonToSerializedSpan } from '../../utils/spanUtils';
20-
import { safeSetSpanJSONAttributes } from './captureSpan';
214

225
/**
236
* Converts a v1 SpanJSON (from a legacy transaction) to a serialized v2 StreamedSpan.
247
*/
25-
export function spanJsonToSerializedStreamedSpan(
26-
span: SpanJSON,
27-
transactionEvent: Event,
28-
client: Client,
29-
): SerializedStreamedSpan {
8+
export function spanJsonToSerializedStreamedSpan(span: SpanJSON): SerializedStreamedSpan {
309
const streamedSpan: StreamedSpanJSON = {
3110
trace_id: span.trace_id,
3211
span_id: span.span_id,
@@ -40,33 +19,6 @@ export function spanJsonToSerializedStreamedSpan(
4019
links: span.links,
4120
};
4221

43-
// Fold op and origin into attributes
44-
safeSetSpanJSONAttributes(streamedSpan, {
45-
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: span.op,
46-
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: span.origin,
47-
});
48-
49-
// Enrich from transaction event context (same pattern as captureSpan.ts applyCommonSpanAttributes)
50-
const sdk = client.getSdkMetadata();
51-
const { release, environment, sendDefaultPii } = client.getOptions();
52-
53-
safeSetSpanJSONAttributes(streamedSpan, {
54-
[SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: transactionEvent.release || release,
55-
[SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: transactionEvent.environment || environment,
56-
[SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]: transactionEvent.transaction,
57-
[SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]: transactionEvent.contexts?.trace?.span_id,
58-
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]: sdk?.sdk?.name,
59-
[SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]: sdk?.sdk?.version,
60-
...(sendDefaultPii
61-
? {
62-
[SEMANTIC_ATTRIBUTE_USER_ID]: transactionEvent.user?.id,
63-
[SEMANTIC_ATTRIBUTE_USER_EMAIL]: transactionEvent.user?.email,
64-
[SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]: transactionEvent.user?.ip_address,
65-
[SEMANTIC_ATTRIBUTE_USER_USERNAME]: transactionEvent.user?.username,
66-
}
67-
: {}),
68-
});
69-
7022
return streamedSpanJsonToSerializedSpan(streamedSpan);
7123
}
7224

packages/core/test/lib/tracing/spans/spanJsonToStreamedSpan.test.ts

Lines changed: 6 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,6 @@
11
import { describe, expect, it } from 'vitest';
2-
import {
3-
SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT,
4-
SEMANTIC_ATTRIBUTE_SENTRY_OP,
5-
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
6-
SEMANTIC_ATTRIBUTE_SENTRY_RELEASE,
7-
SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME,
8-
SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION,
9-
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID,
10-
SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME,
11-
SEMANTIC_ATTRIBUTE_USER_EMAIL,
12-
SEMANTIC_ATTRIBUTE_USER_ID,
13-
SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS,
14-
SEMANTIC_ATTRIBUTE_USER_USERNAME,
15-
} from '../../../../src';
16-
import type { Event } from '../../../../src/types-hoist/event';
172
import type { SpanJSON } from '../../../../src/types-hoist/span';
183
import { spanJsonToSerializedStreamedSpan } from '../../../../src/tracing/spans/spanJsonToStreamedSpan';
19-
import { getDefaultTestClientOptions, TestClient } from '../../../mocks/client';
204

215
function makeSpanJSON(overrides: Partial<SpanJSON> = {}): SpanJSON {
226
return {
@@ -28,31 +12,6 @@ function makeSpanJSON(overrides: Partial<SpanJSON> = {}): SpanJSON {
2812
};
2913
}
3014

31-
function makeTransactionEvent(overrides: Partial<Event> = {}): Event {
32-
return {
33-
type: 'transaction',
34-
transaction: 'GET /api/chat',
35-
release: '1.0.0',
36-
environment: 'production',
37-
contexts: {
38-
trace: {
39-
span_id: 'root0000deadbeef',
40-
trace_id: '00112233445566778899aabbccddeeff',
41-
},
42-
},
43-
...overrides,
44-
};
45-
}
46-
47-
function makeClient(options: Partial<Parameters<typeof getDefaultTestClientOptions>[0]> = {}): TestClient {
48-
return new TestClient(
49-
getDefaultTestClientOptions({
50-
dsn: 'https://dsn@ingest.f00.f00/1',
51-
...options,
52-
}),
53-
);
54-
}
55-
5615
describe('spanJsonToSerializedStreamedSpan', () => {
5716
it('maps basic SpanJSON fields to StreamedSpan fields', () => {
5817
const span = makeSpanJSON({
@@ -64,7 +23,7 @@ describe('spanJsonToSerializedStreamedSpan', () => {
6423
parent_span_id: 'parent00deadbeef',
6524
});
6625

67-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), makeClient());
26+
const result = spanJsonToSerializedStreamedSpan(span);
6827

6928
expect(result.name).toBe('chat gpt-4');
7029
expect(result.start_timestamp).toBe(1000);
@@ -77,14 +36,12 @@ describe('spanJsonToSerializedStreamedSpan', () => {
7736
});
7837

7938
it('uses empty string for name when description is undefined', () => {
80-
const span = makeSpanJSON({ description: undefined });
81-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), makeClient());
39+
const result = spanJsonToSerializedStreamedSpan(makeSpanJSON({ description: undefined }));
8240
expect(result.name).toBe('');
8341
});
8442

8543
it('uses start_timestamp as end_timestamp when timestamp is undefined', () => {
86-
const span = makeSpanJSON({ timestamp: undefined });
87-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), makeClient());
44+
const result = spanJsonToSerializedStreamedSpan(makeSpanJSON({ timestamp: undefined }));
8845
expect(result.end_timestamp).toBe(1000);
8946
});
9047

@@ -99,24 +56,11 @@ describe('spanJsonToSerializedStreamedSpan', () => {
9956
];
10057

10158
for (const [v1Status, expected] of cases) {
102-
const span = makeSpanJSON({ status: v1Status });
103-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), makeClient());
59+
const result = spanJsonToSerializedStreamedSpan(makeSpanJSON({ status: v1Status }));
10460
expect(result.status).toBe(expected);
10561
}
10662
});
10763

108-
it('folds op and origin into attributes', () => {
109-
const span = makeSpanJSON({
110-
op: 'gen_ai.chat',
111-
origin: 'auto.ai.openai',
112-
});
113-
114-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), makeClient());
115-
116-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_OP]).toEqual({ type: 'string', value: 'gen_ai.chat' });
117-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]).toEqual({ type: 'string', value: 'auto.ai.openai' });
118-
});
119-
12064
it('preserves existing span data attributes', () => {
12165
const span = makeSpanJSON({
12266
data: {
@@ -127,111 +71,20 @@ describe('spanJsonToSerializedStreamedSpan', () => {
12771
},
12872
});
12973

130-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), makeClient());
74+
const result = spanJsonToSerializedStreamedSpan(span);
13175

13276
expect(result.attributes?.['gen_ai.system']).toEqual({ type: 'string', value: 'openai' });
13377
expect(result.attributes?.['gen_ai.request.model']).toEqual({ type: 'string', value: 'gpt-4' });
13478
expect(result.attributes?.['gen_ai.usage.input_tokens']).toEqual({ type: 'integer', value: 100 });
13579
expect(result.attributes?.['gen_ai.usage.output_tokens']).toEqual({ type: 'integer', value: 50 });
13680
});
13781

138-
it('enriches with transaction event context', () => {
139-
const span = makeSpanJSON();
140-
const event = makeTransactionEvent({
141-
release: '2.0.0',
142-
environment: 'staging',
143-
transaction: 'POST /api/generate',
144-
contexts: { trace: { span_id: 'segment0deadbeef' } },
145-
});
146-
147-
const result = spanJsonToSerializedStreamedSpan(span, event, makeClient());
148-
149-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]).toEqual({ type: 'string', value: '2.0.0' });
150-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]).toEqual({ type: 'string', value: 'staging' });
151-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_NAME]).toEqual({
152-
type: 'string',
153-
value: 'POST /api/generate',
154-
});
155-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SEGMENT_ID]).toEqual({
156-
type: 'string',
157-
value: 'segment0deadbeef',
158-
});
159-
});
160-
161-
it('enriches with SDK metadata', () => {
162-
const client = makeClient();
163-
client.getOptions()._metadata = { sdk: { name: 'sentry.javascript.node', version: '9.0.0' } };
164-
165-
const span = makeSpanJSON();
166-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), client);
167-
168-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SDK_NAME]).toEqual({
169-
type: 'string',
170-
value: 'sentry.javascript.node',
171-
});
172-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SDK_VERSION]).toEqual({ type: 'string', value: '9.0.0' });
173-
});
174-
175-
it('adds user attributes when sendDefaultPii is true', () => {
176-
const client = makeClient({ sendDefaultPii: true });
177-
const event = makeTransactionEvent({
178-
user: { id: 'u123', email: 'a@b.com', ip_address: '1.2.3.4', username: 'alice' },
179-
});
180-
181-
const span = makeSpanJSON();
182-
const result = spanJsonToSerializedStreamedSpan(span, event, client);
183-
184-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_USER_ID]).toEqual({ type: 'string', value: 'u123' });
185-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_USER_EMAIL]).toEqual({ type: 'string', value: 'a@b.com' });
186-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_USER_IP_ADDRESS]).toEqual({ type: 'string', value: '1.2.3.4' });
187-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_USER_USERNAME]).toEqual({ type: 'string', value: 'alice' });
188-
});
189-
190-
it('does not add user attributes when sendDefaultPii is false', () => {
191-
const client = makeClient({ sendDefaultPii: false });
192-
const event = makeTransactionEvent({
193-
user: { id: 'u123', email: 'a@b.com' },
194-
});
195-
196-
const span = makeSpanJSON();
197-
const result = spanJsonToSerializedStreamedSpan(span, event, client);
198-
199-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_USER_ID]).toBeUndefined();
200-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_USER_EMAIL]).toBeUndefined();
201-
});
202-
203-
it('does not overwrite pre-existing span data attributes with enrichment', () => {
204-
const span = makeSpanJSON({
205-
data: {
206-
[SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]: 'span-level-release',
207-
[SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]: 'span-level-env',
208-
},
209-
});
210-
211-
const event = makeTransactionEvent({
212-
release: 'event-level-release',
213-
environment: 'event-level-env',
214-
});
215-
216-
const result = spanJsonToSerializedStreamedSpan(span, event, makeClient());
217-
218-
// Span-level values should win
219-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_RELEASE]).toEqual({
220-
type: 'string',
221-
value: 'span-level-release',
222-
});
223-
expect(result.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ENVIRONMENT]).toEqual({
224-
type: 'string',
225-
value: 'span-level-env',
226-
});
227-
});
228-
22982
it('carries over links', () => {
23083
const span = makeSpanJSON({
23184
links: [{ trace_id: 'aabb', span_id: 'ccdd', sampled: true, attributes: { foo: 'bar' } }],
23285
});
23386

234-
const result = spanJsonToSerializedStreamedSpan(span, makeTransactionEvent(), makeClient());
87+
const result = spanJsonToSerializedStreamedSpan(span);
23588

23689
expect(result.links).toEqual([
23790
{ trace_id: 'aabb', span_id: 'ccdd', sampled: true, attributes: { foo: { type: 'string', value: 'bar' } } },

0 commit comments

Comments
 (0)