Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0d67dbc

Browse files
author
cod1k
committed
Expand setupOpenTelemetryTracer tests and enhance SentryCloudflareTracer error handling for optional tracer usage.
1 parent 7d7d3b9 commit 0d67dbc

File tree

2 files changed

+79
-11
lines changed

2 files changed

+79
-11
lines changed

‎packages/cloudflare/src/opentelemetry/tracer.ts‎

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1-
import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';
2-
import { ProxyTracerProvider,trace } from '@opentelemetry/api';
1+
import type { Context, ProxyTracerProvider,Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api';
2+
import { trace } from '@opentelemetry/api';
33
import { startInactiveSpan, startSpanManual } from '@sentry/core';
44

55
/**
66
* Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans.
77
* This is not perfect but handles easy/common use cases.
88
*/
99
export function setupOpenTelemetryTracer(): void {
10-
const current = trace.getTracerProvider();
11-
const delegate = current instanceof ProxyTracerProvider ? current.getDelegate() : current;
12-
trace.setGlobalTracerProvider(new SentryCloudflareTraceProvider(delegate));
10+
const result = trace.setGlobalTracerProvider(new SentryCloudflareTraceProvider());
11+
if (result) {
12+
return;
13+
}
14+
const current = trace.getTracerProvider() as ProxyTracerProvider;
15+
current.setDelegate(new SentryCloudflareTraceProvider(current.getDelegate()));
1316
}
1417

1518
class SentryCloudflareTraceProvider implements TracerProvider {
1619
private readonly _tracers: Map<string, Tracer> = new Map();
1720

18-
public constructor(private readonly _provider: TracerProvider) {}
21+
public constructor(private readonly _provider?: TracerProvider) {}
1922

2023
public getTracer(name: string, version?: string, options?: { schemaUrl?: string }): Tracer {
2124
const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`;
2225
if (!this._tracers.has(key)) {
23-
const tracer = this._provider.getTracer(key, version, options);
26+
const tracer = this._provider?.getTracer?.(key, version, options);
2427
this._tracers.set(key, new SentryCloudflareTracer(tracer));
2528
}
2629

@@ -30,9 +33,9 @@ class SentryCloudflareTraceProvider implements TracerProvider {
3033
}
3134

3235
class SentryCloudflareTracer implements Tracer {
33-
public constructor(private readonly _tracer: Tracer) {}
36+
public constructor(private readonly _tracer?: Tracer) {}
3437
public startSpan(name: string, options?: SpanOptions): Span {
35-
const topSpan = this._tracer.startSpan(name, options);
38+
const topSpan = this._tracer?.startSpan?.(name, options);
3639
const sentrySpan = startInactiveSpan({
3740
name,
3841
...options,
@@ -41,7 +44,18 @@ class SentryCloudflareTracer implements Tracer {
4144
'sentry.cloudflare_tracer': true,
4245
},
4346
});
47+
if (!topSpan) {
48+
return sentrySpan;
49+
}
4450
return new Proxy(sentrySpan, {
51+
set: (target, p, newValue, receiver) => {
52+
try {
53+
Reflect.set(topSpan, p, newValue, receiver);
54+
} catch {
55+
//
56+
}
57+
return Reflect.set(target, p, newValue);
58+
},
4559
get: (target, p) => {
4660
const propertyValue = Reflect.get(target, p);
4761
if (typeof propertyValue !== 'function') {
@@ -55,7 +69,7 @@ class SentryCloudflareTracer implements Tracer {
5569
apply: (target, thisArg, argArray) => {
5670
try {
5771
Reflect.apply(proxyTo, topSpan, argArray);
58-
} catch (e){
72+
} catch {
5973
//
6074
}
6175
return Reflect.apply(target, thisArg, argArray);

‎packages/cloudflare/test/opentelemetry.test.ts‎

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { trace } from '@opentelemetry/api';
22
import type { TransactionEvent } from '@sentry/core';
33
import { startSpan } from '@sentry/core';
4-
import { beforeEach, describe, expect, test } from 'vitest';
4+
import { beforeEach, describe, expect, test,vi } from 'vitest';
55
import { init } from '../src/sdk';
66
import { resetSdk } from './testUtils';
77

@@ -132,6 +132,60 @@ describe('opentelemetry compatibility', () => {
132132
'sentry.source': 'custom',
133133
});
134134

135+
expect(transactionEvent?.spans).toEqual([
136+
expect.objectContaining({
137+
description: 'otel span',
138+
data: {
139+
'sentry.cloudflare_tracer': true,
140+
'sentry.origin': 'manual',
141+
},
142+
}),
143+
]);
144+
});
145+
test('Ensure that sentry spans works over other opentelemetry implementations', async () => {
146+
const transactionEvents: TransactionEvent[] = [];
147+
const end = vi.fn();
148+
const _startSpan = vi.fn().mockImplementation(() => ({ end }));
149+
150+
const getTracer = vi.fn().mockImplementation(() => ({
151+
startSpan: _startSpan,
152+
}));
153+
trace.setGlobalTracerProvider({
154+
getTracer,
155+
});
156+
157+
const client = init({
158+
dsn: 'https://username@domain/123',
159+
tracesSampleRate: 1,
160+
beforeSendTransaction: event => {
161+
transactionEvents.push(event);
162+
return null;
163+
},
164+
});
165+
166+
const tracer = trace.getTracer('test');
167+
168+
expect(getTracer).toBeCalledWith('test@:', undefined, undefined);
169+
startSpan({ name: 'sentry span' }, () => {
170+
const span = tracer.startSpan('otel span');
171+
span.end();
172+
});
173+
expect(_startSpan).toBeCalledWith('otel span', undefined);
174+
expect(end).toBeCalled();
175+
176+
await client!.flush();
177+
178+
expect(transactionEvents).toHaveLength(1);
179+
const [transactionEvent] = transactionEvents;
180+
181+
expect(transactionEvent?.spans?.length).toBe(1);
182+
expect(transactionEvent?.transaction).toBe('sentry span');
183+
expect(transactionEvent?.contexts?.trace?.data).toEqual({
184+
'sentry.origin': 'manual',
185+
'sentry.sample_rate': 1,
186+
'sentry.source': 'custom',
187+
});
188+
135189
expect(transactionEvent?.spans).toEqual([
136190
expect.objectContaining({
137191
description: 'otel span',

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /