@multiplayer-app/session-recorder-common 1.3.17-session-buffering.0 → 1.3.18-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/SessionRecorderTraceIdRatioBasedSampler.d.ts.map +1 -1
- package/dist/esm/SessionRecorderTraceIdRatioBasedSampler.js +8 -2
- package/dist/esm/SessionRecorderTraceIdRatioBasedSampler.js.map +1 -1
- package/dist/esm/constants/constants.base.d.ts +1 -1
- package/dist/esm/constants/constants.base.js +2 -2
- package/dist/esm/constants/constants.base.js.map +1 -1
- package/dist/esm/exporters/SessionRecorderBrowserTraceExporter.d.ts +3 -1
- package/dist/esm/exporters/SessionRecorderBrowserTraceExporter.d.ts.map +1 -1
- package/dist/esm/exporters/SessionRecorderBrowserTraceExporter.js +22 -17
- package/dist/esm/exporters/SessionRecorderBrowserTraceExporter.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/type/crash-buffer.d.ts +59 -0
- package/dist/esm/type/crash-buffer.d.ts.map +1 -0
- package/dist/esm/type/crash-buffer.js +2 -0
- package/dist/esm/type/crash-buffer.js.map +1 -0
- package/dist/esm/type/index.d.ts +1 -0
- package/dist/esm/type/index.d.ts.map +1 -1
- package/dist/esm/type/index.js +1 -0
- package/dist/esm/type/index.js.map +1 -1
- package/dist/esnext/SessionRecorderTraceIdRatioBasedSampler.d.ts.map +1 -1
- package/dist/esnext/SessionRecorderTraceIdRatioBasedSampler.js +8 -2
- package/dist/esnext/SessionRecorderTraceIdRatioBasedSampler.js.map +1 -1
- package/dist/esnext/constants/constants.base.d.ts +1 -1
- package/dist/esnext/constants/constants.base.js +2 -2
- package/dist/esnext/constants/constants.base.js.map +1 -1
- package/dist/esnext/exporters/SessionRecorderBrowserTraceExporter.d.ts +3 -1
- package/dist/esnext/exporters/SessionRecorderBrowserTraceExporter.d.ts.map +1 -1
- package/dist/esnext/exporters/SessionRecorderBrowserTraceExporter.js +23 -19
- package/dist/esnext/exporters/SessionRecorderBrowserTraceExporter.js.map +1 -1
- package/dist/esnext/tsconfig.esnext.tsbuildinfo +1 -1
- package/dist/esnext/type/crash-buffer.d.ts +59 -0
- package/dist/esnext/type/crash-buffer.d.ts.map +1 -0
- package/dist/esnext/type/crash-buffer.js +2 -0
- package/dist/esnext/type/crash-buffer.js.map +1 -0
- package/dist/esnext/type/index.d.ts +1 -0
- package/dist/esnext/type/index.d.ts.map +1 -1
- package/dist/esnext/type/index.js +1 -0
- package/dist/esnext/type/index.js.map +1 -1
- package/dist/src/SessionRecorderTraceIdRatioBasedSampler.d.ts.map +1 -1
- package/dist/src/SessionRecorderTraceIdRatioBasedSampler.js +4 -1
- package/dist/src/SessionRecorderTraceIdRatioBasedSampler.js.map +1 -1
- package/dist/src/constants/constants.base.d.ts +1 -1
- package/dist/src/constants/constants.base.js +3 -3
- package/dist/src/constants/constants.base.js.map +1 -1
- package/dist/src/exporters/SessionRecorderBrowserTraceExporter.d.ts +3 -1
- package/dist/src/exporters/SessionRecorderBrowserTraceExporter.d.ts.map +1 -1
- package/dist/src/exporters/SessionRecorderBrowserTraceExporter.js +22 -18
- package/dist/src/exporters/SessionRecorderBrowserTraceExporter.js.map +1 -1
- package/dist/src/type/crash-buffer.d.ts +59 -0
- package/dist/src/type/crash-buffer.d.ts.map +1 -0
- package/dist/src/type/crash-buffer.js +3 -0
- package/dist/src/type/crash-buffer.js.map +1 -0
- package/dist/src/type/index.d.ts +1 -0
- package/dist/src/type/index.d.ts.map +1 -1
- package/dist/src/type/index.js +1 -0
- package/dist/src/type/index.js.map +1 -1
- package/package.json +1 -1
- package/src/SessionRecorderTraceIdRatioBasedSampler.ts +4 -0
- package/src/constants/constants.base.ts +2 -2
- package/src/exporters/SessionRecorderBrowserTraceExporter.ts +31 -25
- package/src/type/crash-buffer.ts +73 -0
- package/src/type/index.ts +2 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base'
|
|
2
|
+
import { ExportResult } from '@opentelemetry/core'
|
|
3
|
+
|
|
2
4
|
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
|
|
3
5
|
import {
|
|
4
6
|
MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_HTTP_URL,
|
|
5
7
|
MULTIPLAYER_TRACE_DEBUG_PREFIX,
|
|
6
|
-
MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX
|
|
8
|
+
MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX
|
|
7
9
|
} from '../constants/constants.base'
|
|
8
10
|
|
|
9
11
|
export interface SessionRecorderBrowserTraceExporterConfig {
|
|
@@ -48,7 +50,7 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
48
50
|
keepAlive = true,
|
|
49
51
|
concurrencyLimit = 20,
|
|
50
52
|
postMessageType = 'MULTIPLAYER_SESSION_DEBUGGER_LIB',
|
|
51
|
-
postMessageTargetOrigin = '*'
|
|
53
|
+
postMessageTargetOrigin = '*'
|
|
52
54
|
} = config
|
|
53
55
|
|
|
54
56
|
this.config = {
|
|
@@ -56,9 +58,9 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
56
58
|
url,
|
|
57
59
|
apiKey,
|
|
58
60
|
headers,
|
|
59
|
-
timeoutMillis,
|
|
60
61
|
keepAlive,
|
|
61
|
-
|
|
62
|
+
timeoutMillis,
|
|
63
|
+
concurrencyLimit
|
|
62
64
|
}
|
|
63
65
|
this.postMessageType = postMessageType
|
|
64
66
|
this.postMessageTargetOrigin = postMessageTargetOrigin
|
|
@@ -66,15 +68,14 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
66
68
|
this.exporter = this._createExporter()
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
export(
|
|
70
|
-
spans: ReadableSpan[],
|
|
71
|
-
resultCallback: (result: { code: number }) => void,
|
|
72
|
-
): void {
|
|
71
|
+
export(spans: ReadableSpan[], resultCallback: (result: { code: number }) => void): void {
|
|
73
72
|
// Filter spans to only include those with Multiplayer trace prefixes
|
|
74
|
-
const filteredSpans = spans.filter(span => {
|
|
73
|
+
const filteredSpans = spans.filter((span) => {
|
|
75
74
|
const traceId = span.spanContext().traceId
|
|
76
|
-
return
|
|
75
|
+
return (
|
|
76
|
+
traceId.startsWith(MULTIPLAYER_TRACE_DEBUG_PREFIX) ||
|
|
77
77
|
traceId.startsWith(MULTIPLAYER_TRACE_CONTINUOUS_DEBUG_PREFIX)
|
|
78
|
+
)
|
|
78
79
|
})
|
|
79
80
|
|
|
80
81
|
// Only proceed if there are filtered spans
|
|
@@ -104,6 +105,14 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
104
105
|
return this.exporter.shutdown()
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
exportBuffer(spans: ReadableSpan[]): Promise<ExportResult | undefined> {
|
|
109
|
+
return new Promise((resolve) => {
|
|
110
|
+
this.exporter.export(spans, (result) => {
|
|
111
|
+
resolve(result)
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
|
|
107
116
|
private exportViaPostMessage(spans: ReadableSpan[], resultCallback: (result: { code: number }) => void): void {
|
|
108
117
|
if (typeof window === 'undefined') {
|
|
109
118
|
resultCallback({ code: 1 })
|
|
@@ -115,9 +124,9 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
115
124
|
{
|
|
116
125
|
action: 'traces',
|
|
117
126
|
type: this.postMessageType,
|
|
118
|
-
payload: spans.map(span => this.
|
|
127
|
+
payload: spans.map((span) => this.serializeSpan(span))
|
|
119
128
|
},
|
|
120
|
-
this.postMessageTargetOrigin
|
|
129
|
+
this.postMessageTargetOrigin
|
|
121
130
|
)
|
|
122
131
|
resultCallback({ code: 0 })
|
|
123
132
|
} catch (e) {
|
|
@@ -125,7 +134,7 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
125
134
|
}
|
|
126
135
|
}
|
|
127
136
|
|
|
128
|
-
|
|
137
|
+
serializeSpan(span: ReadableSpan): any {
|
|
129
138
|
const spanContext = span.spanContext()
|
|
130
139
|
return {
|
|
131
140
|
_spanContext: spanContext,
|
|
@@ -136,17 +145,15 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
136
145
|
events: span.events,
|
|
137
146
|
status: span.status,
|
|
138
147
|
endTime: span.endTime,
|
|
139
|
-
|
|
148
|
+
resource: span.resource,
|
|
140
149
|
duration: span.duration,
|
|
150
|
+
startTime: span.startTime,
|
|
141
151
|
attributes: span.attributes,
|
|
142
|
-
parentSpanId: span.parentSpanContext?.spanId,
|
|
143
|
-
droppedAttributesCount: span.droppedAttributesCount,
|
|
144
|
-
droppedEventsCount: span.droppedEventsCount,
|
|
145
152
|
droppedLinksCount: span.droppedLinksCount,
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
153
|
+
parentSpanContext: span.parentSpanContext,
|
|
154
|
+
droppedEventsCount: span.droppedEventsCount,
|
|
155
|
+
instrumentationScope: span.instrumentationScope,
|
|
156
|
+
droppedAttributesCount: span.droppedAttributesCount
|
|
150
157
|
}
|
|
151
158
|
}
|
|
152
159
|
|
|
@@ -155,18 +162,17 @@ export class SessionRecorderBrowserTraceExporter implements SpanExporter {
|
|
|
155
162
|
url: this.config.url,
|
|
156
163
|
headers: {
|
|
157
164
|
'Content-Type': 'application/json',
|
|
158
|
-
...(this.config.apiKey ? {
|
|
159
|
-
...(this.config.headers || {})
|
|
165
|
+
...(this.config.apiKey ? { Authorization: this.config.apiKey } : {}),
|
|
166
|
+
...(this.config.headers || {})
|
|
160
167
|
},
|
|
161
168
|
timeoutMillis: this.config.timeoutMillis,
|
|
162
169
|
keepAlive: this.config.keepAlive,
|
|
163
|
-
concurrencyLimit: this.config.concurrencyLimit
|
|
170
|
+
concurrencyLimit: this.config.concurrencyLimit
|
|
164
171
|
})
|
|
165
172
|
}
|
|
166
173
|
|
|
167
174
|
setApiKey(apiKey: string): void {
|
|
168
175
|
this.config.apiKey = apiKey
|
|
169
|
-
|
|
170
176
|
this.exporter = this._createExporter()
|
|
171
177
|
}
|
|
172
178
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export type CrashBufferAttrs = {
|
|
2
|
+
sessionAttributes?: Record<string, any>
|
|
3
|
+
resourceAttributes?: Record<string, any>
|
|
4
|
+
userAttributes?: any
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type CrashBufferRrwebEventPayload = {
|
|
8
|
+
ts: number
|
|
9
|
+
isFullSnapshot?: boolean
|
|
10
|
+
event: any
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type CrashBufferOtelSpanPayload = {
|
|
14
|
+
ts: number
|
|
15
|
+
span: any
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Batch append payload for OTEL spans.
|
|
20
|
+
* This is intentionally the same per-span shape as `CrashBufferOtelSpanPayload`,
|
|
21
|
+
* just provided as an array to allow implementations to persist efficiently.
|
|
22
|
+
*/
|
|
23
|
+
export type CrashBufferOtelSpanBatchPayload = CrashBufferOtelSpanPayload[]
|
|
24
|
+
|
|
25
|
+
export type CrashBufferErrorSpanAppendedEvent = CrashBufferOtelSpanPayload
|
|
26
|
+
|
|
27
|
+
export type CrashBufferEventName = 'error-span-appended'
|
|
28
|
+
|
|
29
|
+
export type CrashBufferEventMap = {
|
|
30
|
+
'error-span-appended': CrashBufferErrorSpanAppendedEvent
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type CrashBufferSnapshot = {
|
|
34
|
+
rrwebEvents: CrashBufferRrwebEventPayload[]
|
|
35
|
+
otelSpans: CrashBufferOtelSpanPayload[]
|
|
36
|
+
attrs: CrashBufferAttrs | null
|
|
37
|
+
windowMs: number
|
|
38
|
+
fromTs: number
|
|
39
|
+
toTs: number
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Shared CrashBuffer contract used across browser + react-native implementations.
|
|
44
|
+
*
|
|
45
|
+
* Notes:
|
|
46
|
+
* - `windowMs` is optional because browser implementations usually bake the window into the instance,
|
|
47
|
+
* while React Native typically passes it per call.
|
|
48
|
+
* - `pruneOlderThan` is optional because browser implementations can handle pruning internally.
|
|
49
|
+
*/
|
|
50
|
+
export interface CrashBuffer {
|
|
51
|
+
setAttrs(attrs: CrashBufferAttrs): Promise<void>
|
|
52
|
+
appendEvent(payload: CrashBufferRrwebEventPayload, windowMs?: number): Promise<void>
|
|
53
|
+
appendSpans(payload: CrashBufferOtelSpanBatchPayload, windowMs?: number): Promise<void>
|
|
54
|
+
snapshot(windowMs?: number, now?: number): Promise<CrashBufferSnapshot>
|
|
55
|
+
clear(): Promise<void>
|
|
56
|
+
pruneOlderThan?(cutoffTs: number): Promise<void>
|
|
57
|
+
on?(
|
|
58
|
+
event: CrashBufferEventName,
|
|
59
|
+
listener: (payload: CrashBufferEventMap[CrashBufferEventName]) => void
|
|
60
|
+
): () => void
|
|
61
|
+
off?(
|
|
62
|
+
event: CrashBufferEventName,
|
|
63
|
+
listener: (payload: CrashBufferEventMap[CrashBufferEventName]) => void
|
|
64
|
+
): void
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Optional lifecycle controls supported by some CrashBuffer implementations (e.g. browser tabs).
|
|
69
|
+
*/
|
|
70
|
+
export interface CrashBufferLifecycle extends CrashBuffer {
|
|
71
|
+
setActive(active: boolean): void
|
|
72
|
+
needsFullSnapshot(): boolean
|
|
73
|
+
}
|
package/src/type/index.ts
CHANGED