1
1
import { assertEquals } from 'https://deno.land/[email protected] /assert/mod.ts' ;
2
2
import { context , propagation , trace } from 'npm:@opentelemetry/api@1' ;
3
3
import type { DenoClient } from '../build/esm/index.js' ;
4
- import {
5
- flush ,
6
- getCurrentScope ,
7
- getGlobalScope ,
8
- getIsolationScope ,
9
- init ,
10
- vercelAIIntegration ,
11
- } from '../build/esm/index.js' ;
12
-
13
- function delay ( time : number ) : Promise < void > {
14
- return new Promise ( resolve => {
15
- setTimeout ( resolve , time ) ;
16
- } ) ;
17
- }
4
+ import { getCurrentScope , getGlobalScope , getIsolationScope , init , startSpan } from '../build/esm/index.js' ;
18
5
19
6
function resetGlobals ( ) : void {
20
7
getCurrentScope ( ) . clear ( ) ;
@@ -35,72 +22,124 @@ function resetSdk(): void {
35
22
cleanupOtel ( ) ;
36
23
}
37
24
38
- Deno . test ( 'opentelemetry: should capture spans emitted via @opentelemetry/api' , async _t => {
25
+ Deno . test ( 'should not capture spans emitted via @opentelemetry/api when skipOpenTelemetrySetup is true ' , async ( ) => {
39
26
resetSdk ( ) ;
40
- const events : any [ ] = [ ] ;
27
+ const transactionEvents : any [ ] = [ ] ;
41
28
42
- init ( {
29
+ const client = init ( {
43
30
dsn : 'https://username@domain/123' ,
44
- debug : true ,
45
31
tracesSampleRate : 1 ,
46
- skipOpenTelemetrySetup : false ,
47
- beforeSendTransaction ( event ) {
48
- events . push ( event ) ;
32
+ skipOpenTelemetrySetup : true ,
33
+ beforeSendTransaction : event => {
34
+ transactionEvents . push ( event ) ;
49
35
return null ;
50
36
} ,
51
- } ) ;
37
+ } ) as DenoClient ;
52
38
53
- const tracer = trace . getTracer ( 'test-tracer' ) ;
54
- const span = tracer . startSpan ( 'test span' ) ;
55
- span . setAttribute ( 'test.attribute' , 'test value' ) ;
39
+ const tracer = trace . getTracer ( 'test' ) ;
40
+ const span = tracer . startSpan ( 'test' ) ;
56
41
span . end ( ) ;
57
42
58
- await delay ( 200 ) ;
59
- await flush ( 1000 ) ;
43
+ await client . flush ( ) ;
44
+
45
+ tracer . startActiveSpan ( 'test 2' , { attributes : { 'test.attribute' : 'test' } } , span2 => {
46
+ const span = tracer . startSpan ( 'test 3' , { attributes : { 'test.attribute' : 'test2' } } ) ;
47
+ span . end ( ) ;
48
+ span2 . end ( ) ;
49
+ } ) ;
60
50
61
- assertEquals ( events . length , 1 ) ;
62
- const transactionEvent = events [ 0 ] ;
51
+ await client . flush ( ) ;
63
52
64
- assertEquals ( transactionEvent ?. transaction , 'test span' ) ;
65
- assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.deno_tracer' ] , true ) ;
66
- assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'test.attribute' ] , 'test value' ) ;
53
+ assertEquals ( transactionEvents . length , 0 ) ;
67
54
} ) ;
68
55
69
- Deno . test ( 'opentelemetry: should not capture spans when skipOpenTelemetrySetup is true ' , async ( ) => {
56
+ Deno . test ( 'should capture spans emitted via @opentelemetry/api ' , async ( ) => {
70
57
resetSdk ( ) ;
71
- const events : any [ ] = [ ] ;
58
+ const transactionEvents : any [ ] = [ ] ;
72
59
73
- init ( {
60
+ const client = init ( {
74
61
dsn : 'https://username@domain/123' ,
75
- debug : true ,
76
62
tracesSampleRate : 1 ,
77
- skipOpenTelemetrySetup : true ,
78
- beforeSendTransaction ( event ) {
79
- events . push ( event ) ;
63
+ beforeSendTransaction : event => {
64
+ transactionEvents . push ( event ) ;
80
65
return null ;
81
66
} ,
82
- } ) ;
67
+ } ) as DenoClient ;
83
68
84
- const tracer = trace . getTracer ( 'test-tracer ' ) ;
85
- const span = tracer . startSpan ( 'test span ' ) ;
69
+ const tracer = trace . getTracer ( 'test' ) ;
70
+ const span = tracer . startSpan ( 'test' ) ;
86
71
span . end ( ) ;
87
72
88
- await delay ( 200 ) ;
89
- await flush ( 1000 ) ;
73
+ await client . flush ( ) ;
90
74
91
- assertEquals ( events . length , 0 ) ;
75
+ tracer . startActiveSpan ( 'test 2' , { attributes : { 'test.attribute' : 'test' } } , span2 => {
76
+ const span = tracer . startSpan ( 'test 3' , { attributes : { 'test.attribute' : 'test2' } } ) ;
77
+ span . end ( ) ;
78
+ span2 . end ( ) ;
79
+ } ) ;
80
+
81
+ await client . flush ( ) ;
82
+
83
+ assertEquals ( transactionEvents . length , 2 ) ;
84
+ const [ transactionEvent , transactionEvent2 ] = transactionEvents ;
85
+
86
+ assertEquals ( transactionEvent ?. spans ?. length , 0 ) ;
87
+ assertEquals ( transactionEvent ?. transaction , 'test' ) ;
88
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.deno_tracer' ] , true ) ;
89
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.origin' ] , 'manual' ) ;
90
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.sample_rate' ] , 1 ) ;
91
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.source' ] , 'custom' ) ;
92
+
93
+ assertEquals ( transactionEvent2 ?. spans ?. length , 1 ) ;
94
+ assertEquals ( transactionEvent2 ?. transaction , 'test 2' ) ;
95
+ assertEquals ( transactionEvent2 ?. contexts ?. trace ?. data ?. [ 'sentry.deno_tracer' ] , true ) ;
96
+ assertEquals ( transactionEvent2 ?. contexts ?. trace ?. data ?. [ 'sentry.origin' ] , 'manual' ) ;
97
+ assertEquals ( transactionEvent2 ?. contexts ?. trace ?. data ?. [ 'sentry.sample_rate' ] , 1 ) ;
98
+ assertEquals ( transactionEvent2 ?. contexts ?. trace ?. data ?. [ 'sentry.source' ] , 'custom' ) ;
99
+ assertEquals ( transactionEvent2 ?. contexts ?. trace ?. data ?. [ 'test.attribute' ] , 'test' ) ;
100
+
101
+ const childSpan = transactionEvent2 ?. spans ?. [ 0 ] ;
102
+ assertEquals ( childSpan ?. description , 'test 3' ) ;
103
+ assertEquals ( childSpan ?. data ?. [ 'sentry.deno_tracer' ] , true ) ;
104
+ assertEquals ( childSpan ?. data ?. [ 'sentry.origin' ] , 'manual' ) ;
105
+ assertEquals ( childSpan ?. data ?. [ 'test.attribute' ] , 'test2' ) ;
92
106
} ) ;
93
107
94
- Deno . test ( 'opentelemetry: vercelAI integration can be added' , ( ) => {
108
+ Deno . test ( 'opentelemetry spans should interop with Sentry spans' , async ( ) => {
95
109
resetSdk ( ) ;
110
+ const transactionEvents : any [ ] = [ ] ;
111
+
96
112
const client = init ( {
97
113
dsn : 'https://username@domain/123' ,
98
- debug : true ,
99
114
tracesSampleRate : 1 ,
100
- integrations : [ vercelAIIntegration ( ) ] ,
115
+ beforeSendTransaction : event => {
116
+ transactionEvents . push ( event ) ;
117
+ return null ;
118
+ } ,
101
119
} ) as DenoClient ;
102
120
103
- // Just verify the integration can be added without errors
104
- const integration = client . getIntegrationByName ( 'VercelAI' ) ;
105
- assertEquals ( integration ?. name , 'VercelAI' ) ;
121
+ const tracer = trace . getTracer ( 'test' ) ;
122
+
123
+ startSpan ( { name : 'sentry span' } , ( ) => {
124
+ const span = tracer . startSpan ( 'otel span' ) ;
125
+ span . end ( ) ;
126
+ } ) ;
127
+
128
+ await client . flush ( ) ;
129
+
130
+ assertEquals ( transactionEvents . length , 1 ) ;
131
+ const [ transactionEvent ] = transactionEvents ;
132
+
133
+ assertEquals ( transactionEvent ?. spans ?. length , 1 ) ;
134
+ assertEquals ( transactionEvent ?. transaction , 'sentry span' ) ;
135
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.origin' ] , 'manual' ) ;
136
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.sample_rate' ] , 1 ) ;
137
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.source' ] , 'custom' ) ;
138
+ // Note: Sentry-created spans don't have the deno_tracer marker
139
+ assertEquals ( transactionEvent ?. contexts ?. trace ?. data ?. [ 'sentry.deno_tracer' ] , undefined ) ;
140
+
141
+ const otelSpan = transactionEvent ?. spans ?. [ 0 ] ;
142
+ assertEquals ( otelSpan ?. description , 'otel span' ) ;
143
+ assertEquals ( otelSpan ?. data ?. [ 'sentry.deno_tracer' ] , true ) ;
144
+ assertEquals ( otelSpan ?. data ?. [ 'sentry.origin' ] , 'manual' ) ;
106
145
} ) ;
0 commit comments