@@ -6,12 +6,16 @@ import type { ServerRuntimeClientOptions } from '@sentry/core';
6
6
import { SDK_VERSION , ServerRuntimeClient , applySdkMetadata } from '@sentry/core' ;
7
7
import { logger } from '@sentry/utils' ;
8
8
import { isMainThread , threadId } from 'worker_threads' ;
9
+ import { DEBUG_BUILD } from '../debug-build' ;
9
10
import type { NodeClientOptions } from '../types' ;
10
11
12
+ const CLIENT_REPORT_FLUSH_INTERVAL_MS = 60_000 ; // 60s was chosen arbitrarily
13
+
11
14
/** A client for using Sentry with Node & OpenTelemetry. */
12
15
export class NodeClient extends ServerRuntimeClient < NodeClientOptions > {
13
16
public traceProvider : BasicTracerProvider | undefined ;
14
17
private _tracer : Tracer | undefined ;
18
+ private _clientReportInterval : NodeJS . Timeout | undefined ;
15
19
16
20
public constructor ( options : NodeClientOptions ) {
17
21
const clientOptions : ServerRuntimeClientOptions = {
@@ -28,6 +32,18 @@ export class NodeClient extends ServerRuntimeClient<NodeClientOptions> {
28
32
) ;
29
33
30
34
super ( clientOptions ) ;
35
+
36
+ if ( clientOptions . sendClientReports !== false ) {
37
+ // There is one mild concern here, being that if users periodically and unboundedly create new clients, we will
38
+ // create more and more intervals, which may leak memory. In these situations, users are required to
39
+ // call `client.close()` in order to dispose of the client resource.
40
+ this . _clientReportInterval = setInterval ( ( ) => {
41
+ DEBUG_BUILD && logger . log ( 'Flushing client reports based on interval.' ) ;
42
+ this . _flushOutcomes ( ) ;
43
+ } , CLIENT_REPORT_FLUSH_INTERVAL_MS )
44
+ // Unref is critical, otherwise we stop the process from exiting by itself
45
+ . unref ( ) ;
46
+ }
31
47
}
32
48
33
49
/** Get the OTEL tracer. */
@@ -44,9 +60,8 @@ export class NodeClient extends ServerRuntimeClient<NodeClientOptions> {
44
60
return tracer ;
45
61
}
46
62
47
- /**
48
- * @inheritDoc
49
- */
63
+ // Eslint ignore explanation: This is already documented in super.
64
+ // eslint-disable-next-line jsdoc/require-jsdoc
50
65
public async flush ( timeout ?: number ) : Promise < boolean > {
51
66
const provider = this . traceProvider ;
52
67
const spanProcessor = provider ?. activeSpanProcessor ;
@@ -55,6 +70,18 @@ export class NodeClient extends ServerRuntimeClient<NodeClientOptions> {
55
70
await spanProcessor . forceFlush ( ) ;
56
71
}
57
72
73
+ this . _flushOutcomes ( ) ;
74
+
58
75
return super . flush ( timeout ) ;
59
76
}
77
+
78
+ // Eslint ignore explanation: This is already documented in super.
79
+ // eslint-disable-next-line jsdoc/require-jsdoc
80
+ public close ( timeout ?: number | undefined ) : PromiseLike < boolean > {
81
+ if ( this . _clientReportInterval ) {
82
+ clearInterval ( this . _clientReportInterval ) ;
83
+ }
84
+
85
+ return super . close ( timeout ) ;
86
+ }
60
87
}
0 commit comments