1
- import { Span as SpanInterface } from '@sentry/types' ;
1
+ import { Span as SpanInterface , SpanDetails } from '@sentry/types' ;
2
2
import { uuid4 } from '@sentry/utils' ;
3
3
4
4
export const TRACEPARENT_REGEXP = / ^ [ \t ] * ( [ 0 - 9 a - f ] { 32 } ) ? - ? ( [ 0 - 9 a - f ] { 16 } ) ? - ? ( [ 0 1 ] ) ? [ \t ] * $ / ;
@@ -7,71 +7,168 @@ export const TRACEPARENT_REGEXP = /^[ \t]*([0-9a-f]{32})?-?([0-9a-f]{16})?-?([01
7
7
* Span containg all data about a span
8
8
*/
9
9
export class Span implements SpanInterface {
10
- public constructor (
11
- private readonly _traceId : string = uuid4 ( ) ,
12
- private readonly _spanId : string = uuid4 ( ) . substring ( 16 ) ,
13
- private _sampled ?: boolean ,
14
- private _parent ?: Span ,
15
- ) { }
10
+ /**
11
+ * Trace ID
12
+ */
13
+ private readonly _traceId : string = uuid4 ( ) ;
16
14
17
15
/**
18
- * Setter for parent
16
+ * Span ID
19
17
*/
20
- public setParent ( parent : Span | undefined ) : this {
21
- this . _parent = parent ;
22
- return this ;
18
+ private readonly _spanId : string = uuid4 ( ) . substring ( 16 ) ;
19
+
20
+ /**
21
+ * Parent Span ID
22
+ */
23
+ private readonly _parentSpanId ?: string ;
24
+
25
+ /**
26
+ * Has the sampling decision been made?
27
+ */
28
+ public readonly sampled ?: string ;
29
+
30
+ /**
31
+ * Timestamp when the span was created.
32
+ */
33
+ public readonly startTimestamp : number = new Date ( ) . getTime ( ) ;
34
+
35
+ /**
36
+ * Finish timestamp of the span.
37
+ */
38
+ public timestamp ?: number ;
39
+
40
+ /**
41
+ * Set the transaction of the Span.
42
+ */
43
+ public transaction ?: string ;
44
+
45
+ /**
46
+ * Set the operation of the Span.
47
+ */
48
+ public op ?: string ;
49
+
50
+ /**
51
+ * Set the description of the Span.
52
+ */
53
+ public description ?: string ;
54
+
55
+ /**
56
+ * List of spans that were finalized
57
+ */
58
+ public finishedSpans : Span [ ] = [ ] ;
59
+
60
+ public constructor ( spanDetails ?: SpanDetails ) {
61
+ if ( ! spanDetails ) {
62
+ return this ;
63
+ }
64
+
65
+ if ( spanDetails . traceId ) {
66
+ this . _traceId = spanDetails . traceId ;
67
+ }
68
+ if ( spanDetails . spanId ) {
69
+ this . _spanId = spanDetails . spanId ;
70
+ }
71
+ if ( spanDetails . parentSpanId ) {
72
+ this . _parentSpanId = spanDetails . parentSpanId ;
73
+ }
74
+ if ( spanDetails . sampled ) {
75
+ this . sampled = spanDetails . sampled ;
76
+ }
77
+ if ( spanDetails . transaction ) {
78
+ this . transaction = spanDetails . transaction ;
79
+ }
80
+ if ( spanDetails . op ) {
81
+ this . op = spanDetails . op ;
82
+ }
83
+ if ( spanDetails . description ) {
84
+ this . description = spanDetails . description ;
85
+ }
86
+ }
87
+
88
+ /** JSDoc */
89
+ public newSpan ( spanDetails ?: Pick < SpanDetails , Exclude < keyof SpanDetails , 'spanId' > > ) : Span {
90
+ const span = new Span ( {
91
+ ...spanDetails ,
92
+ parentSpanId : this . _parentSpanId ,
93
+ sampled : this . sampled ,
94
+ traceId : this . _traceId ,
95
+ } ) ;
96
+
97
+ span . finishedSpans = this . finishedSpans ;
98
+
99
+ return span ;
23
100
}
24
101
25
102
/**
26
- * Setter for sampled
103
+ * Setter for transaction.
27
104
*/
28
- public setSampled ( sampled : boolean | undefined ) : this {
29
- this . _sampled = sampled ;
105
+ public setTransaction ( transaction : string | undefined ) : this {
106
+ this . transaction = transaction ;
30
107
return this ;
31
108
}
32
109
33
110
/**
34
111
* Continues a trace
35
112
* @param traceparent Traceparent string
36
113
*/
37
- public static fromTraceparent ( traceparent : string ) : Span | undefined {
114
+ public static fromTraceparent (
115
+ traceparent : string ,
116
+ spanDetails ?: Pick < SpanDetails , Exclude < keyof SpanDetails , 'spanId' | 'sampled' | 'traceid' > > ,
117
+ ) : Span | undefined {
38
118
const matches = traceparent . match ( TRACEPARENT_REGEXP ) ;
39
119
if ( matches ) {
40
- let sampled ;
41
- if ( matches [ 3 ] === '1' ) {
42
- sampled = true ;
43
- } else if ( matches [ 3 ] === '0' ) {
44
- sampled = false ;
45
- }
46
- const parent = new Span ( matches [ 1 ] , matches [ 2 ] , sampled ) ;
47
- return new Span ( matches [ 1 ] , undefined , sampled , parent ) ;
120
+ const [ traceId , spanId , sampled ] = matches ;
121
+ return new Span ( {
122
+ ...spanDetails ,
123
+ sampled,
124
+ spanId,
125
+ traceId,
126
+ } ) ;
48
127
}
49
128
return undefined ;
50
129
}
51
130
131
+ /**
132
+ * Sets the finish timestamp on the current span
133
+ */
134
+ public finish ( ) : void {
135
+ this . timestamp = new Date ( ) . getTime ( ) ;
136
+ this . finishedSpans . push ( this ) ;
137
+ }
138
+
52
139
/**
53
140
* @inheritDoc
54
141
*/
55
142
public toTraceparent ( ) : string {
56
- let sampled = '' ;
57
- if ( this . _sampled === true ) {
58
- sampled = '-1' ;
59
- } else if ( this . _sampled === false ) {
60
- sampled = '-0' ;
61
- }
62
-
63
- return `${ this . _traceId } -${ this . _spanId } ${ sampled } ` ;
143
+ return `${ this . _traceId } -${ this . _spanId } ${ this . sampled ? '-1' : '0' } ` ;
144
+ }
145
+ /**
146
+ * @inheritDoc
147
+ */
148
+ public getTraceContext ( ) : object {
149
+ return {
150
+ description : this . description ,
151
+ op : this . op ,
152
+ parent_span_id : this . _parentSpanId ,
153
+ span_id : this . _spanId ,
154
+ trace_id : this . _traceId ,
155
+ } ;
64
156
}
65
157
66
158
/**
67
159
* @inheritDoc
68
160
*/
69
161
public toJSON ( ) : object {
70
162
return {
71
- parent : ( this . _parent && this . _parent . toJSON ( ) ) || undefined ,
72
- sampled : this . _sampled ,
163
+ description : this . description ,
164
+ op : this . op ,
165
+ parent_span_id : this . _parentSpanId ,
166
+ sampled : this . sampled ,
73
167
span_id : this . _spanId ,
168
+ start_timestamp : this . startTimestamp ,
169
+ timestamp : this . timestamp ,
74
170
trace_id : this . _traceId ,
171
+ transaction : this . transaction ,
75
172
} ;
76
173
}
77
174
}
0 commit comments