| 61 | * still active and modifyable when child spans are added to the buffer. |
| 62 | */ |
| 63 | export class SpanBuffer { |
| 64 | /* Bucket spans by their trace id, along with accumulated size and a per-trace flush timeout */ |
| 65 | private _traceBuckets: Map<string, TraceBucket>; |
| 66 | |
| 67 | private _client: Client; |
| 68 | private _maxSpanLimit: number; |
| 69 | private _flushInterval: number; |
| 70 | private _maxTraceWeight: number; |
| 71 | |
| 72 | public constructor(client: Client, options?: SpanBufferOptions) { |
| 73 | this._traceBuckets = new Map(); |
| 74 | this._client = client; |
| 75 | |
| 76 | const { maxSpanLimit, flushInterval, maxTraceWeightInBytes } = options ?? {}; |
| 77 | |
| 78 | this._maxSpanLimit = |
| 79 | maxSpanLimit && maxSpanLimit > 0 && maxSpanLimit <= MAX_SPANS_PER_ENVELOPE |
| 80 | ? maxSpanLimit |
| 81 | : MAX_SPANS_PER_ENVELOPE; |
| 82 | this._flushInterval = flushInterval && flushInterval > 0 ? flushInterval : 5_000; |
| 83 | this._maxTraceWeight = |
| 84 | maxTraceWeightInBytes && maxTraceWeightInBytes > 0 ? maxTraceWeightInBytes : MAX_TRACE_WEIGHT_IN_BYTES; |
| 85 | |
| 86 | this._client.on('flush', () => { |
| 87 | this.drain(); |
| 88 | }); |
| 89 | |
| 90 | this._client.on('close', () => { |
| 91 | // No need to drain the buffer here as `Client.close()` internally already calls `Client.flush()` |
| 92 | // which already invokes the `flush` hook and thus drains the buffer. |
| 93 | this._traceBuckets.forEach(bucket => { |
| 94 | clearTimeout(bucket.timeout); |
| 95 | }); |
| 96 | this._traceBuckets.clear(); |
| 97 | }); |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Add a span to the buffer. |
| 102 | */ |
| 103 | public add(spanJSON: SerializedStreamedSpanWithSegmentSpan): void { |
| 104 | const traceId = spanJSON.trace_id; |
| 105 | let bucket = this._traceBuckets.get(traceId); |
| 106 | |
| 107 | if (!bucket) { |
| 108 | bucket = { |
| 109 | spans: new Set(), |
| 110 | size: 0, |
| 111 | timeout: safeUnref( |
| 112 | setTimeout(() => { |
| 113 | this.flush(traceId); |
| 114 | }, this._flushInterval), |
| 115 | ), |
| 116 | }; |
| 117 | this._traceBuckets.set(traceId, bucket); |
| 118 | } |
| 119 | |
| 120 | bucket.spans.add(spanJSON); |
nothing calls this directly
no outgoing calls
no test coverage detected