UNPKG

@sentry/node

Version:

Sentry Node SDK using OpenTelemetry for performance instrumentation

152 lines (148 loc) 5.73 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const dc = require('node:diagnostics_channel'); const instrumentation$1 = require('./vendored/instrumentation.js'); const core = require('@sentry/core'); const nodeCore = require('@sentry/node-core'); const debugBuild = require('../../../debug-build.js'); const instrumentation = require('./v3/instrumentation.js'); const INTEGRATION_NAME = "Fastify"; const instrumentFastifyV3 = nodeCore.generateInstrumentOnce( `${INTEGRATION_NAME}.v3`, () => new instrumentation.FastifyInstrumentationV3() ); function getFastifyIntegration() { const client = core.getClient(); if (!client) { return void 0; } else { return client.getIntegrationByName(INTEGRATION_NAME); } } function handleFastifyError(error, request, reply, handlerOrigin) { const shouldHandleError = getFastifyIntegration()?.getShouldHandleError() || defaultShouldHandleError; if (handlerOrigin === "diagnostics-channel") { this.diagnosticsChannelExists = true; } if (this.diagnosticsChannelExists && handlerOrigin === "onError-hook") { debugBuild.DEBUG_BUILD && core.debug.warn( "Fastify error handler was already registered via diagnostics channel.", "You can safely remove `setupFastifyErrorHandler` call and set `shouldHandleError` on the integration options." ); return; } if (shouldHandleError(error, request, reply)) { core.captureException(error, { mechanism: { handled: false, type: "auto.function.fastify" } }); } } const instrumentFastify = nodeCore.generateInstrumentOnce(`${INTEGRATION_NAME}.v5`, () => { const fastifyOtelInstrumentationInstance = new instrumentation$1.FastifyOtelInstrumentation(); const plugin = fastifyOtelInstrumentationInstance.plugin(); dc.subscribe("fastify.initialization", (message) => { const fastifyInstance = message.fastify; fastifyInstance?.register(plugin).after((err) => { if (err) { debugBuild.DEBUG_BUILD && core.debug.error("Failed to setup Fastify instrumentation", err); } else { instrumentClient(); if (fastifyInstance) { instrumentOnRequest(fastifyInstance); } } }); }); dc.subscribe("tracing:fastify.request.handler:error", (message) => { const { error, request, reply } = message; handleFastifyError.call(handleFastifyError, error, request, reply, "diagnostics-channel"); }); return fastifyOtelInstrumentationInstance; }); const _fastifyIntegration = (({ shouldHandleError }) => { let _shouldHandleError; return { name: INTEGRATION_NAME, setupOnce() { _shouldHandleError = shouldHandleError || defaultShouldHandleError; instrumentFastifyV3(); instrumentFastify(); }, getShouldHandleError() { return _shouldHandleError; }, setShouldHandleError(fn) { _shouldHandleError = fn; } }; }); const fastifyIntegration = core.defineIntegration( (options = {}) => _fastifyIntegration(options) ); function defaultShouldHandleError(_error, _request, reply) { const statusCode = reply.statusCode; return statusCode >= 500 || statusCode <= 299; } function setupFastifyErrorHandler(fastify, options) { if (options?.shouldHandleError) { getFastifyIntegration()?.setShouldHandleError(options.shouldHandleError); } const plugin = Object.assign( function(fastify2, _options, done) { fastify2.addHook("onError", async (request, reply, error) => { handleFastifyError.call(handleFastifyError, error, request, reply, "onError-hook"); }); done(); }, { [/* @__PURE__ */ Symbol.for("skip-override")]: true, [/* @__PURE__ */ Symbol.for("fastify.display-name")]: "sentry-fastify-error-handler" } ); fastify.register(plugin); } function addFastifySpanAttributes(span) { const spanJSON = core.spanToJSON(span); const spanName = spanJSON.description; const attributes = spanJSON.data; const type = attributes["fastify.type"]; const isHook = type === "hook"; const isHandler = type === spanName?.startsWith("handler -"); const isRequestHandler = spanName === "request" || type === "request-handler"; if (attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_OP] || !isHandler && !isRequestHandler && !isHook) { return; } const opPrefix = isHook ? "hook" : isHandler ? "middleware" : isRequestHandler ? "request_handler" : "<unknown>"; span.setAttributes({ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.otel.fastify", [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${opPrefix}.fastify` }); const attrName = attributes["fastify.name"] || attributes["plugin.name"] || attributes["hook.name"]; if (typeof attrName === "string") { const updatedName = attrName.replace(/^fastify -> /, "").replace(/^@fastify\/otel -> /, "").replace(/^@sentry\/instrumentation-fastify -> /, ""); span.updateName(updatedName); } } function instrumentClient() { const client = core.getClient(); if (client) { client.on("spanStart", (span) => { addFastifySpanAttributes(span); }); } } function instrumentOnRequest(fastify) { fastify.addHook("onRequest", async (request, _reply) => { if (request.opentelemetry) { const { span } = request.opentelemetry(); if (span) { addFastifySpanAttributes(span); } } const routeName = request.routeOptions?.url; const method = request.method || "GET"; core.getIsolationScope().setTransactionName(`${method} ${routeName}`); }); } exports.fastifyIntegration = fastifyIntegration; exports.instrumentFastify = instrumentFastify; exports.instrumentFastifyV3 = instrumentFastifyV3; exports.setupFastifyErrorHandler = setupFastifyErrorHandler; //# sourceMappingURL=index.js.map