@multiplayer-app/session-recorder-common
v1.3.14
Published
Multiplayer Fullstack Session Recorder - opentelemetry
Downloads
1,581
Readme

Multiplayer Full Stack Session Recorder Common
This package provides implementations of the OpenTelemetry API for trace and metrics. It's intended for use both on the server and in the browser.
Built-in Implementations
Constants
import {
MULTIPLAYER_TRACE_DOC_PREFIX,
MULTIPLAYER_TRACE_DEBUG_PREFIX,
MULTIPLAYER_OTEL_DEFAULT_TRACES_EXPORTER_URL,
MULTIPLAYER_OTEL_DEFAULT_LOGS_EXPORTER_URL,
MULTIPLAYER_ATTRIBUTE_PREFIX,
MULTIPLAYER_MAX_HTTP_REQUEST_RESPONSE_SIZE,
ATTR_MULTIPLAYER_DEBUG_SESSION,
ATTR_MULTIPLAYER_HTTP_REQUEST_BODY,
ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY,
ATTR_MULTIPLAYER_HTTP_REQUEST_HEADERS,
ATTR_MULTIPLAYER_HTTP_RESPONSE_HEADERS,
ATTR_MULTIPLAYER_HTTP_RESPONSE_BODY_ENCODING,
ATTR_MULTIPLAYER_RPC_REQUEST_MESSAGE,
ATTR_MULTIPLAYER_RPC_RESPONSE_MESSAGE,
ATTR_MULTIPLAYER_GRPC_REQUEST_MESSAGE,
ATTR_MULTIPLAYER_GRPC_RESPONSE_MESSAGE,
ATTR_MULTIPLAYER_MESSAGING_MESSAGE_BODY
} from '@multiplayer-app/session-recorder-common'Setup opentelemetry for capturing http request/response body
Session Recorder hooks for nodejs http instrumentation for injecting http request/response headers and payload to span.
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
import { type Instrumentation } from '@opentelemetry/instrumentation'
import { SessionRecorderHttpInstrumentationHooks } from '@multiplayer-app/session-recorder-common'
export const instrumentations: Instrumentation[] = getNodeAutoInstrumentations({
'@opentelemetry/instrumentation-http': {
enabled: true,
responseHook: SessionRecorderHttpInstrumentationHooks.responseHook({
maxPayloadSizeBytes: 1000,
uncompressPayload: true,
captureHeaders: true,
captureBody: true,
isMaskBodyEnabled: true,
isMaskHeadersEnabled: true,
maskBody: (data, span) => {
// mask logic here
return data
},
maskHeaders: (data, span) => {
// mask logic here
return data
},
maskBodyFieldsList: ['password', 'card'],
maskHeadersList: ['x-trace-id'],
headersToInclude: ['Set-Cookie', 'Authorization'],
headersToExclude: ['Cookie'],
}),
requestHook: SessionRecorderHttpInstrumentationHooks.requestHook({
maxPayloadSizeBytes: 1000,
captureHeaders: true,
captureBody: true,
isMaskBodyEnabled: true,
isMaskHeadersEnabled: true,
maskBody: (data, span) => {
// mask logic here
return data
},
maskHeaders: (data, span) => {
// mask logic here
return data
},
maskBodyFieldsList: ['password', 'card'],
maskHeadersList: ['x-trace-id'],
headersToInclude: ['Set-Cookie', 'Authorization'],
headersToExclude: ['Cookie'],
}),
},
)Session Recorder Http Trace exporter web
import { BatchSpanProcessor, WebTracerProvider } from '@opentelemetry/sdk-trace-web'
import { SessionRecorderBrowserTraceExporter } from '@multiplayer-app/session-recorder-common'
const collectorOptions = {
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is https://api.multiplayer.app/v1/traces
apiKey: '<multiplayer-otlp-key>' // api key from multiplayer integration
}
const exporter = new SessionRecorderBrowserTraceExporter(collectorOptions)
const provider = new WebTracerProvider({
spanProcessors: [
new BatchSpanProcessor(exporter, {
// The maximum queue size. After the size is reached spans are dropped.
maxQueueSize: 100,
// The maximum batch size of every export. It must be smaller or equal to maxQueueSize.
maxExportBatchSize: 10,
// The interval between two consecutive exports
scheduledDelayMillis: 500,
// How long the export can run before it is cancelled
exportTimeoutMillis: 30000
})
]
})
provider.register()Session Recorder id generator
import { BatchSpanProcessor, WebTracerProvider } from '@opentelemetry/sdk-trace-web'
import { SessionRecorderIdGenerator, SessionRecorderBrowserTraceExporter } from '@multiplayer-app/session-recorder-common'
const idGenerator = new SessionRecorderIdGenerator({ autoDocTracesRatio: 0.05 })
const collectorOptions = {
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is https://api.multiplayer.app/v1/traces
apiKey: '<multiplayer-otlp-key>' // api key from multiplayer integration
}
const exporter = new SessionRecorderBrowserTraceExporter(collectorOptions)
const provider = new WebTracerProvider({
spanProcessors: [
new BatchSpanProcessor(exporter, {
// The maximum queue size. After the size is reached spans are dropped.
maxQueueSize: 100,
// The maximum batch size of every export. It must be smaller or equal to maxQueueSize.
maxExportBatchSize: 10,
// The interval between two consecutive exports
scheduledDelayMillis: 500,
// How long the export can run before it is cancelled
exportTimeoutMillis: 30000
})
],
idGenerator
})
idGenerator.setSessionId('<multiplayer-debug-session-short-id>')Trace id ratio based sampler
Session Recorder sampler will always sample traces with appropriate prefixes, other traces will be sampled using ration provided to constructor.
import { BatchSpanProcessor, WebTracerProvider } from '@opentelemetry/sdk-trace-web'
import {
SessionRecorderTraceIdRatioBasedSampler,
SessionRecorderBrowserTraceExporter
} from '@multiplayer-app/session-recorder-common'
const collectorOptions = {
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is https://api.multiplayer.app/v1/traces
apiKey: '<multiplayer-otlp-key>' // api key from multiplayer integration
}
const exporter = new SessionRecorderBrowserTraceExporter(collectorOptions)
const provider = new WebTracerProvider({
spanProcessors: [
new BatchSpanProcessor(exporter, {
// The maximum queue size. After the size is reached spans are dropped.
maxQueueSize: 100,
// The maximum batch size of every export. It must be smaller or equal to maxQueueSize.
maxExportBatchSize: 10,
// The interval between two consecutive exports
scheduledDelayMillis: 500,
// How long the export can run before it is cancelled
exportTimeoutMillis: 30000
})
],
sampler: new SessionRecorderTraceIdRatioBasedSampler(0.05)
})Helper for capturing exception in session recording
import { SessionRecorderSdk } from '@multiplayer-app/session-recorder-common'
const error = new Error('Some text here')
SessionRecorderSdk.captureException(error)Helpers for adding content to session recording
import { SessionRecorderSdk } from '@multiplayer-app/session-recorder-common'
SessionRecorderSdk.setAttribute('{{SOME_KEY}}', '{{SOME_VALUE}}')
// following helpers do masking of sensitive fields
SessionRecorderSdk.setHttpRequestBody('{{ANY_REQUEST_PAYLOAD_HERE}}')
SessionRecorderSdk.setHttpRequestHeaders({ Cookie: '...', Authorization: '...' })
SessionRecorderSdk.setHttpResponseBody({ some_payload: '{{ANY_REQUEST_PAYLOAD_HERE}}' })
SessionRecorderSdk.setHttpResponseHeaders({ 'Set-Cookie': '...' })
SessionRecorderSdk.setMessageBody({ some_payload: '{{ANY_REQUEST_PAYLOAD_HERE}}' })
SessionRecorderSdk.setRpcRequestMessage({ some_payload: '{{ANY_REQUEST_PAYLOAD_HERE}}' })
SessionRecorderSdk.setRpcResponseMessage({ some_payload: '{{ANY_REQUEST_PAYLOAD_HERE}}' })
SessionRecorderSdk.setGrpcRequestMessage({ some_payload: '{{ANY_REQUEST_PAYLOAD_HERE}}' })
SessionRecorderSdk.setGrpcResponseMessage({ some_payload: '{{ANY_REQUEST_PAYLOAD_HERE}}' })License
MIT - See LICENSE for more information.
