UNPKG

@sentry/node

Version:

Sentry Node SDK using OpenTelemetry for performance instrumentation

134 lines (118 loc) 3.81 kB
import { ATTR_HTTP_ROUTE, ATTR_HTTP_REQUEST_METHOD } from '@opentelemetry/semantic-conventions'; import { defineIntegration, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getIsolationScope, getDefaultIsolationScope, debug, httpRequestToRequestData, captureException } from '@sentry/core'; import { generateInstrumentOnce, ensureIsWrapped } from '@sentry/node-core'; import { DEBUG_BUILD } from '../../../debug-build.js'; import { AttributeNames } from './constants.js'; import { HonoInstrumentation } from './instrumentation.js'; const INTEGRATION_NAME = 'Hono'; function addHonoSpanAttributes(span) { const attributes = spanToJSON(span).data; const type = attributes[AttributeNames.HONO_TYPE]; if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) { return; } span.setAttributes({ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.hono', [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.hono`, }); const name = attributes[AttributeNames.HONO_NAME]; if (typeof name === 'string') { span.updateName(name); } if (getIsolationScope() === getDefaultIsolationScope()) { DEBUG_BUILD && debug.warn('Isolation scope is default isolation scope - skipping setting transactionName'); return; } const route = attributes[ATTR_HTTP_ROUTE]; const method = attributes[ATTR_HTTP_REQUEST_METHOD]; if (typeof route === 'string' && typeof method === 'string') { getIsolationScope().setTransactionName(`${method} ${route}`); } } const instrumentHono = generateInstrumentOnce( INTEGRATION_NAME, () => new HonoInstrumentation({ responseHook: span => { addHonoSpanAttributes(span); }, }), ); const _honoIntegration = (() => { return { name: INTEGRATION_NAME, setupOnce() { instrumentHono(); }, }; }) ; /** * Adds Sentry tracing instrumentation for [Hono](https://hono.dev/). * * If you also want to capture errors, you need to call `setupHonoErrorHandler(app)` after you set up your Hono server. * * For more information, see the [hono documentation](https://docs.sentry.io/platforms/javascript/guides/hono/). * * @example * ```javascript * const Sentry = require('@sentry/node'); * * Sentry.init({ * integrations: [Sentry.honoIntegration()], * }) * ``` */ const honoIntegration = defineIntegration(_honoIntegration); function honoRequestHandler() { return async function sentryRequestMiddleware(context, next) { const normalizedRequest = httpRequestToRequestData(context.req); getIsolationScope().setSDKProcessingMetadata({ normalizedRequest }); await next(); }; } function defaultShouldHandleError(context) { const statusCode = context.res.status; return statusCode >= 500; } function honoErrorHandler(options) { return async function sentryErrorMiddleware(context, next) { await next(); const shouldHandleError = options?.shouldHandleError || defaultShouldHandleError; if (shouldHandleError(context)) { (context.res ).sentry = captureException(context.error, { mechanism: { type: 'auto.middleware.hono', handled: false, }, }); } }; } /** * Add a Hono error handler to capture errors to Sentry. * * @param app The Hono instances * @param options Configuration options for the handler * * @example * ```javascript * const Sentry = require('@sentry/node'); * const { Hono } = require("hono"); * * const app = new Hono(); * * Sentry.setupHonoErrorHandler(app); * * // Add your routes, etc. * ``` */ function setupHonoErrorHandler( app, options, ) { app.use(honoRequestHandler()); app.use(honoErrorHandler(options)); ensureIsWrapped(app.use, 'hono'); } export { honoIntegration, instrumentHono, setupHonoErrorHandler }; //# sourceMappingURL=index.js.map