UNPKG

@coralogix/browser

Version:

Official Coralogix SDK for browsers

1,193 lines (1,148 loc) 214 kB
import { __assign, __extends, __awaiter, __generator, __read as __read$1, __spreadArray, __rest, __values as __values$1 } from 'tslib'; import { SamplingDecision, AlwaysOnSampler, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'; import { getElementXPath, WebTracerProvider } from '@opentelemetry/sdk-trace-web'; import { InstrumentationBase, registerInstrumentations } from '@opentelemetry/instrumentation'; import ErrorStackParser from 'error-stack-parser'; import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch'; import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request'; import { onFID, onCLS, onLCP, onFCP, onINP, onTTFB } from 'web-vitals/attribution'; import { createContextKey, baggageEntryMetadataFromString, propagation, diag, trace, isSpanContextValid, TraceFlags, context } from '@opentelemetry/api'; import { B3Propagator, B3InjectEncoding } from '@opentelemetry/propagator-b3'; import { AWSXRayPropagator } from '@opentelemetry/propagator-aws-xray'; function isString(value) { return typeof value === 'string'; } function isRegExp(value) { return value instanceof RegExp; } function isMatchingPattern(value, pattern, requireExactStringMatch) { if (requireExactStringMatch === undefined) { requireExactStringMatch = false; } if (!isString(value)) { return false; } if (isRegExp(pattern)) { return pattern.test(value); } if (isString(pattern)) { return requireExactStringMatch ? value === pattern : value.includes(pattern); } return false; } function stringMatchesSomePattern(testString, patterns, requireExactStringMatch) { if (patterns === undefined) { patterns = []; } if (requireExactStringMatch === undefined) { requireExactStringMatch = false; } return patterns.some(function (pattern) { return isMatchingPattern(testString, pattern, requireExactStringMatch); }); } /** * UUID v4 * https://gist.github.com/jed/982883 */ function generateUUID(placeholder) { return placeholder ? (+placeholder ^ ((Math.random() * 16) >> (+placeholder / 4))).toString(16) : "".concat(1e7, "-").concat(1e3, "-").concat(4e3, "-").concat(8e3, "-").concat(1e11).replace(/[018]/g, generateUUID); } function isFunction (funktion) { return typeof funktion === 'function' } // Default to complaining loudly when things don't go according to plan. var logger = console.error.bind(console); // Sets a property on an object, preserving its enumerability. // This function assumes that the property is already writable. function defineProperty (obj, name, value) { var enumerable = !!obj[name] && obj.propertyIsEnumerable(name); Object.defineProperty(obj, name, { configurable: true, enumerable: enumerable, writable: true, value: value }); } // Keep initialization idempotent. function shimmer (options) { if (options && options.logger) { if (!isFunction(options.logger)) logger("new logger isn't a function, not replacing"); else logger = options.logger; } } function wrap (nodule, name, wrapper) { if (!nodule || !nodule[name]) { logger('no original function ' + name + ' to wrap'); return } if (!wrapper) { logger('no wrapper function'); logger((new Error()).stack); return } if (!isFunction(nodule[name]) || !isFunction(wrapper)) { logger('original object and wrapper must be functions'); return } var original = nodule[name]; var wrapped = wrapper(original, name); defineProperty(wrapped, '__original', original); defineProperty(wrapped, '__unwrap', function () { if (nodule[name] === wrapped) defineProperty(nodule, name, original); }); defineProperty(wrapped, '__wrapped', true); defineProperty(nodule, name, wrapped); return wrapped } function massWrap (nodules, names, wrapper) { if (!nodules) { logger('must provide one or more modules to patch'); logger((new Error()).stack); return } else if (!Array.isArray(nodules)) { nodules = [nodules]; } if (!(names && Array.isArray(names))) { logger('must provide one or more functions to wrap on modules'); return } nodules.forEach(function (nodule) { names.forEach(function (name) { wrap(nodule, name, wrapper); }); }); } function unwrap (nodule, name) { if (!nodule || !nodule[name]) { logger('no function to unwrap.'); logger((new Error()).stack); return } if (!nodule[name].__unwrap) { logger('no original to unwrap to -- has ' + name + ' already been unwrapped?'); } else { return nodule[name].__unwrap() } } function massUnwrap (nodules, names) { if (!nodules) { logger('must provide one or more modules to patch'); logger((new Error()).stack); return } else if (!Array.isArray(nodules)) { nodules = [nodules]; } if (!(names && Array.isArray(names))) { logger('must provide one or more functions to unwrap on modules'); return } nodules.forEach(function (nodule) { names.forEach(function (name) { unwrap(nodule, name); }); }); } shimmer.wrap = wrap; shimmer.massWrap = massWrap; shimmer.unwrap = unwrap; shimmer.massUnwrap = massUnwrap; var shimmer_1 = shimmer; var CoralogixEventType; (function (CoralogixEventType) { CoralogixEventType["ERROR"] = "error"; CoralogixEventType["NETWORK_REQUEST"] = "network-request"; CoralogixEventType["LOG"] = "log"; CoralogixEventType["USER_INTERACTION"] = "user-interaction"; CoralogixEventType["WEB_VITALS"] = "web-vitals"; CoralogixEventType["LONG_TASK"] = "longtask"; CoralogixEventType["RESOURCES"] = "resources"; CoralogixEventType["INTERNAL"] = "internal"; CoralogixEventType["DOM"] = "dom"; CoralogixEventType["CUSTOM_MEASUREMENT"] = "custom-measurement"; CoralogixEventType["MEMORY_USAGE"] = "memory-usage"; CoralogixEventType["SCREENSHOT"] = "screenshot"; CoralogixEventType["CUSTOM_SPAN"] = "custom-span"; })(CoralogixEventType || (CoralogixEventType = {})); var PerformanceTypes; (function (PerformanceTypes) { PerformanceTypes["Resource"] = "resource"; PerformanceTypes["LongTask"] = "longtask"; PerformanceTypes["Navigation"] = "navigation"; PerformanceTypes["SoftNavigation"] = "soft-navigation"; })(PerformanceTypes || (PerformanceTypes = {})); var OtelNetworkAttrs; (function (OtelNetworkAttrs) { OtelNetworkAttrs["METHOD"] = "http.method"; OtelNetworkAttrs["URL"] = "http.url"; OtelNetworkAttrs["STATUS_CODE"] = "http.status_code"; OtelNetworkAttrs["HOST"] = "http.host"; OtelNetworkAttrs["SCHEME"] = "http.scheme"; OtelNetworkAttrs["STATUS_TEXT"] = "http.status_text"; OtelNetworkAttrs["RESPONSE_CONTENT_LENGTH"] = "http.response_content_length"; })(OtelNetworkAttrs || (OtelNetworkAttrs = {})); var UrlType; (function (UrlType) { UrlType["PAGE"] = "page"; UrlType["NETWORK_REQUEST"] = "network_request"; })(UrlType || (UrlType = {})); var CoralogixLogSeverity; (function (CoralogixLogSeverity) { CoralogixLogSeverity[CoralogixLogSeverity["Debug"] = 1] = "Debug"; CoralogixLogSeverity[CoralogixLogSeverity["Verbose"] = 2] = "Verbose"; CoralogixLogSeverity[CoralogixLogSeverity["Info"] = 3] = "Info"; CoralogixLogSeverity[CoralogixLogSeverity["Warn"] = 4] = "Warn"; CoralogixLogSeverity[CoralogixLogSeverity["Error"] = 5] = "Error"; CoralogixLogSeverity[CoralogixLogSeverity["Critical"] = 6] = "Critical"; })(CoralogixLogSeverity || (CoralogixLogSeverity = {})); var millisecondsPerSecond = 1000; var millisecondsPerMinute = millisecondsPerSecond * 60; var MILLISECONDS_PER_HOUR = millisecondsPerMinute * 60; function getNowTime() { return new Date().getTime(); } var MAX_BATCH_TIME_MS = 10000; //10s var SESSION_RECORDING_DEFAULT_HEADERS = { 'Content-Encoding': 'gzip', }; var SESSION_RECORDING_DEFAULT_ERROR_MESSAGE = 'Coralogix Browser SDK - Recording is not supported on this platform'; var SESSION_RECORDING_NETWORK_ERR0R_MESSAGE = 'Coralogix Browser SDK - Error while sending record'; var BATCH_TIME_DELAY = 1000; var SESSION_RECORDING_POSTFIX_URL = '/browser/alpha/sessionrecording'; var SESSION_KEY = 'rum_session'; var PREV_SESSION_KEY = 'rum_prev_session'; var MAX_MUTATIONS_FOR_SESSION_RECORDING = 5000; var DEFAULT_SESSION_CONFIG = { sessionSampleRate: 100, onlyWithErrorConfig: { enable: false, }, }; var SESSION_IDLE_TIME = 15 * millisecondsPerMinute; var SESSION_EXPIRATION_TIME = MILLISECONDS_PER_HOUR; var SESSION_MANAGER_KEY = 'rumSessionManager'; var SESSION_RECORDER_KEY = 'rumSessionRecorder'; var SESSION_RECORDER_SEGMENTS_MAP = 'rumSessionRecorderSegmentsMap'; var SNAPSHOT_MANAGER_KEY = 'rumSnapshotManager'; var INITIAL_SNAPSHOT_CONTEXT = { errorCount: 0, viewCount: 0, actionCount: 0, hasRecording: false, hasScreenshot: false, }; function getCxGlobal() { if (typeof globalThis === 'object') { return globalThis; } Object.defineProperty(Object.prototype, '__cx_global__', { get: function () { return this; }, configurable: true, }); var globalObject = __cx_global__; delete Object.prototype.__cx_global__; if (typeof globalObject !== 'object') { if (typeof self === 'object') { globalObject = self; } else if (typeof window === 'object') { globalObject = window; } else { globalObject = {}; } } return globalObject; } var CxGlobal = getCxGlobal(); function getSnapshotManager() { return CxGlobal[SNAPSHOT_MANAGER_KEY]; } function getSessionManager() { return CxGlobal[SESSION_MANAGER_KEY]; } function getSessionRecorder() { return CxGlobal[SESSION_RECORDER_KEY]; } function getSdkConfig() { return CxGlobal[SDK_CONFIG_KEY]; } var GLOBAL_SPAN_KEY = '__globalSpan__'; var CUSTOM_TRACER_KEY = '__customTracer__'; var CUSTOM_TRACER_IGNORED_INSTRUMENTS = '__customTracerIgnoredInstruments__'; function setGlobalSpan(globalSpan) { CxGlobal[GLOBAL_SPAN_KEY] = globalSpan; } function getGlobalSpan() { return CxGlobal[GLOBAL_SPAN_KEY]; } function clearGlobalSpan() { delete CxGlobal[GLOBAL_SPAN_KEY]; } function setCustomTracer(customTracer) { CxGlobal[CUSTOM_TRACER_KEY] = customTracer; } function getCustomTracer() { return CxGlobal[CUSTOM_TRACER_KEY]; } function setCustomTracerIgnoredInstruments(ignoredInstruments) { CxGlobal[CUSTOM_TRACER_IGNORED_INSTRUMENTS] = ignoredInstruments; } function getCustomTracerIgnoredInstruments() { return CxGlobal[CUSTOM_TRACER_IGNORED_INSTRUMENTS]; } function shouldAttachSpanToGlobalSpan(instrumentationType) { var _a; return (getGlobalSpan() && !((_a = getCustomTracerIgnoredInstruments()) === null || _a === undefined ? undefined : _a.includes(instrumentationType))); } function attachChildSpanToGlobalSpan(name) { var span; var globalSpan = getGlobalSpan(); globalSpan.withContext(function () { var childSpan = globalSpan.startCustomSpan(name); span = childSpan.span; }); return span; } var IS_OTEL_READY = 'otelReady'; var MAIN_TRACER_KEY = '@'; var ATTR_PROCESSOR_KEY = 'attrProcessor'; var SpanStatusCode; (function (SpanStatusCode) { /** * The default status. */ SpanStatusCode[SpanStatusCode["UNSET"] = 0] = "UNSET"; /** * The operation has been validated by an Application developer or * Operator to have completed successfully. */ SpanStatusCode[SpanStatusCode["OK"] = 1] = "OK"; /** * The operation contains an error. */ SpanStatusCode[SpanStatusCode["ERROR"] = 2] = "ERROR"; })(SpanStatusCode || (SpanStatusCode = {})); function markSpanAsOtelToSend(span) { span[IS_OTEL_READY] = true; } function shouldAddOtelAttr(span) { return !!span[IS_OTEL_READY]; } function setAttrProcessor(processor) { CxGlobal[ATTR_PROCESSOR_KEY] = processor; } function getAttrProcessor() { return CxGlobal[ATTR_PROCESSOR_KEY]; } function setCustomLabelsForSpan(span, labels) { if (labels === undefined) { labels = {}; } span.setAttribute(CoralogixAttributes.CUSTOM_LABELS, JSON.stringify(getCustomMergedLabels(labels))); } function getCustomMergedLabels(labels) { var _a; if (labels === undefined) { labels = {}; } var globalLabels = ((_a = getAttrProcessor()) === null || _a === undefined ? undefined : _a.getCustomLabels()) || {}; return __assign(__assign({}, globalLabels), labels); } var CACHED_METADATA_KEY = '__cx_metadata__'; var ERROR_INSTRUMENTATION_VERSION = '1'; var STACK_LIMIT = 4096; var MESSAGE_LIMIT = 1024; var ERROR_INSTRUMENTATION_NAME = 'errors'; var ErrorAttributes = { TYPE: 'error_type', STACK: 'error_stack', MESSAGE: 'error_message', DATA: 'error_custom_data', }; var ErrorSource; (function (ErrorSource) { ErrorSource["CONSOLE"] = "console"; ErrorSource["WINDOW"] = "window"; ErrorSource["UNHANDLED_REJECTION"] = "unhandledrejection"; ErrorSource["DOCUMENT"] = "document"; ErrorSource["CAPTURED"] = "captured"; })(ErrorSource || (ErrorSource = {})); function buildStacktrace(span, err) { return __awaiter(this, undefined, undefined, function () { var stack, message, name, hasStack, supportMfe, stackFrames; return __generator(this, function (_a) { switch (_a.label) { case 0: stack = err.stack, message = err.message, name = err.name; hasStack = !!(stack === null || stack === undefined ? undefined : stack.includes('at ')); if (!(err && hasStack)) return [3 /*break*/, 3]; supportMfe = getSdkConfig().supportMfe; stackFrames = ErrorStackParser.parse({ stack: stack.substring(0, STACK_LIMIT), message: message, name: name, }).map(function (_a) { var fileName = _a.fileName, columnNumber = _a.columnNumber, lineNumber = _a.lineNumber, functionName = _a.functionName; return ({ fileName: fileName, columnNumber: columnNumber, lineNumber: lineNumber, functionName: functionName, }); }); if (!supportMfe) return [3 /*break*/, 2]; return [4 /*yield*/, handleMFE(stackFrames, span)]; case 1: _a.sent(); _a.label = 2; case 2: span[ErrorAttributes.STACK] = stackFrames; _a.label = 3; case 3: return [2 /*return*/]; } }); }); } function handleMFE(stackFrames, span) { return __awaiter(this, undefined, undefined, function () { var i, metadata, _a, lastFrame; return __generator(this, function (_b) { switch (_b.label) { case 0: i = 0; _b.label = 1; case 1: if (!(i < stackFrames.length)) return [3 /*break*/, 4]; return [4 /*yield*/, extractMetadataFromMfeStacktrace(stackFrames[i].fileName)]; case 2: metadata = _b.sent(); stackFrames[i] = __assign(__assign({}, stackFrames[i]), (metadata || { isShell: true })); _b.label = 3; case 3: i++; return [3 /*break*/, 1]; case 4: _a = __read$1(stackFrames, 1), lastFrame = _a[0]; addLabelForMFE(span, lastFrame); return [2 /*return*/]; } }); }); } function addLabelForMFE(span, lastFrame) { var app = lastFrame.app, version = lastFrame.version, isShell = lastFrame.isShell; // Do not add label if its shell if (!isShell) { setCustomLabelsForSpan(span, { mfeApp: app, mfeVersion: version }); } } function extractMetadataFromMfeStacktrace() { return __awaiter(this, arguments, undefined, function (fileName) { var metadata, cachedMetadata, MFE_METADATA_KEY, _a, mfePath, response, _b, e_1; if (fileName === undefined) { fileName = ''; } return __generator(this, function (_c) { switch (_c.label) { case 0: cachedMetadata = CxGlobal[CACHED_METADATA_KEY]; MFE_METADATA_KEY = 'cx-metadata.json'; _a = __read$1(fileName.match(/https?:\/\/.*\//), 1), mfePath = _a[0]; if (!mfePath) return [3 /*break*/, 7]; response = undefined; if (!!(cachedMetadata === null || cachedMetadata === undefined ? undefined : cachedMetadata.has(mfePath))) return [3 /*break*/, 6]; _c.label = 1; case 1: _c.trys.push([1, 4, , 5]); return [4 /*yield*/, fetch("".concat(mfePath).concat(MFE_METADATA_KEY), { //this is a browser cache control cache: 'no-cache', })]; case 2: response = _c.sent(); _b = [{}]; return [4 /*yield*/, response.json()]; case 3: metadata = __assign.apply(undefined, [__assign.apply(undefined, _b.concat([(_c.sent())])), { mfePath: mfePath }]); return [3 /*break*/, 5]; case 4: e_1 = _c.sent(); if (getSdkConfig().debug) { console.warn('Coralogix Browser SDK - Error fetching metadata', e_1); } return [3 /*break*/, 5]; case 5: CxGlobal[CACHED_METADATA_KEY] = cachedMetadata.set(mfePath, metadata); return [3 /*break*/, 7]; case 6: metadata = cachedMetadata === null || cachedMetadata === undefined ? undefined : cachedMetadata.get(mfePath); _c.label = 7; case 7: return [2 /*return*/, metadata]; } }); }); } var _consoleErrorHandler = function (that) { return function (original) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } that.report(ErrorSource.CONSOLE, args); return original.apply(that, args); }; }; }; var _errorListener = function (that) { return function (event) { that.report(ErrorSource.WINDOW, event); }; }; var _unhandledRejectionListener = function (that) { return function (event) { that.report(ErrorSource.UNHANDLED_REJECTION, event.reason); }; }; var _documentErrorListener = function (that) { return function (event) { that.report(ErrorSource.DOCUMENT, event); }; }; function addErrorDefaultAttributes(span) { span.setAttribute(CoralogixAttributes.EVENT_TYPE, CoralogixEventType.ERROR); span.setAttribute(CoralogixAttributes.SEVERITY, CoralogixLogSeverity.Error); } var CoralogixErrorInstrumentation = /** @class */ (function (_super) { __extends(CoralogixErrorInstrumentation, _super); function CoralogixErrorInstrumentation(config) { var _this = _super.call(this, ERROR_INSTRUMENTATION_NAME, ERROR_INSTRUMENTATION_VERSION, config) || this; _this.parseErrorObject = function (obj) { var _a; return (_a = obj === null || obj === undefined ? undefined : obj.message) !== null && _a !== undefined ? _a : JSON.stringify(obj, getCircularReplacer()); }; if (getSdkConfig().supportMfe) { CxGlobal[CACHED_METADATA_KEY] = new Map(); } return _this; } CoralogixErrorInstrumentation.prototype.init = function () { }; CoralogixErrorInstrumentation.prototype.enable = function () { shimmer_1.wrap(console, 'error', _consoleErrorHandler(this)); CxGlobal.addEventListener('error', _errorListener(this)); CxGlobal.addEventListener('unhandledrejection', _unhandledRejectionListener(this)); document.documentElement.addEventListener('error', _documentErrorListener(this), { capture: true, }); }; CoralogixErrorInstrumentation.prototype.disable = function () { shimmer_1.unwrap(console, 'error'); CxGlobal.removeEventListener('error', _errorListener(this)); CxGlobal.removeEventListener('unhandledrejection', _unhandledRejectionListener(this)); document.documentElement.removeEventListener('error', _documentErrorListener(this), { capture: true }); }; CoralogixErrorInstrumentation.prototype.report = function (source, arg) { var _this = this; if (arg instanceof Array) { if (arg.length === 0) { return; } } switch (true) { case arg instanceof Error: this.reportError(source, arg); break; case arg instanceof ErrorEvent: this.reportErrorEvent(source, arg); break; case arg instanceof Event: this.reportEvent(source, arg); break; case typeof arg === 'string': this.reportString(source, arg); break; case arg instanceof Array: { // if any arguments are Errors then add the stack trace even though the message is handled differently var firstError = arg.find(function (x) { return x instanceof Error; }); var message = arg .map(function (msg) { return typeof msg === 'string' ? msg : _this.parseErrorObject(msg); }) .join(' '); this.reportString(source, message, firstError); break; } default: this.reportString(source, typeof arg === 'string' ? arg : this.getPossibleEventMessage(arg)); } }; CoralogixErrorInstrumentation.prototype.reportError = function (source, err, customData, labels) { return __awaiter(this, undefined, undefined, function () { var message, name, span, cleanMessage; return __generator(this, function (_a) { switch (_a.label) { case 0: message = err.message, name = err.name; span = this.createSpan('error'); cleanMessage = message.split('\n')[0]; addErrorDefaultAttributes(span); span.setAttribute(CoralogixAttributes.SOURCE, source); span.setAttribute(ErrorAttributes.TYPE, name); span.setAttribute(ErrorAttributes.MESSAGE, cleanMessage); if (customData) { span[ErrorAttributes.DATA] = JSON.stringify(customData, getCircularReplacer()); } if (labels) { setCustomLabelsForSpan(span, labels); } return [4 /*yield*/, buildStacktrace(span, err)]; case 1: _a.sent(); span.end(); return [2 /*return*/]; } }); }); }; CoralogixErrorInstrumentation.prototype.reportString = function (source, message, firstError) { return __awaiter(this, undefined, undefined, function () { var span; return __generator(this, function (_a) { switch (_a.label) { case 0: span = this.createSpan(source); addErrorDefaultAttributes(span); span.setAttribute(CoralogixAttributes.SOURCE, source); span.setAttribute(ErrorAttributes.MESSAGE, message === null || message === undefined ? undefined : message.substring(0, MESSAGE_LIMIT)); if (!firstError) return [3 /*break*/, 2]; return [4 /*yield*/, buildStacktrace(span, firstError)]; case 1: _a.sent(); _a.label = 2; case 2: span.end(); return [2 /*return*/]; } }); }); }; CoralogixErrorInstrumentation.prototype.reportErrorEvent = function (source, _a) { var error = _a.error, message = _a.message; var event = error !== null && error !== undefined ? error : message; this.report(source, event); }; CoralogixErrorInstrumentation.prototype.reportEvent = function (source, ev) { if (!ev.target) { return; } var span = this.createSpan(source); addErrorDefaultAttributes(span); span.setAttribute(CoralogixAttributes.SOURCE, source); if (ev.target) { span.setAttribute('target_element', ev.target.tagName); span.setAttribute('target_xpath', getElementXPath(ev.target, true)); span.setAttribute('target_src', ev.target.src); } span.end(); }; CoralogixErrorInstrumentation.prototype.createSpan = function (name) { var span; if (shouldAttachSpanToGlobalSpan(CoralogixEventType.ERROR)) { span = attachChildSpanToGlobalSpan(name); } else { span = this.tracer.startSpan(name); } return span; }; CoralogixErrorInstrumentation.prototype.getPossibleEventMessage = function (event) { var _a = event || {}, message = _a.message, statusMessage = _a.statusMessage; if (message && typeof message === 'string') { return message; } // GrpcStatusEvent if (statusMessage && typeof statusMessage === 'string') { return statusMessage; } return JSON.stringify(event); }; return CoralogixErrorInstrumentation; }(InstrumentationBase)); var propagateTraceHeaderCorsUrls = function (config) { var _a; var traceParentInHeader = config.traceParentInHeader; var propagateCorsUrls = (_a = traceParentInHeader === null || traceParentInHeader === undefined ? undefined : traceParentInHeader.options) === null || _a === undefined ? undefined : _a.propagateTraceHeaderCorsUrls; if ((traceParentInHeader === null || traceParentInHeader === undefined ? undefined : traceParentInHeader.enabled) && propagateCorsUrls) { config.propagateTraceHeaderCorsUrls = propagateCorsUrls; } }; var NetworkDataManager = /** @class */ (function () { function NetworkDataManager() { var _this = this; this.responseBodyParsers = new Map([ [MimeType.Json, function (body) { return __awaiter(_this, undefined, undefined, function () { var _a, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _b = (_a = JSON).stringify; return [4 /*yield*/, body.json()]; case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])]; } }); }); }], [MimeType.TextPlain, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, body.text()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }], [MimeType.TextHtml, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, body.text()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }], [MimeType.TextCss, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, body.text()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }], [MimeType.TextJavascript, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, body.text()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }], [MimeType.Xml, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, body.text()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }], [MimeType.FormData, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, body.text()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }], ]); this.requestBodySerializers = new Map([ [BodyType.String, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { return [2 /*return*/, body]; }); }); }], [BodyType.Blob, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { return [2 /*return*/, body.text()]; }); }); }], [ BodyType.FormData, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { return [2 /*return*/, this.serializeFormData(body)]; }); }); }, ], [ BodyType.URLSearchParams, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { return [2 /*return*/, body.toString()]; }); }); }, ], [BodyType.JsonObject, function (body) { return __awaiter(_this, undefined, undefined, function () { return __generator(this, function (_a) { return [2 /*return*/, JSON.stringify(body)]; }); }); }], ]); } NetworkDataManager.prototype.resolveConfigForUrl = function (url, configs) { if (configs === undefined) { configs = []; } return configs.find(function (_a) { var configUrl = _a.url; return configUrl === url || (configUrl instanceof RegExp && configUrl.test(url)); }); }; NetworkDataManager.prototype.stringifyRequestBody = function (request) { return __awaiter(this, undefined, undefined, function () { var bodyContent; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(request === null || request === undefined ? undefined : request.body)) return [2 /*return*/, '']; return [4 /*yield*/, this.serializeRequestBody(request.body)]; case 1: bodyContent = _a.sent(); return [2 /*return*/, this.truncateIfExceedsLimit(bodyContent)]; } }); }); }; NetworkDataManager.prototype.stringifyResponseBody = function (response) { return __awaiter(this, undefined, undefined, function () { var contentType, mimeType, parser, parsedContent; return __generator(this, function (_a) { switch (_a.label) { case 0: contentType = response.headers.get('content-type') || ''; mimeType = contentType.split(';')[0].trim(); parser = this.responseBodyParsers.get(mimeType); if (!parser) return [2 /*return*/, '']; return [4 /*yield*/, parser(response)]; case 1: parsedContent = _a.sent(); return [2 /*return*/, this.truncateIfExceedsLimit(parsedContent)]; } }); }); }; NetworkDataManager.prototype.truncateIfExceedsLimit = function (content) { return content.length > MAX_CHARACTERS ? undefined : content; }; NetworkDataManager.prototype.serializeRequestBody = function (body) { return __awaiter(this, undefined, undefined, function () { var handler, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: handler = this.requestBodySerializers.get(body.constructor.name); if (!handler) return [3 /*break*/, 2]; return [4 /*yield*/, handler(body)]; case 1: _a = _b.sent(); return [3 /*break*/, 3]; case 2: _a = ''; _b.label = 3; case 3: return [2 /*return*/, _a]; } }); }); }; NetworkDataManager.prototype.serializeFormData = function (formData) { var result = ''; formData.forEach(function (value, key) { result += "".concat(key, ": ").concat(value, "\n"); }); return result.trim(); }; return NetworkDataManager; }()); var MimeType; (function (MimeType) { MimeType["Json"] = "application/json"; MimeType["TextPlain"] = "text/plain"; MimeType["TextHtml"] = "text/html"; MimeType["TextCss"] = "text/css"; MimeType["TextJavascript"] = "application/javascript"; MimeType["Xml"] = "application/xml"; MimeType["FormData"] = "multipart/form-data"; })(MimeType || (MimeType = {})); var BodyType; (function (BodyType) { BodyType["String"] = "String"; BodyType["Blob"] = "Blob"; BodyType["FormData"] = "FormData"; BodyType["URLSearchParams"] = "URLSearchParams"; BodyType["JsonObject"] = "JsonObject"; BodyType["Unknown"] = "Unknown"; })(BodyType || (BodyType = {})); var HeadersManager = /** @class */ (function () { function HeadersManager() { } HeadersManager.prototype.filterHeaders = function (headersInit, allowedKeys) { if (allowedKeys === undefined) { allowedKeys = []; } if (!headersInit) { return new Map(); } var normalized = this.normalizeHeaders(headersInit); var filteredHeaders = new Map(); allowedKeys.forEach(function (headerKey) { var normalizedKey = headerKey.toLowerCase(); if (normalized.has(normalizedKey)) { filteredHeaders.set(headerKey, normalized.get(normalizedKey)); } }); return filteredHeaders; }; HeadersManager.prototype.normalizeHeaders = function (headersInit) { if (typeof headersInit === 'string') { return this.normalizeHeadersFromString(headersInit); } var headers = new Headers(headersInit); var headersMap = new Map(); headers.forEach(function (value, key) { headersMap.set(key.toLowerCase(), value); }); return headersMap; }; HeadersManager.prototype.normalizeHeadersFromString = function (headersString) { var headerMap = new Map(); if (!headersString) { return headerMap; } var lines = headersString.trim().split(/\r\n/); lines.forEach(function (line) { var _a = __read$1(line.split(': ', 2), 2), key = _a[0], value = _a[1]; if (key && value) { headerMap.set(key.trim().toLowerCase(), value.trim()); } }); return headerMap; }; return HeadersManager; }()); var NetworkInstrumentationAttributes = { REQUEST_HEADERS: 'request_headers', RESPONSE_HEADERS: 'response_headers', RESPONSE_PAYLOAD: 'response_payload', REQUEST_PAYLOAD: 'request_payload', }; function checkAttachingNetworkSpanToGlobalSpan(span) { if (shouldAttachSpanToGlobalSpan(CoralogixEventType.NETWORK_REQUEST)) { var globalSpan = getGlobalSpan(); var _a = globalSpan.span.spanContext(), traceId = _a.traceId, globalSpanId = _a.spanId; span['_spanContext'].traceId = traceId; span['parentSpanId'] = globalSpanId; } } var FetchSource; (function (FetchSource) { FetchSource["FETCH"] = "fetch"; })(FetchSource || (FetchSource = {})); var CoralogixFetchInstrumentation = /** @class */ (function (_super) { __extends(CoralogixFetchInstrumentation, _super); function CoralogixFetchInstrumentation(config) { var _this = this; propagateTraceHeaderCorsUrls(config); config.applyCustomAttributesOnSpan = function (span, request, result) { markSpanAsOtelToSend(span); checkAttachingNetworkSpanToGlobalSpan(span); _this.setNetworkSpanAttributes(span, request, result); }; _this = _super.call(this, config) || this; _this.networkDataManager = new NetworkDataManager(); _this.headersManager = new HeadersManager(); return _this; } CoralogixFetchInstrumentation.prototype.setNetworkSpanAttributes = function (span, request, response) { return __awaiter(this, undefined, undefined, function () { var status, networkExtraConfig, url, resolvedConfig; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: status = response.status; networkExtraConfig = getSdkConfig().networkExtraConfig; url = span.attributes['http.url'] || ''; resolvedConfig = this.networkDataManager.resolveConfigForUrl(url, networkExtraConfig); if (!resolvedConfig) return [3 /*break*/, 3]; return [4 /*yield*/, this.setRequestAttributes(span, request, resolvedConfig)]; case 1: _b.sent(); return [4 /*yield*/, this.setResponseAttributes(span, response, resolvedConfig)]; case 2: _b.sent(); _b.label = 3; case 3: span.setAttributes((_a = {}, _a[CoralogixAttributes.SEVERITY] = isNetworkError(status) ? CoralogixLogSeverity.Error : CoralogixLogSeverity.Info, _a[CoralogixAttributes.EVENT_TYPE] = CoralogixEventType.NETWORK_REQUEST, _a[CoralogixAttributes.SOURCE] = FetchSource.FETCH, _a)); return [2 /*return*/]; } }); }); }; CoralogixFetchInstrumentation.prototype.setRequestAttributes = function (span, request, networkExtraConfig) { return __awaiter(this, undefined, undefined, function () { var reqHeaders, collectReqPayload, requestPayload, _a, sanitizedHeaders, error_1; return __generator(this, function (_b) { switch (_b.label) { case 0: reqHeaders = networkExtraConfig.reqHeaders, collectReqPayload = networkExtraConfig.collectReqPayload; _b.label = 1; case 1: _b.trys.push([1, 5, , 6]); if (!collectReqPayload) return [3 /*break*/, 3]; return [4 /*yield*/, this.networkDataManager.stringifyRequestBody(request)]; case 2: _a = _b.sent(); return [3 /*break*/, 4]; case 3: _a = undefined; _b.label = 4; case 4: requestPayload = _a; sanitizedHeaders = (reqHeaders === null || reqHeaders === undefined ? undefined : reqHeaders.length) ? this.headersManager.filterHeaders(request.headers, reqHeaders) : undefined; if (requestPayload) span[NetworkInstrumentationAttributes.REQUEST_PAYLOAD] = requestPayload; if (sanitizedHeaders === null || sanitizedHeaders === undefined ? undefined : sanitizedHeaders.size) { span[NetworkInstrumentationAttributes.REQUEST_HEADERS] = Object.fromEntries(sanitizedHeaders); } return [3 /*break*/, 6]; case 5: error_1 = _b.sent(); if (getSdkConfig().debug) { console.debug('Error setting request attributes on span:', error_1); } return [3 /*break*/, 6]; case 6: return [2 /*return*/]; } }); }); }; CoralogixFetchInstrumentation.prototype.setResponseAttributes = function (span, result, networkExtraConfig) { return __awaiter(this, undefined, undefined, function () { var resHeaders, collectResPayload, responsePayload, _a, sanitizedHeaders, error_2; return __generator(this, function (_b) { switch (_b.label) { case 0: resHeaders = networkExtraConfig.resHeaders, collectResPayload = networkExtraConfig.collectResPayload; if (!(result instanceof Response)) return [3 /*break*/, 6]; _b.label = 1; case 1: _b.trys.push([1, 5, , 6]); if (!collectResPayload) return [3 /*break*/, 3]; return [4 /*yield*/, this.networkDataManager.stringifyResponseBody(result)]; case 2: _a = _b.sent(); return [3 /*break*/, 4]; case 3: _a = undefined; _b.label = 4; case 4: responsePayload = _a; sanitizedHeaders = (resHeaders === null || resHeaders === undefined ? undefined : resHeaders.length) ? this.headersManager.filterHeaders(result.headers, resHeaders) : undefined; if (responsePayload) { span[NetworkInstrumentationAttributes.RESPONSE_PAYLOAD] = responsePayload; } if (sanitizedHeaders === null || sanitizedHeaders === undefined ? undefined : sanitizedHeaders.size) { span[NetworkInstrumentationAttributes.RESPONSE_HEADERS] = Object.fromEntries(sanitizedHeaders); } return [3 /*break*/, 6]; case 5: error_2 = _b.sent(); if (getSdkConfig().debug) { console.debug('Error setting request attributes on span:', error_2); } return [3 /*break*/, 6]; case 6: return [2 /*return*/]; } }); }); }; return CoralogixFetchInstrumentation; }(FetchInstrumentation)); var XHRSource; (function (XHRSource) { XHRSource["XHR"] = "xhr"; })(XHRSource || (XHRSource = {})); var CoralogixXhrInstrumentation = /** @class */ (function (_super) { __extends(CoralogixXhrInstrumentation, _super); function CoralogixXhrInstrumentation(config) { var _this = this; propagateTraceHeaderCorsUrls(config); config.applyCustomAttributesOnSpan = function (span, xhr) { markSpanAsOtelToSend(span); checkAttachingNetworkSpanToGlobalSpan(span); _this.setNetworkSpanAttributes(span, xhr); }; _this = _super.call(this, config) || this; _this.networkDataManager = new NetworkDataManager(); _this.headersManager = new HeadersManager(); return _this; } CoralogixXhrInstrumentation.prototype.setNetworkSpanAttributes = function (span, xhr) { var _a; var status = xhr.status; var networkExtraConfig = getSdkConfig().networkExtraConfig; var resolvedConfig = this.networkDataManager.resolveConfigForUrl(xhr.responseURL, networkExtraConfig); span.setAttributes((_a = {}, _a[CoralogixAttributes.SEVERITY] = isNetworkError(status) ? CoralogixLogSeverity.Error : CoralogixLogSeverity.Info, _a[CoralogixAttributes.EVENT_TYPE] = CoralogixEventType.NETWORK_REQUEST, _a[CoralogixAttributes.SOURCE] = XHRSource.XHR, _a)); if (resolvedConfig) { this.setResponseAttributes(span, xhr, resolvedConfig); } }; CoralogixXhrInstrumentation.prototype.setResponseAttributes = function (span, xhr, resolvedConfig) { var resHeaders = resolvedConfig.resHeaders, collectResPayload = resolvedConfig.collectResPayload; var responsePayload = collectResPayload ? this.networkDataManager.truncateIfExceedsLimit(xhr.responseText) : undefined; var sanitizedHeaders = (resHeaders === null || resHeaders === undefined ? undefined : resHeaders.length) ? this.headersManager.filterHeaders(xhr.getAllResponseHeaders(), resHeaders) : undefined; if (responsePayload) { span[NetworkInstrumentationAttributes.RESPONSE_PAYLOAD] = responsePayload; } if (sanitizedHeaders === null || sanitizedHeaders === undefined ? undefined : sanitizedHeaders.size) { span[NetworkInstrumentationAttributes.RESPONSE_HEADERS] = Object.fromEntries(sanitizedHeaders); } }; return CoralogixXhrInstrumentation; }(XMLHttpRequestInstrumentation)); var CUSTOM_INSTRUMENTATION_VERSION = '1'; var LogSource; (function (LogSource) { LogSource["CODE"] = "code"; })(LogSource || (LogSource = {})); var CoralogixCustomLogInstrumentation = /** @class */ (function (_super) { __extends(CoralogixCustomLogInstrumentation, _super); function CoralogixCustomLogInstrumentation(config) { var _a; var _this = _super.call(this, CoralogixEventType.LOG, CUSTOM_INSTRUMENTATION_VERSION, config) || this; _this.stringifyCustomLogData = (_a = getSdkConfig()) === null || _a === undefined ? undefined : _a.stringifyCustomLogData; return _this; } CoralogixCustomLogInstrumentation.prototype.init = function () { }; CoralogixCustomLogInstrumentation.prototype.disable = function () { }; CoralogixCustomLogInstrumentation.prototype.enable = function () { }; CoralogixCustomLogInstrumentation.prototype.log = function (_a) { var severity = _a.severity, message = _a.message, data = _a.data, labels = _a.labels; var span = this.tracer.startSpan(CoralogixEventType.LOG); span.setAttribute(CoralogixAttributes.EVENT_TYPE, CoralogixEventType.LOG); span.setAttribute(CoralogixAttributes.SOURCE, LogSource.CODE); span.setAttribute(CoralogixAttributes.SEVERITY, severity); span.setAttribute(CoralogixAttributes.LOG, JSON.stringify({ severity: severity, message: message, data: this.stringifyCustomLogData ? JSON.stringify(data, getCircularReplacer()) : data, })); if (labels) { setCustomLabelsForSpan(span, labels); } span.end(); }; return CoralogixCustomLogInstrumentation; }(InstrumentationBase)); /** * Checks if value is null or undefined. * * @param value The value to check. * @returns Returns true if value is null or undefined, else false. */ function isNil(value) { return value == null; } /** * Ensures a given value is converted into an array of elements. * * @template T - The type of the input value and the elements in the resulting array. * * @param value - The input value, which can be a single instance of type `T`, an array of instances of type `T`, or a Set of instances of type `T`. * * @returns An array of elements of type `T`. If the input is `null` or `undefined`, returns an empty array. */ function coerceArray(value) { if (isNil(value))