|
1 | 1 | import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core'; |
2 | | -import { captureException, defineIntegration, getDefaultIsolationScope, getIsolationScope } from '@sentry/core'; |
| 2 | +import { |
| 3 | + SEMANTIC_ATTRIBUTE_SENTRY_OP, |
| 4 | + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, |
| 5 | + captureException, |
| 6 | + defineIntegration, |
| 7 | + getClient, |
| 8 | + getDefaultIsolationScope, |
| 9 | + getIsolationScope, |
| 10 | + spanToJSON, |
| 11 | +} from '@sentry/core'; |
3 | 12 | import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; |
4 | | -import type { IntegrationFn } from '@sentry/types'; |
| 13 | +import type { IntegrationFn, Span } from '@sentry/types'; |
5 | 14 | import { logger } from '@sentry/utils'; |
6 | 15 |
|
7 | 16 | interface MinimalNestJsExecutionContext { |
@@ -52,6 +61,16 @@ export const nestIntegration = defineIntegration(_nestIntegration); |
52 | 61 | * Setup an error handler for Nest. |
53 | 62 | */ |
54 | 63 | export function setupNestErrorHandler(app: MinimalNestJsApp, baseFilter: NestJsErrorFilter): void { |
| 64 | + // Sadly, NestInstrumentation has no requestHook, so we need to add the attributes here |
| 65 | + // We register this hook in this method, because if we register it in the integration `setup`, |
| 66 | + // it would always run even for users that are not even using Nest.js |
| 67 | + const client = getClient(); |
| 68 | + if (client) { |
| 69 | + client.on('spanStart', span => { |
| 70 | + addNestSpanAttributes(span); |
| 71 | + }); |
| 72 | + } |
| 73 | + |
55 | 74 | app.useGlobalInterceptors({ |
56 | 75 | intercept(context, next) { |
57 | 76 | if (getIsolationScope() === getDefaultIsolationScope()) { |
@@ -86,3 +105,20 @@ export function setupNestErrorHandler(app: MinimalNestJsApp, baseFilter: NestJsE |
86 | 105 |
|
87 | 106 | app.useGlobalFilters(wrappedFilter); |
88 | 107 | } |
| 108 | + |
| 109 | +function addNestSpanAttributes(span: Span): void { |
| 110 | + const attributes = spanToJSON(span).data || {}; |
| 111 | + |
| 112 | + // this is one of: app_creation, request_context, handler |
| 113 | + const type = attributes['nestjs.type']; |
| 114 | + |
| 115 | + // If this is already set, or we have no nest.js span, no need to process again... |
| 116 | + if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) { |
| 117 | + return; |
| 118 | + } |
| 119 | + |
| 120 | + span.setAttributes({ |
| 121 | + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.nestjs', |
| 122 | + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.nestjs`, |
| 123 | + }); |
| 124 | +} |
0 commit comments