1
- import fs from 'fs' ;
2
1
import Span from './Span.js' ;
3
2
4
- export default class Tracer {
5
- private activeSpans : Map < string , Span > = new Map ( ) ;
6
- private spanFile = 'spans.json' ;
7
- private jsonlStream = fs . createWriteStream ( 'spans.jsonl' , { flags : 'a' } ) ;
3
+ class Tracer {
4
+ protected activeSpans : Map < string , Span > = new Map ( ) ;
5
+ protected queue : Array < Span > = [ ] ;
6
+ protected resolveWaitChunksP : ( ( ) => void ) | undefined ;
7
+ protected ended : boolean = false ;
8
+
9
+ protected queueSpan ( span : Span ) {
10
+ this . queue . push ( span ) ;
11
+ if ( this . resolveWaitChunksP != null ) this . resolveWaitChunksP ( ) ;
12
+ }
8
13
9
14
public startSpan ( name : string , parentSpanId ?: string ) : string {
10
15
const span = new Span ( name , parentSpanId ) ;
@@ -14,45 +19,31 @@ export default class Tracer {
14
19
this . activeSpans . get ( parentSpanId ) ! . children . push ( span ) ;
15
20
}
16
21
17
- this . saveSpansToFile ( ) ;
18
22
return span . spanId ;
19
23
}
20
24
21
- public endSpan ( spanId : string ) : Span | null {
25
+ public endSpan ( spanId : string ) : Span | undefined {
22
26
const span = this . activeSpans . get ( spanId ) ;
23
- if ( ! span ) return null ;
27
+ if ( ! span ) return ;
24
28
25
29
span . close ( ) ;
26
- this . jsonlStream . write ( JSON . stringify ( span . toJSON ( ) ) + '\n' ) ;
27
- this . saveSpansToFile ( ) ;
30
+ this . queueSpan ( span ) ;
28
31
return span ;
29
32
}
30
33
31
- public traced < T > (
34
+ public async traced < T > (
32
35
name : string ,
33
36
fn : ( ) => Promise < T > ,
34
37
parentSpanId ?: string ,
35
38
) : Promise < T > {
36
39
const spanId = this . startSpan ( name , parentSpanId ) ;
37
- return fn ( )
38
- . then ( ( result ) => {
39
- this . endSpan ( spanId ) ;
40
- return result ;
41
- } )
42
- . catch ( ( err ) => {
43
- this . endSpan ( spanId ) ;
44
- throw err ;
45
- } ) ;
40
+ return await fn ( ) . finally ( ( ) => this . endSpan ( spanId ) ) ;
46
41
}
47
42
48
- public getActiveSpans ( ) : Span [ ] {
43
+ public getActiveSpans ( ) : Array < Span > {
49
44
return Array . from ( this . activeSpans . values ( ) ) ;
50
45
}
51
46
52
- public flush ( ) : void {
53
- this . saveSpansToFile ( ) ;
54
- }
55
-
56
47
public getTraceJSON ( ) : string {
57
48
return JSON . stringify (
58
49
this . getActiveSpans ( ) . map ( ( s ) => s . toJSON ( ) ) ,
@@ -61,10 +52,23 @@ export default class Tracer {
61
52
) ;
62
53
}
63
54
64
- private saveSpansToFile ( ) : void {
65
- fs . writeFileSync (
66
- this . spanFile ,
67
- JSON . stringify ( this . getActiveSpans ( ) , null , 2 ) ,
68
- ) ;
55
+ public endTracing ( ) : void {
56
+ this . ended = true ;
57
+ }
58
+
59
+ public async * streamEvents ( ) : AsyncGenerator < Span , void , void > {
60
+ while ( true ) {
61
+ const value = this . queue . shift ( ) ;
62
+ if ( value == null ) {
63
+ if ( this . ended ) break ;
64
+ await new Promise < void > ( ( resolve ) => {
65
+ this . resolveWaitChunksP = resolve ;
66
+ } ) ;
67
+ continue ;
68
+ }
69
+ yield value ;
70
+ }
69
71
}
70
72
}
73
+
74
+ export default Tracer ;
0 commit comments