@hyperdx/instrumentation-sentry-node
Version:
[![NPM Published Version][npm-img]][npm-url] [![Apache License][license-image]][license-image]
186 lines (185 loc) • 9.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getEventProcessor = exports.getSpanNameFromEvent = exports.isSentryEventAnException = exports.extractSpanEventsFromException = exports.extractSemAttrsFromEvent = exports.SEMATTRS_SENTRY_VERSION = exports.SEMATTRS_EXCEPTION_THREAD_ID = exports.SEMATTRS_EXCEPTION_TAGS = exports.SEMATTRS_EXCEPTION_PARSED_STACKTRACE = exports.SEMATTRS_EXCEPTION_MODULES = exports.SEMATTRS_EXCEPTION_MODULE = exports.SEMATTRS_EXCEPTION_MECHANISM = void 0;
const tslib_1 = require("tslib");
const api_1 = tslib_1.__importStar(require("@opentelemetry/api"));
const enums_1 = require("@opentelemetry/sdk-trace-base/build/src/enums");
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
const utils_1 = require("./utils");
const package_json_1 = require("../package.json");
const defaultTracer = api_1.default.trace.getTracer(package_json_1.name, package_json_1.version);
exports.SEMATTRS_EXCEPTION_MECHANISM = 'exception.mechanism';
exports.SEMATTRS_EXCEPTION_MODULE = 'exception.module';
exports.SEMATTRS_EXCEPTION_MODULES = 'exception.modules';
exports.SEMATTRS_EXCEPTION_PARSED_STACKTRACE = 'exception.parsed_stacktrace';
exports.SEMATTRS_EXCEPTION_TAGS = 'exception.tags';
exports.SEMATTRS_EXCEPTION_THREAD_ID = 'exception.thread_id';
exports.SEMATTRS_SENTRY_VERSION = 'sentry.version';
const extractSemAttrsFromEvent = (event, hint, sentryVersion) => {
var _a, _b, _c, _d, _e, _f;
return ({
...(sentryVersion && {
[exports.SEMATTRS_SENTRY_VERSION]: sentryVersion,
}),
...(event.modules && {
[exports.SEMATTRS_EXCEPTION_MODULES]: (0, utils_1.jsonToString)(event.modules),
}),
[exports.SEMATTRS_EXCEPTION_TAGS]: (0, utils_1.jsonToString)({
culture: (_a = event.contexts) === null || _a === void 0 ? void 0 : _a.culture,
dist: event.dist,
environment: event.environment,
mechanism: hint.mechanism,
release: event.release,
}),
...(((_b = event.contexts) === null || _b === void 0 ? void 0 : _b.app) && {
'app.build_type': event.contexts.app.build_type,
'app.id': event.contexts.app.app_identifier,
'app.memory': event.contexts.app.app_memory,
'app.name': event.contexts.app.app_name,
'app.start_time': event.contexts.app.app_start_time,
'app.version': event.contexts.app.app_version,
}),
...(((_c = event.contexts) === null || _c === void 0 ? void 0 : _c.response) && {
[semantic_conventions_1.SEMATTRS_HTTP_STATUS_CODE]: event.contexts.response.status_code,
[semantic_conventions_1.SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH]: event.contexts.response.body_size,
...(event.contexts.response.headers &&
Object.entries(event.contexts.response.headers).reduce((acc, [key, value]) => {
acc[`http.response.header.${key}`] = value;
return acc;
}),
{}),
}),
...(((_d = event.contexts) === null || _d === void 0 ? void 0 : _d.cloud_resource) && {
'cloud.provider': event.contexts.cloud_resource['cloud.provider'],
'cloud.account.id': event.contexts.cloud_resource['cloud.account.id'],
'cloud.region': event.contexts.cloud_resource['cloud.region'],
'cloud.availability_zone': event.contexts.cloud_resource['cloud.availability_zone'],
'cloud.platform': event.contexts.cloud_resource['cloud.platform'],
'host.id': event.contexts.cloud_resource['host.id'],
'host.type': event.contexts.cloud_resource['host.type'],
}),
...(((_e = event.contexts) === null || _e === void 0 ? void 0 : _e.os) && {
'os.build_id': event.contexts.os.build,
'os.kernel_version': event.contexts.os.kernel_version,
'os.type': event.contexts.os.name,
'os.version': event.contexts.os.version,
}),
...(((_f = event.contexts) === null || _f === void 0 ? void 0 : _f.device) && {
'device.id': event.contexts.device.device_unique_identifier,
'device.manufacturer': event.contexts.device.manufacturer,
'device.model.identifier': event.contexts.device.model_id,
'device.model.name': event.contexts.device.model,
'device.type': event.contexts.device.device_type,
'device.battery_level': event.contexts.device.battery_level,
'device.battery_status': event.contexts.device.battery_status,
'device.orientation': event.contexts.device.orientation,
'device.brand': event.contexts.device.brand,
'device.sreen_resolution': event.contexts.device.screen_resolution,
'device.screen_height_pixels': event.contexts.device.screen_height_pixels,
'device.screen_width_pixels': event.contexts.device.screen_width_pixels,
'device.screen_density': event.contexts.device.screen_density,
'device.screen_dpi': event.contexts.device.screen_dpi,
'device.online': event.contexts.device.online,
'device.charging': event.contexts.device.charging,
'device.supports_vibration': event.contexts.device.supports_vibration,
'device.supports_accelerometer': event.contexts.device.supports_accelerometer,
'device.supports_gyroscope': event.contexts.device.supports_gyroscope,
'device.supports_audio': event.contexts.device.supports_audio,
'device.supports_location_service': event.contexts.device.supports_location_service,
'device.boot_time': event.contexts.device.boot_time,
'device.low_memory': event.contexts.device.low_memory,
'device.simulator': event.contexts.device.simulator,
'device.memory_size': event.contexts.device.memory_size,
'device.free_memory': event.contexts.device.free_memory,
'device.usable_memory': event.contexts.device.usable_memory,
'device.storage_size': event.contexts.device.storage_size,
'device.free_storage': event.contexts.device.free_storage,
'device.external_storage_size': event.contexts.device.external_storage_size,
'device.external_free_storage': event.contexts.device.external_free_storage,
'host.cpu.model.name': event.contexts.device.cpu_description,
'host.cpu.count': event.contexts.device.processor_count,
'host.cpu.frequency': event.contexts.device.processor_frequency,
}),
...(event.server_name && {
'host.name': event.server_name,
}),
});
};
exports.extractSemAttrsFromEvent = extractSemAttrsFromEvent;
const extractSpanEventsFromException = (exception) => ({
[semantic_conventions_1.SEMATTRS_EXCEPTION_MESSAGE]: exception.value,
[exports.SEMATTRS_EXCEPTION_PARSED_STACKTRACE]: (0, utils_1.jsonToString)(exception.stacktrace),
[semantic_conventions_1.SEMATTRS_EXCEPTION_TYPE]: exception.type,
...(exception.mechanism && {
[exports.SEMATTRS_EXCEPTION_MECHANISM]: (0, utils_1.jsonToString)(exception.mechanism),
}),
...(exception.module && {
[exports.SEMATTRS_EXCEPTION_MODULE]: exception.module,
}),
...(exception.thread_id && {
[exports.SEMATTRS_EXCEPTION_THREAD_ID]: exception.thread_id,
}),
});
exports.extractSpanEventsFromException = extractSpanEventsFromException;
const isSentryEventAnException = (event) => { var _a, _b; return ((_b = (_a = event.exception) === null || _a === void 0 ? void 0 : _a.values) === null || _b === void 0 ? void 0 : _b.length) > 0; };
exports.isSentryEventAnException = isSentryEventAnException;
const getSpanNameFromEvent = (event) => {
var _a;
return event.message
? event.message
: [(_a = event.exception) === null || _a === void 0 ? void 0 : _a.values[0].type, event.transaction].join(' ');
};
exports.getSpanNameFromEvent = getSpanNameFromEvent;
const _startOtelSpanFromSentryEvent = ({ customAttributes, event, hint, sentryVersion, span, spanStatus, tracer, }) => {
var _a, _b;
let _span = span;
let isRootSpan = false;
const startTime = event.timestamp * 1000;
const eventAttributes = (0, exports.extractSemAttrsFromEvent)(event, hint, sentryVersion);
if (_span == null) {
isRootSpan = true;
_span = tracer.startSpan((0, exports.getSpanNameFromEvent)(event), {
attributes: {
...customAttributes,
...eventAttributes,
},
startTime,
kind: api_1.SpanKind.INTERNAL,
});
}
_span.setStatus({
code: spanStatus,
});
for (const exception of (_b = (_a = event.exception) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : []) {
_span.addEvent(enums_1.ExceptionEventName, (0, exports.extractSpanEventsFromException)(exception));
}
if (isRootSpan) {
_span.end(startTime);
}
};
const getEventProcessor = (tracer, sentryVersion) => (event, hint, span, attributes) => {
try {
api_1.diag.debug('Received Sentry event', event);
if ((0, exports.isSentryEventAnException)(event)) {
let _tracer = tracer;
if (_tracer == null) {
_tracer = defaultTracer;
api_1.diag.debug('Using default tracer');
}
_startOtelSpanFromSentryEvent({
customAttributes: attributes,
event,
hint,
sentryVersion,
span,
spanStatus: api_1.SpanStatusCode.ERROR,
tracer: _tracer,
});
}
}
catch (e) {
api_1.diag.error('Error processing event', e);
}
return event;
};
exports.getEventProcessor = getEventProcessor;