UNPKG

@sentry/core

Version:
189 lines (162 loc) 6.02 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const client = require('../client.js'); const currentScopes = require('../currentScopes.js'); const debugBuild = require('../debug-build.js'); const constants = require('./constants.js'); const is = require('../utils-hoist/is.js'); require('../utils-hoist/debug-build.js'); const logger = require('../utils-hoist/logger.js'); require('../utils-hoist/time.js'); require('../utils-hoist/syncpromise.js'); const spanOnScope = require('../utils/spanOnScope.js'); const envelope = require('./envelope.js'); const MAX_LOG_BUFFER_SIZE = 100; const CLIENT_TO_LOG_BUFFER_MAP = new WeakMap(); /** * Converts a log attribute to a serialized log attribute. * * @param key - The key of the log attribute. * @param value - The value of the log attribute. * @returns The serialized log attribute. */ function logAttributeToSerializedLogAttribute(key, value) { switch (typeof value) { case 'number': return { key, value: { doubleValue: value }, }; case 'boolean': return { key, value: { boolValue: value }, }; case 'string': return { key, value: { stringValue: value }, }; default: { let stringValue = ''; try { stringValue = JSON.stringify(value) ?? ''; } catch { // Do nothing } return { key, value: { stringValue }, }; } } } /** * Captures a log event and sends it to Sentry. * * @param log - The log event to capture. * @param scope - A scope. Uses the current scope if not provided. * @param client - A client. Uses the current client if not provided. * * @experimental This method will experience breaking changes. This is not yet part of * the stable Sentry SDK API and can be changed or removed without warning. */ function _INTERNAL_captureLog( beforeLog, client$1 = currentScopes.getClient(), scope = currentScopes.getCurrentScope(), ) { if (!client$1) { debugBuild.DEBUG_BUILD && logger.logger.warn('No client available to capture log.'); return; } const { _experiments, release, environment } = client$1.getOptions(); const { enableLogs = false, beforeSendLog } = _experiments ?? {}; if (!enableLogs) { debugBuild.DEBUG_BUILD && logger.logger.warn('logging option not enabled, log will not be captured.'); return; } const [, traceContext] = client._getTraceInfoFromScope(client$1, scope); const processedLogAttributes = { ...beforeLog.attributes, }; if (release) { processedLogAttributes['sentry.release'] = release; } if (environment) { processedLogAttributes['sentry.environment'] = environment; } const { sdk } = client$1.getSdkMetadata() ?? {}; if (sdk) { processedLogAttributes['sentry.sdk.name'] = sdk.name; processedLogAttributes['sentry.sdk.version'] = sdk.version; } const beforeLogMessage = beforeLog.message; if (is.isParameterizedString(beforeLogMessage)) { const { __sentry_template_string__, __sentry_template_values__ = [] } = beforeLogMessage; processedLogAttributes['sentry.message.template'] = __sentry_template_string__; __sentry_template_values__.forEach((param, index) => { processedLogAttributes[`sentry.message.parameter.${index}`] = param; }); } const span = spanOnScope._getSpanForScope(scope); if (span) { // Add the parent span ID to the log attributes for trace context processedLogAttributes['sentry.trace.parent_span_id'] = span.spanContext().spanId; } const processedLog = { ...beforeLog, attributes: processedLogAttributes }; client$1.emit('beforeCaptureLog', processedLog); const log = beforeSendLog ? beforeSendLog(processedLog) : processedLog; if (!log) { client$1.recordDroppedEvent('before_send', 'log_item', 1); debugBuild.DEBUG_BUILD && logger.logger.warn('beforeSendLog returned null, log will not be captured.'); return; } const { level, message, attributes = {}, severityNumber } = log; const serializedLog = { severityText: level, body: { stringValue: message, }, attributes: Object.entries(attributes).map(([key, value]) => logAttributeToSerializedLogAttribute(key, value)), timeUnixNano: `${new Date().getTime().toString()}000000`, traceId: traceContext?.trace_id, severityNumber: severityNumber ?? constants.SEVERITY_TEXT_TO_SEVERITY_NUMBER[level], }; const logBuffer = CLIENT_TO_LOG_BUFFER_MAP.get(client$1); if (logBuffer === undefined) { CLIENT_TO_LOG_BUFFER_MAP.set(client$1, [serializedLog]); } else { logBuffer.push(serializedLog); if (logBuffer.length > MAX_LOG_BUFFER_SIZE) { _INTERNAL_flushLogsBuffer(client$1, logBuffer); } } client$1.emit('afterCaptureLog', log); } /** * Flushes the logs buffer to Sentry. * * @param client - A client. * @param maybeLogBuffer - A log buffer. Uses the log buffer for the given client if not provided. * * @experimental This method will experience breaking changes. This is not yet part of * the stable Sentry SDK API and can be changed or removed without warning. */ function _INTERNAL_flushLogsBuffer(client, maybeLogBuffer) { const logBuffer = maybeLogBuffer ?? CLIENT_TO_LOG_BUFFER_MAP.get(client) ?? []; if (logBuffer.length === 0) { return; } const clientOptions = client.getOptions(); const envelope$1 = envelope.createOtelLogEnvelope(logBuffer, clientOptions._metadata, clientOptions.tunnel, client.getDsn()); // Clear the log buffer after envelopes have been constructed. logBuffer.length = 0; client.emit('flushLogs'); // sendEnvelope should not throw // eslint-disable-next-line @typescript-eslint/no-floating-promises client.sendEnvelope(envelope$1); } exports._INTERNAL_captureLog = _INTERNAL_captureLog; exports._INTERNAL_flushLogsBuffer = _INTERNAL_flushLogsBuffer; exports.logAttributeToSerializedLogAttribute = logAttributeToSerializedLogAttribute; //# sourceMappingURL=exports.js.map