@danieljvdm/dev-kit 1.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/package.json +1 -1
- package/skill-sources.jsonc +6 -29
- package/skill-sources.lock.json +23 -109
- package/skills/animate/LICENSE +21 -0
- package/skills/animate/NOTICE +10 -0
- package/skills/animate/SKILL.md +34 -0
- package/skills/animate/references/gestures.md +27 -0
- package/skills/animate/references/glossary.md +136 -0
- package/skills/animate/references/implementation.md +22 -0
- package/skills/animate/references/opportunities.md +18 -0
- package/skills/animate/references/principles.md +48 -0
- package/skills/animate/references/review.md +19 -0
- package/skills/cloudflare-workers/LICENSE +202 -0
- package/skills/cloudflare-workers/NOTICE +9 -0
- package/skills/cloudflare-workers/SKILL.md +26 -0
- package/skills/cloudflare-workers/references/durable-objects.md +68 -0
- package/skills/cloudflare-workers/references/sandbox.md +48 -0
- package/skills/cloudflare-workers/references/workers.md +63 -0
- package/skills/cloudflare-workers/references/wrangler.md +56 -0
- package/skills/design-ui/LICENSE +21 -0
- package/skills/design-ui/NOTICE +8 -0
- package/skills/design-ui/SKILL.md +29 -0
- package/skills/design-ui/references/appearance.md +22 -0
- package/skills/design-ui/references/components.md +33 -0
- package/skills/design-ui/references/exploration.md +50 -0
- package/skills/design-ui/references/libraries.md +39 -0
- package/skills/design-ui/references/themes.md +23 -0
- package/skills/dev-kit/SKILL.md +19 -38
- package/skills/dev-kit/references/cloudflare-worker-api.md +1 -1
- package/skills/dev-kit/references/skills.md +2 -2
- package/skills/effect-development/SKILL.md +27 -0
- package/skills/effect-development/agents/openai.yaml +4 -0
- package/skills/effect-development/references/api/index.md +32 -0
- package/skills/effect-development/references/api/schema-codecs.md +15 -0
- package/skills/{build-effect-apis/references → effect-development/references/api}/verification.md +10 -5
- package/skills/{effect-architecture-audit/SKILL.md → effect-development/references/architecture/index.md} +1 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-client.md +8 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-testing.md +7 -2
- package/skills/effect-development/references/atom/index.md +40 -0
- package/skills/{build-effect-clis/references → effect-development/references/cli}/entrypoints-and-testing.md +6 -2
- package/skills/effect-development/references/cli/index.md +39 -0
- package/skills/effect-development/references/setup.md +15 -0
- package/skills/open-pull-request/SKILL.md +11 -115
- package/skills/open-pull-request/agents/openai.yaml +3 -3
- package/skills/open-pull-request/references/evidence.md +22 -0
- package/skills/open-pull-request/references/explanation.md +21 -0
- package/skills/open-pull-request/references/publication.md +21 -0
- package/skills/sentry/LICENSE +202 -0
- package/skills/sentry/LICENSE-UPSTREAM +21 -0
- package/skills/sentry/NOTICE +14 -0
- package/skills/sentry/SKILL.md +33 -0
- package/skills/sentry/references/alert-payloads.md +105 -0
- package/skills/sentry/references/alerts.md +17 -0
- package/skills/sentry/references/artifacts.md +25 -0
- package/skills/sentry/references/auth-token.md +65 -0
- package/skills/sentry/references/concepts/ai-monitoring.md +131 -0
- package/skills/sentry/references/concepts/choosing-a-signal.md +78 -0
- package/skills/sentry/references/concepts/crons.md +50 -0
- package/skills/sentry/references/concepts/data-scrubbing.md +43 -0
- package/skills/sentry/references/concepts/errors.md +40 -0
- package/skills/sentry/references/concepts/logging.md +85 -0
- package/skills/sentry/references/concepts/metrics.md +49 -0
- package/skills/sentry/references/concepts/monitors.md +78 -0
- package/skills/sentry/references/concepts/profiling.md +38 -0
- package/skills/sentry/references/concepts/reduce-volume.md +49 -0
- package/skills/sentry/references/concepts/releases.md +43 -0
- package/skills/sentry/references/concepts/session-replay.md +35 -0
- package/skills/sentry/references/concepts/tracing.md +54 -0
- package/skills/sentry/references/concepts/user-feedback.md +36 -0
- package/skills/sentry/references/debug-artifacts/android.md +68 -0
- package/skills/sentry/references/debug-artifacts/apple.md +96 -0
- package/skills/sentry/references/debug-artifacts/dotnet.md +70 -0
- package/skills/sentry/references/debug-artifacts/flutter.md +65 -0
- package/skills/sentry/references/debug-artifacts/index.md +75 -0
- package/skills/sentry/references/debug-artifacts/javascript.md +94 -0
- package/skills/sentry/references/debug-artifacts/matching.md +73 -0
- package/skills/sentry/references/debug-artifacts/react-native.md +75 -0
- package/skills/sentry/references/first-error-setup.md +25 -0
- package/skills/sentry/references/instrumentation.md +30 -0
- package/skills/sentry/references/issues.md +32 -0
- package/skills/sentry/references/new-project.md +17 -0
- package/skills/sentry/references/otel-exporter.md +30 -0
- package/skills/sentry/references/release-workflow.md +31 -0
- package/skills/sentry/references/releases/ci-pipeline.md +214 -0
- package/skills/sentry/references/releases/index.md +93 -0
- package/skills/sentry/references/releases/suspect-commits.md +155 -0
- package/skills/sentry/references/releases/tagging.md +131 -0
- package/skills/sentry/references/releases/troubleshooting.md +67 -0
- package/skills/sentry/references/sdks/android/crons.md +305 -0
- package/skills/sentry/references/sdks/android/error-monitoring.md +800 -0
- package/skills/sentry/references/sdks/android/index.md +748 -0
- package/skills/sentry/references/sdks/android/integrations.md +48 -0
- package/skills/sentry/references/sdks/android/logging.md +374 -0
- package/skills/sentry/references/sdks/android/metrics.md +288 -0
- package/skills/sentry/references/sdks/android/profiling.md +397 -0
- package/skills/sentry/references/sdks/android/session-replay.md +406 -0
- package/skills/sentry/references/sdks/android/tracing.md +861 -0
- package/skills/sentry/references/sdks/browser/error-monitoring.md +861 -0
- package/skills/sentry/references/sdks/browser/index.md +714 -0
- package/skills/sentry/references/sdks/browser/logging.md +315 -0
- package/skills/sentry/references/sdks/browser/profiling.md +236 -0
- package/skills/sentry/references/sdks/browser/session-replay.md +586 -0
- package/skills/sentry/references/sdks/browser/tracing.md +561 -0
- package/skills/sentry/references/sdks/browser/user-feedback.md +354 -0
- package/skills/sentry/references/sdks/cloudflare/ai-monitoring.md +661 -0
- package/skills/sentry/references/sdks/cloudflare/crons.md +231 -0
- package/skills/sentry/references/sdks/cloudflare/durable-objects.md +381 -0
- package/skills/sentry/references/sdks/cloudflare/error-monitoring.md +329 -0
- package/skills/sentry/references/sdks/cloudflare/index.md +698 -0
- package/skills/sentry/references/sdks/cloudflare/logging.md +169 -0
- package/skills/sentry/references/sdks/cloudflare/nodejs-compat.md +134 -0
- package/skills/sentry/references/sdks/cloudflare/tracing.md +475 -0
- package/skills/sentry/references/sdks/cocoa/error-monitoring.md +394 -0
- package/skills/sentry/references/sdks/cocoa/index.md +497 -0
- package/skills/sentry/references/sdks/cocoa/logging.md +209 -0
- package/skills/sentry/references/sdks/cocoa/metrics.md +136 -0
- package/skills/sentry/references/sdks/cocoa/profiling.md +223 -0
- package/skills/sentry/references/sdks/cocoa/session-replay.md +257 -0
- package/skills/sentry/references/sdks/cocoa/tracing.md +524 -0
- package/skills/sentry/references/sdks/cocoa/user-feedback.md +310 -0
- package/skills/sentry/references/sdks/dotnet/crons.md +465 -0
- package/skills/sentry/references/sdks/dotnet/error-monitoring.md +1100 -0
- package/skills/sentry/references/sdks/dotnet/index.md +614 -0
- package/skills/sentry/references/sdks/dotnet/logging.md +556 -0
- package/skills/sentry/references/sdks/dotnet/metrics.md +229 -0
- package/skills/sentry/references/sdks/dotnet/profiling.md +296 -0
- package/skills/sentry/references/sdks/dotnet/tracing.md +897 -0
- package/skills/sentry/references/sdks/elixir/crons.md +371 -0
- package/skills/sentry/references/sdks/elixir/error-monitoring.md +335 -0
- package/skills/sentry/references/sdks/elixir/index.md +383 -0
- package/skills/sentry/references/sdks/elixir/logging.md +239 -0
- package/skills/sentry/references/sdks/elixir/tracing.md +233 -0
- package/skills/sentry/references/sdks/flutter/ecosystem-integrations.md +70 -0
- package/skills/sentry/references/sdks/flutter/error-monitoring.md +312 -0
- package/skills/sentry/references/sdks/flutter/index.md +728 -0
- package/skills/sentry/references/sdks/flutter/logging.md +387 -0
- package/skills/sentry/references/sdks/flutter/metrics.md +310 -0
- package/skills/sentry/references/sdks/flutter/profiling.md +214 -0
- package/skills/sentry/references/sdks/flutter/session-replay.md +308 -0
- package/skills/sentry/references/sdks/flutter/tracing.md +502 -0
- package/skills/sentry/references/sdks/go/crons.md +270 -0
- package/skills/sentry/references/sdks/go/error-monitoring.md +361 -0
- package/skills/sentry/references/sdks/go/index.md +324 -0
- package/skills/sentry/references/sdks/go/logging.md +354 -0
- package/skills/sentry/references/sdks/go/metrics.md +273 -0
- package/skills/sentry/references/sdks/go/profiling.md +46 -0
- package/skills/sentry/references/sdks/go/tracing.md +366 -0
- package/skills/sentry/references/sdks/index.md +41 -0
- package/skills/sentry/references/sdks/nestjs/ai-monitoring.md +410 -0
- package/skills/sentry/references/sdks/nestjs/crons.md +268 -0
- package/skills/sentry/references/sdks/nestjs/error-monitoring.md +729 -0
- package/skills/sentry/references/sdks/nestjs/index.md +699 -0
- package/skills/sentry/references/sdks/nestjs/logging.md +174 -0
- package/skills/sentry/references/sdks/nestjs/metrics.md +243 -0
- package/skills/sentry/references/sdks/nestjs/profiling.md +127 -0
- package/skills/sentry/references/sdks/nestjs/tracing.md +762 -0
- package/skills/sentry/references/sdks/nextjs/ai-monitoring.md +494 -0
- package/skills/sentry/references/sdks/nextjs/crons.md +383 -0
- package/skills/sentry/references/sdks/nextjs/error-monitoring.md +974 -0
- package/skills/sentry/references/sdks/nextjs/index.md +491 -0
- package/skills/sentry/references/sdks/nextjs/logging.md +381 -0
- package/skills/sentry/references/sdks/nextjs/metrics.md +411 -0
- package/skills/sentry/references/sdks/nextjs/profiling.md +403 -0
- package/skills/sentry/references/sdks/nextjs/session-replay.md +462 -0
- package/skills/sentry/references/sdks/nextjs/tracing.md +628 -0
- package/skills/sentry/references/sdks/node/ai-monitoring.md +303 -0
- package/skills/sentry/references/sdks/node/crons.md +432 -0
- package/skills/sentry/references/sdks/node/error-monitoring.md +1125 -0
- package/skills/sentry/references/sdks/node/index.md +942 -0
- package/skills/sentry/references/sdks/node/logging.md +380 -0
- package/skills/sentry/references/sdks/node/metrics.md +278 -0
- package/skills/sentry/references/sdks/node/profiling.md +373 -0
- package/skills/sentry/references/sdks/node/tracing.md +878 -0
- package/skills/sentry/references/sdks/php/ai-monitoring.md +310 -0
- package/skills/sentry/references/sdks/php/crons.md +265 -0
- package/skills/sentry/references/sdks/php/error-monitoring.md +626 -0
- package/skills/sentry/references/sdks/php/index.md +362 -0
- package/skills/sentry/references/sdks/php/laravel.md +542 -0
- package/skills/sentry/references/sdks/php/logging.md +242 -0
- package/skills/sentry/references/sdks/php/metrics.md +193 -0
- package/skills/sentry/references/sdks/php/profiling.md +115 -0
- package/skills/sentry/references/sdks/php/symfony.md +552 -0
- package/skills/sentry/references/sdks/php/tracing.md +516 -0
- package/skills/sentry/references/sdks/python/ai-monitoring.md +351 -0
- package/skills/sentry/references/sdks/python/crons.md +218 -0
- package/skills/sentry/references/sdks/python/error-monitoring.md +292 -0
- package/skills/sentry/references/sdks/python/index.md +361 -0
- package/skills/sentry/references/sdks/python/logging.md +234 -0
- package/skills/sentry/references/sdks/python/metrics.md +154 -0
- package/skills/sentry/references/sdks/python/profiling.md +120 -0
- package/skills/sentry/references/sdks/python/tracing.md +364 -0
- package/skills/sentry/references/sdks/react/error-monitoring.md +1607 -0
- package/skills/sentry/references/sdks/react/index.md +492 -0
- package/skills/sentry/references/sdks/react/logging.md +364 -0
- package/skills/sentry/references/sdks/react/profiling.md +322 -0
- package/skills/sentry/references/sdks/react/react-features.md +1272 -0
- package/skills/sentry/references/sdks/react/session-replay.md +1193 -0
- package/skills/sentry/references/sdks/react/tracing.md +1415 -0
- package/skills/sentry/references/sdks/react-native/error-monitoring.md +1481 -0
- package/skills/sentry/references/sdks/react-native/expo-config-plugin.md +45 -0
- package/skills/sentry/references/sdks/react-native/index.md +1030 -0
- package/skills/sentry/references/sdks/react-native/logging.md +444 -0
- package/skills/sentry/references/sdks/react-native/profiling.md +386 -0
- package/skills/sentry/references/sdks/react-native/session-replay.md +704 -0
- package/skills/sentry/references/sdks/react-native/tracing.md +1086 -0
- package/skills/sentry/references/sdks/react-native/user-feedback.md +815 -0
- package/skills/sentry/references/sdks/react-router-framework/error-monitoring.md +127 -0
- package/skills/sentry/references/sdks/react-router-framework/index.md +411 -0
- package/skills/sentry/references/sdks/react-router-framework/logging.md +66 -0
- package/skills/sentry/references/sdks/react-router-framework/profiling.md +57 -0
- package/skills/sentry/references/sdks/react-router-framework/react-router-framework-features.md +110 -0
- package/skills/sentry/references/sdks/react-router-framework/session-replay.md +67 -0
- package/skills/sentry/references/sdks/react-router-framework/tracing.md +96 -0
- package/skills/sentry/references/sdks/react-router-framework/user-feedback.md +71 -0
- package/skills/sentry/references/sdks/ruby/crons.md +184 -0
- package/skills/sentry/references/sdks/ruby/error-monitoring.md +248 -0
- package/skills/sentry/references/sdks/ruby/index.md +297 -0
- package/skills/sentry/references/sdks/ruby/logging.md +168 -0
- package/skills/sentry/references/sdks/ruby/metrics.md +196 -0
- package/skills/sentry/references/sdks/ruby/migration.md +321 -0
- package/skills/sentry/references/sdks/ruby/profiling.md +107 -0
- package/skills/sentry/references/sdks/ruby/tracing.md +388 -0
- package/skills/sentry/references/sdks/svelte/error-monitoring.md +456 -0
- package/skills/sentry/references/sdks/svelte/index.md +467 -0
- package/skills/sentry/references/sdks/svelte/logging.md +344 -0
- package/skills/sentry/references/sdks/svelte/session-replay.md +369 -0
- package/skills/sentry/references/sdks/svelte/tracing.md +406 -0
- package/skills/sentry/references/sdks/tanstack-start/error-monitoring.md +149 -0
- package/skills/sentry/references/sdks/tanstack-start/index.md +381 -0
- package/skills/sentry/references/sdks/tanstack-start/logging.md +74 -0
- package/skills/sentry/references/sdks/tanstack-start/session-replay.md +76 -0
- package/skills/sentry/references/sdks/tanstack-start/tanstackstart-features.md +128 -0
- package/skills/sentry/references/sdks/tanstack-start/tracing.md +123 -0
- package/skills/sentry/references/sdks/tanstack-start/user-feedback.md +81 -0
- package/skills/sentry/references/search-query-language.md +226 -0
- package/skills/sentry/references/semantics/angular.md +7 -0
- package/skills/sentry/references/semantics/app.md +28 -0
- package/skills/sentry/references/semantics/art.md +17 -0
- package/skills/sentry/references/semantics/aws.md +43 -0
- package/skills/sentry/references/semantics/browser.md +34 -0
- package/skills/sentry/references/semantics/cache.md +12 -0
- package/skills/sentry/references/semantics/client.md +8 -0
- package/skills/sentry/references/semantics/cloud.md +12 -0
- package/skills/sentry/references/semantics/cloudflare.md +23 -0
- package/skills/sentry/references/semantics/code.md +11 -0
- package/skills/sentry/references/semantics/culture.md +11 -0
- package/skills/sentry/references/semantics/db.md +21 -0
- package/skills/sentry/references/semantics/device.md +43 -0
- package/skills/sentry/references/semantics/error.md +7 -0
- package/skills/sentry/references/semantics/event.md +8 -0
- package/skills/sentry/references/semantics/exception.md +10 -0
- package/skills/sentry/references/semantics/faas.md +19 -0
- package/skills/sentry/references/semantics/file.md +8 -0
- package/skills/sentry/references/semantics/flag.md +7 -0
- package/skills/sentry/references/semantics/gcp.md +16 -0
- package/skills/sentry/references/semantics/gen_ai.md +53 -0
- package/skills/sentry/references/semantics/general.md +11 -0
- package/skills/sentry/references/semantics/graphql.md +9 -0
- package/skills/sentry/references/semantics/grpc.md +19 -0
- package/skills/sentry/references/semantics/http.md +34 -0
- package/skills/sentry/references/semantics/index.md +63 -0
- package/skills/sentry/references/semantics/jsonrpc.md +8 -0
- package/skills/sentry/references/semantics/jvm.md +12 -0
- package/skills/sentry/references/semantics/koa.md +7 -0
- package/skills/sentry/references/semantics/logger.md +7 -0
- package/skills/sentry/references/semantics/mcp.md +37 -0
- package/skills/sentry/references/semantics/mdc.md +7 -0
- package/skills/sentry/references/semantics/messaging.md +23 -0
- package/skills/sentry/references/semantics/middleware.md +7 -0
- package/skills/sentry/references/semantics/navigation.md +9 -0
- package/skills/sentry/references/semantics/nel.md +11 -0
- package/skills/sentry/references/semantics/network.md +17 -0
- package/skills/sentry/references/semantics/os.md +15 -0
- package/skills/sentry/references/semantics/otel.md +10 -0
- package/skills/sentry/references/semantics/params.md +7 -0
- package/skills/sentry/references/semantics/process.md +14 -0
- package/skills/sentry/references/semantics/react.md +7 -0
- package/skills/sentry/references/semantics/remix.md +7 -0
- package/skills/sentry/references/semantics/resource.md +7 -0
- package/skills/sentry/references/semantics/rpc.md +10 -0
- package/skills/sentry/references/semantics/score.md +10 -0
- package/skills/sentry/references/semantics/sentry.md +69 -0
- package/skills/sentry/references/semantics/server.md +8 -0
- package/skills/sentry/references/semantics/service.md +8 -0
- package/skills/sentry/references/semantics/session.md +7 -0
- package/skills/sentry/references/semantics/state.md +7 -0
- package/skills/sentry/references/semantics/thread.md +8 -0
- package/skills/sentry/references/semantics/timber.md +7 -0
- package/skills/sentry/references/semantics/trpc.md +8 -0
- package/skills/sentry/references/semantics/ui.md +18 -0
- package/skills/sentry/references/semantics/url.md +15 -0
- package/skills/sentry/references/semantics/user.md +17 -0
- package/skills/sentry/references/semantics/user_agent.md +7 -0
- package/skills/sentry/references/semantics/vercel.md +42 -0
- package/skills/sentry/references/setup-verification.md +39 -0
- package/skills/sentry/references/snapshots/github-actions-fanout.md +206 -0
- package/skills/sentry/references/snapshots/github-actions-simple.md +102 -0
- package/skills/sentry/references/snapshots/github-actions-swift-snapshot-testing.md +118 -0
- package/skills/sentry/references/snapshots/index.md +19 -0
- package/skills/sentry/references/snapshots/snapshot-previews.md +100 -0
- package/skills/sentry/references/snapshots/snapshots.md +123 -0
- package/skills/sentry/references/snapshots/wizard-setup.md +134 -0
- package/skills/testing/LICENSE +21 -0
- package/skills/testing/NOTICE +7 -0
- package/skills/testing/SKILL.md +13 -19
- package/skills/testing/agents/openai.yaml +1 -2
- package/skills/testing/references/selection.md +23 -0
- package/skills/testing/references/tdd.md +19 -0
- package/skills/testing/references/test-design.md +17 -0
- package/src/catalog.ts +1 -7
- package/skills/build-effect-apis/SKILL.md +0 -81
- package/skills/build-effect-apis/agents/openai.yaml +0 -4
- package/skills/build-effect-clis/SKILL.md +0 -92
- package/skills/build-effect-clis/agents/openai.yaml +0 -4
- package/skills/effect-architecture-audit/agents/openai.yaml +0 -4
- package/skills/effect-atom-state/SKILL.md +0 -97
- package/skills/effect-atom-state/agents/openai.yaml +0 -4
- package/skills/effect-ts/SKILL.md +0 -35
- package/skills/effect-ts/agents/openai.yaml +0 -4
- /package/skills/{build-effect-apis/references → effect-development/references/api}/cloudflare-workers.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/runtime-assembly.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/server-and-middleware.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/shared-contracts.md +0 -0
- /package/skills/{effect-architecture-audit/references → effect-development/references/architecture}/service-and-boundary-audit.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-lifecycle.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-workflows.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/tanstack-start.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/command-design.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/processes-and-platform.md +0 -0
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
# Tracing — Sentry NestJS SDK
|
|
2
|
+
|
|
3
|
+
> Minimum SDK: `@sentry/nestjs` 8.x (requires Node >= 18.0.0; 18.19.0+ or 19.9.0+
|
|
4
|
+
> recommended)
|
|
5
|
+
|
|
6
|
+
## Configuration
|
|
7
|
+
|
|
8
|
+
| Option | Type | Default | Purpose |
|
|
9
|
+
| -------------------------- | ---------------------- | ----------- | -------------------------------------------------------------------------------------------- |
|
|
10
|
+
| `tracesSampleRate` | `number` | `undefined` | Fraction of transactions to trace (0.0–1.0); omit to disable tracing |
|
|
11
|
+
| `tracesSampler` | `function` | `undefined` | Per-transaction sampling function; overrides `tracesSampleRate` |
|
|
12
|
+
| `tracePropagationTargets` | `(string \| RegExp)[]` | all origins | URLs/patterns to inject `sentry-trace` / `baggage` headers into |
|
|
13
|
+
| `profileSessionSampleRate` | `number` | `undefined` | Fraction of **process sessions** to profile (0.0–1.0); decided once at init |
|
|
14
|
+
| `profileLifecycle` | `'trace' \| 'manual'` | `'trace'` | `'trace'` = auto start/stop with spans; `'manual'` = call `startProfiler()`/`stopProfiler()` |
|
|
15
|
+
| `beforeSendSpan` | `function` | `undefined` | Callback to mutate or drop individual spans before sending |
|
|
16
|
+
| `skipOpenTelemetrySetup` | `boolean` | `false` | Skip automatic OTel provider setup (for custom OTel configurations) |
|
|
17
|
+
| `strictTraceContinuation` | `boolean` | `false` | Only continue traces from same Sentry org (v10+) |
|
|
18
|
+
|
|
19
|
+
## Architecture
|
|
20
|
+
|
|
21
|
+
`@sentry/nestjs` is a thin wrapper over `@sentry/node`. Its tracing stack:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
@sentry/nestjs
|
|
25
|
+
├── Sentry.init() → auto-adds nestIntegration() to default integrations
|
|
26
|
+
├── nestIntegration() → registers 3 OTel instrumentations:
|
|
27
|
+
│ ├── @opentelemetry/instrumentation-nestjs-core → app_creation, request_context, handler spans
|
|
28
|
+
│ ├── SentryNestInstrumentation → middleware, guard, pipe, interceptor, filter spans
|
|
29
|
+
│ └── SentryNestEventInstrumentation → @OnEvent handler spans
|
|
30
|
+
├── SentryModule.forRoot() → registers SentryTracingInterceptor globally
|
|
31
|
+
├── SentryTracingInterceptor → sets HTTP transaction names from Express/Fastify route patterns
|
|
32
|
+
└── SentryGlobalFilter → captures unhandled exceptions (HTTP, GraphQL, RPC)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Sentry is the OpenTelemetry provider — any OTel instrumentation automatically flows into
|
|
36
|
+
Sentry.
|
|
37
|
+
|
|
38
|
+
## Code Examples
|
|
39
|
+
|
|
40
|
+
### Enable tracing
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// instrument.ts — must be loaded FIRST in main.ts, before NestJS imports
|
|
44
|
+
import * as Sentry from "@sentry/nestjs";
|
|
45
|
+
|
|
46
|
+
Sentry.init({
|
|
47
|
+
dsn: "https://<key>@<org>.ingest.sentry.io/<project>",
|
|
48
|
+
tracesSampleRate: 1.0, // 1.0 = 100% of transactions; reduce in production
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// main.ts
|
|
54
|
+
import "./instrument"; // MUST be first — before @nestjs/core or any module
|
|
55
|
+
import { NestFactory } from "@nestjs/core";
|
|
56
|
+
import { AppModule } from "./app.module";
|
|
57
|
+
|
|
58
|
+
async function bootstrap() {
|
|
59
|
+
const app = await NestFactory.create(AppModule);
|
|
60
|
+
await app.listen(3000);
|
|
61
|
+
}
|
|
62
|
+
bootstrap();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// app.module.ts — two distinct entry points
|
|
67
|
+
import { Module } from "@nestjs/common";
|
|
68
|
+
import { SentryModule } from "@sentry/nestjs/setup"; // /setup entry point
|
|
69
|
+
import { APP_FILTER } from "@nestjs/core";
|
|
70
|
+
import { SentryGlobalFilter } from "@sentry/nestjs/setup"; // /setup entry point
|
|
71
|
+
|
|
72
|
+
@Module({
|
|
73
|
+
imports: [SentryModule.forRoot()], // registers SentryTracingInterceptor globally
|
|
74
|
+
providers: [
|
|
75
|
+
{
|
|
76
|
+
provide: APP_FILTER,
|
|
77
|
+
useClass: SentryGlobalFilter, // captures unhandled HTTP/GraphQL/RPC exceptions
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
})
|
|
81
|
+
export class AppModule {}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> **`@sentry/nestjs` vs `@sentry/nestjs/setup` — two separate entry points:**
|
|
85
|
+
>
|
|
86
|
+
> - `@sentry/nestjs` — `Sentry.init()`, decorators, span APIs, all `@sentry/node`
|
|
87
|
+
> re-exports
|
|
88
|
+
> - `@sentry/nestjs/setup` — `SentryModule`, `SentryTracingInterceptor`,
|
|
89
|
+
> `SentryGlobalFilter`
|
|
90
|
+
|
|
91
|
+
### HTTP request auto-tracing
|
|
92
|
+
|
|
93
|
+
HTTP tracing requires no extra code.
|
|
94
|
+
Two mechanisms work together:
|
|
95
|
+
|
|
96
|
+
1. **`nestIntegration`** (via `@opentelemetry/instrumentation-nestjs-core`) creates
|
|
97
|
+
spans:
|
|
98
|
+
- `app_creation.nestjs` — NestJS bootstrap
|
|
99
|
+
- `request_context.nestjs` — overall request handling
|
|
100
|
+
- `handler.nestjs` — each route handler
|
|
101
|
+
|
|
102
|
+
2. **`SentryTracingInterceptor`** (registered via `SentryModule.forRoot()`) sets the
|
|
103
|
+
transaction name from the parameterized route:
|
|
104
|
+
- Express: `GET /users/:id` (from `req.route.path`)
|
|
105
|
+
- Fastify: `GET /users/:id` (from `req.routeOptions.url`)
|
|
106
|
+
|
|
107
|
+
**Typical span tree for a request:**
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
GET /api/users/:id (transaction name)
|
|
111
|
+
└── request_context.nestjs
|
|
112
|
+
├── AuthGuard (middleware.nestjs)
|
|
113
|
+
├── ParseIntPipe (middleware.nestjs)
|
|
114
|
+
├── LoggingInterceptor (middleware.nestjs — before route)
|
|
115
|
+
│ └── handler.nestjs
|
|
116
|
+
│ └── db query span (auto from pg/mysql/etc.)
|
|
117
|
+
└── LoggingInterceptor - Interceptors - After Route (middleware.nestjs)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
> All NestJS lifecycle spans (middleware, guards, pipes, interceptors, filters) share op
|
|
121
|
+
> `middleware.nestjs`.
|
|
122
|
+
|
|
123
|
+
### `@SentryTraced` decorator
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { SentryTraced } from "@sentry/nestjs";
|
|
127
|
+
import { Injectable } from "@nestjs/common";
|
|
128
|
+
|
|
129
|
+
@Injectable()
|
|
130
|
+
export class OrderService {
|
|
131
|
+
@SentryTraced("db.query") // op="db.query", name="findOrder" (method name)
|
|
132
|
+
async findOrder(id: string) {
|
|
133
|
+
return this.orderRepo.findOne({ where: { id } });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@SentryTraced() // op="function" (default)
|
|
137
|
+
async processOrder(data: CreateOrderDto) {
|
|
138
|
+
return this.process(data);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- Span `name` = method name (e.g., `"findOrder"`)
|
|
144
|
+
- Span `op` = decorator argument, defaults to `"function"`
|
|
145
|
+
- Works with both sync and async methods
|
|
146
|
+
- Copies `reflect-metadata` keys — NestJS DI compatibility preserved
|
|
147
|
+
|
|
148
|
+
### Custom spans with `startSpan` (auto-ends)
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import * as Sentry from "@sentry/nestjs";
|
|
152
|
+
import { Injectable } from "@nestjs/common";
|
|
153
|
+
|
|
154
|
+
@Injectable()
|
|
155
|
+
export class PaymentService {
|
|
156
|
+
async charge(userId: string, amount: number) {
|
|
157
|
+
return Sentry.startSpan({ name: "charge-card", op: "payment.charge" }, async (span) => {
|
|
158
|
+
span.setAttribute("payment.userId", userId);
|
|
159
|
+
span.setAttribute("payment.amount", amount);
|
|
160
|
+
const result = await this.stripeService.charge(userId, amount);
|
|
161
|
+
span.setAttribute("payment.transactionId", result.id);
|
|
162
|
+
return result;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### `startSpanManual` (callback-style, must call `span.end()`)
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
return Sentry.startSpanManual({ name: "legacy-callback", op: "function" }, (span) => {
|
|
172
|
+
legacyLib.doWork((err, result) => {
|
|
173
|
+
span.setStatus({ code: err ? 2 : 1 }); // 1=OK, 2=ERROR
|
|
174
|
+
span.end();
|
|
175
|
+
callback(err, result);
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `startInactiveSpan` (detached, no auto-parent)
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const span = Sentry.startInactiveSpan({ name: "background-index", op: "task" });
|
|
184
|
+
// ... do work independently ...
|
|
185
|
+
span.end();
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Span options reference
|
|
189
|
+
|
|
190
|
+
| Option | Type | Description |
|
|
191
|
+
| ------------------ | --------------------------------------------- | ----------------------------------------------------------------------- |
|
|
192
|
+
| `name` | `string` | **Required.** Span name |
|
|
193
|
+
| `op` | `string` | Operation type (`db`, `http.client`, `function`, `queue.process`, etc.) |
|
|
194
|
+
| `attributes` | `Record<string, string \| number \| boolean>` | Key-value metadata |
|
|
195
|
+
| `startTime` | `number` | Custom start timestamp (Unix seconds) |
|
|
196
|
+
| `parentSpan` | `Span` | Explicit parent (overrides auto-parent from context) |
|
|
197
|
+
| `onlyIfParent` | `boolean` | Skip creating span if no active parent exists |
|
|
198
|
+
| `forceTransaction` | `boolean` | Display as root transaction in Sentry UI |
|
|
199
|
+
|
|
200
|
+
### Accessing and modifying the active span
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import * as Sentry from "@sentry/nestjs";
|
|
204
|
+
|
|
205
|
+
// Read active span
|
|
206
|
+
const span = Sentry.getActiveSpan();
|
|
207
|
+
if (span) {
|
|
208
|
+
span.setAttribute("user.id", userId);
|
|
209
|
+
span.setAttributes({ "order.type": "subscription", "order.currency": "USD" });
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Update span name (v8.47.0+)
|
|
213
|
+
if (span) Sentry.updateSpanName(span, "Refined Operation Name");
|
|
214
|
+
|
|
215
|
+
// Span status codes: 0=UNSET, 1=OK, 2=ERROR
|
|
216
|
+
span?.setStatus({ code: 2 });
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Nested spans
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
return Sentry.startSpan({ name: "process-checkout", op: "business.logic" }, async () => {
|
|
223
|
+
const cart = await Sentry.startSpan({ name: "fetch-cart", op: "db.query" }, () =>
|
|
224
|
+
this.cartRepo.findById(cartId),
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
await Sentry.startSpan({ name: "apply-discount", op: "function" }, () =>
|
|
228
|
+
this.discountService.apply(cart),
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
return Sentry.startSpan({ name: "create-order", op: "db.query" }, () =>
|
|
232
|
+
this.orderRepo.create(cart),
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Modify all spans globally (`beforeSendSpan`)
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
Sentry.init({
|
|
241
|
+
dsn: "YOUR_DSN",
|
|
242
|
+
beforeSendSpan(span) {
|
|
243
|
+
if (span.op === "db.query" && span.description?.includes("password")) {
|
|
244
|
+
span.description = "[REDACTED]";
|
|
245
|
+
}
|
|
246
|
+
// return null to drop the span entirely
|
|
247
|
+
return span;
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Dynamic sampling with `tracesSampler`
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
Sentry.init({
|
|
256
|
+
dsn: "YOUR_DSN",
|
|
257
|
+
tracesSampler: ({ name, attributes, parentSampled }) => {
|
|
258
|
+
// Drop health check endpoints
|
|
259
|
+
if (/\/(health|ping|readiness|liveness)/.test(name)) return 0;
|
|
260
|
+
|
|
261
|
+
// Always capture authentication flows
|
|
262
|
+
if (name.includes("/auth/")) return 1;
|
|
263
|
+
|
|
264
|
+
// Inherit parent's sampling decision (distributed tracing)
|
|
265
|
+
if (parentSampled !== undefined) return parentSampled;
|
|
266
|
+
|
|
267
|
+
// Default 10%
|
|
268
|
+
return 0.1;
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Event emitter auto-tracing (`@OnEvent`)
|
|
274
|
+
|
|
275
|
+
Requires `@nestjs/event-emitter` >= 2.0.0. Handlers are auto-wrapped — no code changes
|
|
276
|
+
needed:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
import { OnEvent } from "@nestjs/event-emitter";
|
|
280
|
+
import { Injectable } from "@nestjs/common";
|
|
281
|
+
|
|
282
|
+
@Injectable()
|
|
283
|
+
export class NotificationListener {
|
|
284
|
+
@OnEvent("user.created")
|
|
285
|
+
async handleUserCreated(payload: UserCreatedEvent) {
|
|
286
|
+
// Auto span: name="event user.created", op="event.nestjs"
|
|
287
|
+
// forceTransaction: true → appears as separate root transaction in Sentry UI
|
|
288
|
+
// Unhandled exceptions auto-captured (they bypass SentryGlobalFilter)
|
|
289
|
+
await this.emailService.sendWelcome(payload.userId);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
@OnEvent("user.created")
|
|
293
|
+
@OnEvent("user.updated")
|
|
294
|
+
async handleUserChange(payload: UserEvent) {
|
|
295
|
+
// Span: name="event user.created|user.updated"
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
@OnEvent("order.*") // wildcards supported
|
|
299
|
+
async handleOrder(payload: OrderEvent) {
|
|
300
|
+
await this.orderService.process(payload);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
> **Note:** Event spans always use `forceTransaction: true` — they appear as isolated
|
|
306
|
+
> root transactions, not child spans of the HTTP request that emitted the event.
|
|
307
|
+
|
|
308
|
+
### GraphQL resolver tracing
|
|
309
|
+
|
|
310
|
+
GraphQL is auto-traced via `graphqlIntegration` (enabled by default).
|
|
311
|
+
No configuration needed:
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
// Spans auto-created for:
|
|
315
|
+
// - Query/mutation/subscription execution
|
|
316
|
+
// - Individual resolver fields
|
|
317
|
+
|
|
318
|
+
// SentryGlobalFilter handles GraphQL exceptions correctly:
|
|
319
|
+
// - HttpException → rethrown without capturing (expected)
|
|
320
|
+
// - All other errors → captured then rethrown (GraphQL ExternalExceptionFilter needs the rethrow)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Microservices — transport support matrix
|
|
324
|
+
|
|
325
|
+
| Transport | Auto-traced? | Mechanism |
|
|
326
|
+
| --------------- | ------------ | ------------------------------------------------------------------------------------------ |
|
|
327
|
+
| AMQP / RabbitMQ | ✅ | `amqplibIntegration` — `amqp.publish` + `amqp.process` spans, headers auto-injected |
|
|
328
|
+
| Kafka (KafkaJS) | ✅ | `kafkaIntegration` — `kafka.send` + `kafka.process` spans, trace context in record headers |
|
|
329
|
+
| Redis pub/sub | ⚠️ Partial | `redisIntegration` traces Redis commands only |
|
|
330
|
+
| TCP | ❌ | No OTel instrumentation |
|
|
331
|
+
| NATS | ❌ | Community OTel NATS package needed |
|
|
332
|
+
| gRPC | ❌ | Community OTel gRPC package needed |
|
|
333
|
+
|
|
334
|
+
### WebSocket gateway tracing (manual)
|
|
335
|
+
|
|
336
|
+
No dedicated WebSocket auto-tracing exists.
|
|
337
|
+
`SentryTracingInterceptor` only handles HTTP contexts:
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import { SubscribeMessage, WebSocketGateway, MessageBody } from "@nestjs/websockets";
|
|
341
|
+
import * as Sentry from "@sentry/nestjs";
|
|
342
|
+
|
|
343
|
+
@WebSocketGateway(3001)
|
|
344
|
+
export class ChatGateway {
|
|
345
|
+
@SubscribeMessage("message")
|
|
346
|
+
async handleMessage(@MessageBody() payload: { data: any; _sentry?: any }) {
|
|
347
|
+
const { sentryTrace, baggage } = payload._sentry ?? {};
|
|
348
|
+
|
|
349
|
+
return Sentry.continueTrace({ sentryTrace, baggage }, () =>
|
|
350
|
+
Sentry.startSpan(
|
|
351
|
+
{
|
|
352
|
+
name: "ws.chat.message",
|
|
353
|
+
op: "websocket.server",
|
|
354
|
+
forceTransaction: true,
|
|
355
|
+
},
|
|
356
|
+
async () => this.chatService.process(payload.data),
|
|
357
|
+
),
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Client: attach trace context to every message
|
|
363
|
+
const traceData = Sentry.getTraceData();
|
|
364
|
+
socket.emit("message", {
|
|
365
|
+
data: payload,
|
|
366
|
+
_sentry: {
|
|
367
|
+
sentryTrace: traceData["sentry-trace"],
|
|
368
|
+
baggage: traceData["baggage"],
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Bull/BullMQ job tracing (manual)
|
|
374
|
+
|
|
375
|
+
No dedicated Bull integration — use manual spans in `@Process()` handlers.
|
|
376
|
+
Always wrap with `withIsolationScope` to prevent scope leakage between concurrent jobs.
|
|
377
|
+
|
|
378
|
+
#### BullMQ with `WorkerHost` (recommended for `@nestjs/bullmq`)
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
import { Processor, WorkerHost } from "@nestjs/bullmq";
|
|
382
|
+
import { Job } from "bullmq";
|
|
383
|
+
import * as Sentry from "@sentry/nestjs";
|
|
384
|
+
|
|
385
|
+
@Processor("email")
|
|
386
|
+
export class EmailProcessor extends WorkerHost {
|
|
387
|
+
async process(job: Job) {
|
|
388
|
+
return Sentry.withIsolationScope(() =>
|
|
389
|
+
Sentry.startSpan(
|
|
390
|
+
{
|
|
391
|
+
name: `email ${job.name}`,
|
|
392
|
+
op: "queue.process",
|
|
393
|
+
forceTransaction: true,
|
|
394
|
+
attributes: {
|
|
395
|
+
"messaging.system": "bullmq",
|
|
396
|
+
"messaging.destination": "email",
|
|
397
|
+
"messaging.message.id": job.id ?? "unknown",
|
|
398
|
+
"job.name": job.name,
|
|
399
|
+
"job.attemptsMade": job.attemptsMade,
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
async () => {
|
|
403
|
+
await this.emailService.sendWelcomeEmail(job.data.userId);
|
|
404
|
+
},
|
|
405
|
+
),
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
> **Why `withIsolationScope`?** BullMQ processes jobs concurrently in the same process.
|
|
412
|
+
> Without isolation, `setTag`, `setUser`, and breadcrumbs leak between concurrent jobs.
|
|
413
|
+
|
|
414
|
+
#### Bull with `@Process()` decorator
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
import { Process, Processor } from "@nestjs/bull";
|
|
418
|
+
import { Job } from "bull";
|
|
419
|
+
import * as Sentry from "@sentry/nestjs";
|
|
420
|
+
|
|
421
|
+
@Processor("email")
|
|
422
|
+
export class EmailProcessor {
|
|
423
|
+
@Process("send-welcome")
|
|
424
|
+
async handle(job: Job<{ userId: string; _sentry?: Record<string, string> }>) {
|
|
425
|
+
const { _sentry, ...data } = job.data;
|
|
426
|
+
|
|
427
|
+
return Sentry.withIsolationScope(() =>
|
|
428
|
+
Sentry.continueTrace(
|
|
429
|
+
{
|
|
430
|
+
sentryTrace: _sentry?.["sentry-trace"],
|
|
431
|
+
baggage: _sentry?.["baggage"],
|
|
432
|
+
},
|
|
433
|
+
() =>
|
|
434
|
+
Sentry.startSpan(
|
|
435
|
+
{
|
|
436
|
+
name: "email.send-welcome",
|
|
437
|
+
op: "queue.process",
|
|
438
|
+
forceTransaction: true,
|
|
439
|
+
},
|
|
440
|
+
async (span) => {
|
|
441
|
+
span.setAttribute("job.id", job.id.toString());
|
|
442
|
+
span.setAttribute("job.attemptsMade", job.attemptsMade);
|
|
443
|
+
await this.emailService.sendWelcomeEmail(data.userId);
|
|
444
|
+
},
|
|
445
|
+
),
|
|
446
|
+
),
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
#### Publisher — attach trace context to job data
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
async queueWelcomeEmail(userId: string) {
|
|
456
|
+
return Sentry.startSpan({ name: "email.queue", op: "queue.publish" }, () => {
|
|
457
|
+
const traceData = Sentry.getTraceData();
|
|
458
|
+
return this.emailQueue.add("send-welcome", { userId, _sentry: traceData });
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Kafka / NATS microservice handler tracing
|
|
464
|
+
|
|
465
|
+
Kafka messages are auto-instrumented by `kafkaIntegration` (KafkaJS), but NATS and other
|
|
466
|
+
transports require manual spans.
|
|
467
|
+
For consistency, wrapping `@EventPattern()` and `@MessagePattern()` handlers with
|
|
468
|
+
explicit spans is recommended for all transports:
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
import { Controller } from "@nestjs/common";
|
|
472
|
+
import { EventPattern, MessagePattern, Payload } from "@nestjs/microservices";
|
|
473
|
+
import * as Sentry from "@sentry/nestjs";
|
|
474
|
+
|
|
475
|
+
@Controller()
|
|
476
|
+
export class OrderController {
|
|
477
|
+
@EventPattern("order.created")
|
|
478
|
+
async handleOrderCreated(@Payload() data: OrderEvent) {
|
|
479
|
+
return Sentry.startSpan(
|
|
480
|
+
{ name: "handleOrderCreated", op: "kafka", forceTransaction: true },
|
|
481
|
+
async () => {
|
|
482
|
+
await this.orderService.processCreated(data);
|
|
483
|
+
},
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
@MessagePattern("order.get")
|
|
488
|
+
async getOrder(@Payload() data: { id: string }) {
|
|
489
|
+
return Sentry.startSpan({ name: "getOrder", op: "rpc" }, async () => {
|
|
490
|
+
return this.orderService.findById(data.id);
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
> Use `forceTransaction: true` for event handlers that should appear as root
|
|
497
|
+
> transactions in Sentry UI.
|
|
498
|
+
|
|
499
|
+
### Distributed tracing between services
|
|
500
|
+
|
|
501
|
+
HTTP services propagate `sentry-trace` and `baggage` headers automatically.
|
|
502
|
+
For custom channels:
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
// Service A — publish with trace context
|
|
506
|
+
async sendToQueue(data: any) {
|
|
507
|
+
return Sentry.startSpan({ name: "queue.publish", op: "queue.publish" }, () => {
|
|
508
|
+
const traceData = Sentry.getTraceData();
|
|
509
|
+
return this.queue.send({
|
|
510
|
+
payload: data,
|
|
511
|
+
headers: {
|
|
512
|
+
"sentry-trace": traceData["sentry-trace"],
|
|
513
|
+
"baggage": traceData["baggage"],
|
|
514
|
+
},
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Service B — continue trace from received message
|
|
520
|
+
async handleMessage(message: any) {
|
|
521
|
+
return Sentry.continueTrace(
|
|
522
|
+
{
|
|
523
|
+
sentryTrace: message.headers["sentry-trace"],
|
|
524
|
+
baggage: message.headers["baggage"],
|
|
525
|
+
},
|
|
526
|
+
() => Sentry.startSpan(
|
|
527
|
+
{ name: "queue.process", op: "queue.process" },
|
|
528
|
+
() => this.processPayload(message.payload)
|
|
529
|
+
)
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Limit trace propagation targets
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
Sentry.init({
|
|
538
|
+
dsn: "YOUR_DSN",
|
|
539
|
+
tracePropagationTargets: [
|
|
540
|
+
"localhost",
|
|
541
|
+
"https://api.internal.example.com",
|
|
542
|
+
/^https:\/\/microservice-[a-z]+\.internal\./,
|
|
543
|
+
// tracePropagationTargets: [] → disable outgoing propagation entirely
|
|
544
|
+
],
|
|
545
|
+
});
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Database auto-instrumentation
|
|
549
|
+
|
|
550
|
+
| Driver / ORM | Auto-enabled | Notes |
|
|
551
|
+
| -------------------- | ------------ | ---------------------------------------------------------------------------------- |
|
|
552
|
+
| PostgreSQL (`pg`) | ✅ | `postgresIntegration` |
|
|
553
|
+
| MySQL | ✅ | `mysqlIntegration` |
|
|
554
|
+
| MySQL2 | ✅ | `mysql2Integration` |
|
|
555
|
+
| MongoDB | ✅ | `mongoIntegration` |
|
|
556
|
+
| Mongoose | ✅ | `mongooseIntegration` |
|
|
557
|
+
| Prisma | ⚠️ Manual | `prismaIntegration` — add explicitly: `integrations: [Sentry.prismaIntegration()]` |
|
|
558
|
+
| SQL Server (Tedious) | ✅ | `tediousIntegration` |
|
|
559
|
+
| Knex | ❌ | Must add manually |
|
|
560
|
+
| TypeORM | ❌ | Use `opentelemetry-instrumentation-typeorm` community package |
|
|
561
|
+
| Sequelize | ❌ | No known integration |
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
// Knex — must add explicitly:
|
|
565
|
+
import { knexIntegration } from "@sentry/node";
|
|
566
|
+
Sentry.init({ dsn: "YOUR_DSN", integrations: [knexIntegration()] });
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Redis auto-instrumentation
|
|
570
|
+
|
|
571
|
+
`redisIntegration` is auto-enabled — traces all `ioredis` and `node-redis` commands:
|
|
572
|
+
|
|
573
|
+
```
|
|
574
|
+
name: "SET user:123" op: "db.redis"
|
|
575
|
+
name: "GET session:abc" op: "db.redis"
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
No configuration needed.
|
|
579
|
+
|
|
580
|
+
### Using OTel APIs directly
|
|
581
|
+
|
|
582
|
+
Since Sentry is the OTel provider, OTel spans automatically appear in Sentry:
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
import { trace, SpanStatusCode } from "@opentelemetry/api";
|
|
586
|
+
|
|
587
|
+
const tracer = trace.getTracer("my-service", "1.0.0");
|
|
588
|
+
|
|
589
|
+
tracer.startActiveSpan("process-event", (span) => {
|
|
590
|
+
try {
|
|
591
|
+
processEvent();
|
|
592
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
593
|
+
} catch (e) {
|
|
594
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
595
|
+
throw e;
|
|
596
|
+
} finally {
|
|
597
|
+
span.end();
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
// → Appears in Sentry automatically, no extra config
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
Third-party OTel instrumentations also work without any Sentry-specific setup:
|
|
604
|
+
|
|
605
|
+
```typescript
|
|
606
|
+
// e.g., community TypeORM OTel instrumentation
|
|
607
|
+
import "opentelemetry-instrumentation-typeorm";
|
|
608
|
+
// → TypeORM query spans appear in Sentry automatically
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### Disable or customize integrations
|
|
612
|
+
|
|
613
|
+
```typescript
|
|
614
|
+
Sentry.init({
|
|
615
|
+
// Disable a specific integration:
|
|
616
|
+
integrations: (defaults) => defaults.filter((i) => i.name !== "Kafka"),
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
// Override integration config:
|
|
620
|
+
Sentry.init({
|
|
621
|
+
integrations: [Sentry.breadcrumbsIntegration({ console: false })],
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
// Add non-default integration:
|
|
625
|
+
Sentry.addIntegration(Sentry.captureConsoleIntegration());
|
|
626
|
+
|
|
627
|
+
// Disable all defaults (uncommon):
|
|
628
|
+
Sentry.init({ defaultIntegrations: false });
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
### Profiling with `@sentry/profiling-node`
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
# Version must exactly match @sentry/nestjs
|
|
635
|
+
npm install @sentry/profiling-node
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
```typescript
|
|
639
|
+
// instrument.ts
|
|
640
|
+
import * as Sentry from "@sentry/nestjs";
|
|
641
|
+
const { nodeProfilingIntegration } = require("@sentry/profiling-node");
|
|
642
|
+
|
|
643
|
+
Sentry.init({
|
|
644
|
+
dsn: "YOUR_DSN",
|
|
645
|
+
integrations: [nodeProfilingIntegration()],
|
|
646
|
+
tracesSampleRate: 1.0,
|
|
647
|
+
profileSessionSampleRate: 1.0, // profile 100% of process sessions
|
|
648
|
+
profileLifecycle: "trace", // auto start/stop with spans (recommended)
|
|
649
|
+
});
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
| `profileLifecycle` | Start | Stop | Use case |
|
|
653
|
+
| ------------------- | --------------------------------- | -------------------------------- | ------------------------------- |
|
|
654
|
+
| `"trace"` (default) | First active span | Last span ends | General profiling — zero config |
|
|
655
|
+
| `"manual"` | `Sentry.profiler.startProfiler()` | `Sentry.profiler.stopProfiler()` | Targeted hot paths |
|
|
656
|
+
|
|
657
|
+
> **`profileSessionSampleRate` is process-level** — decided once at startup, not
|
|
658
|
+
> per-request. Use `0.1` to profile 10% of pods in a fleet without overhead on the rest.
|
|
659
|
+
|
|
660
|
+
## Auto-Instrumented Integrations
|
|
661
|
+
|
|
662
|
+
### Framework & HTTP (all auto-enabled)
|
|
663
|
+
|
|
664
|
+
| Integration | What is traced |
|
|
665
|
+
| ---------------------------- | --------------------------------------------------------------------- |
|
|
666
|
+
| `nestIntegration` | Middleware, guards, pipes, interceptors, filters, `@OnEvent` handlers |
|
|
667
|
+
| `httpIntegration` | Incoming HTTP requests + outgoing `http`/`https` calls |
|
|
668
|
+
| `nativeNodeFetchIntegration` | Outgoing `fetch()` calls |
|
|
669
|
+
| `requestDataIntegration` | HTTP request data attached to error events |
|
|
670
|
+
|
|
671
|
+
### Databases (all auto-enabled)
|
|
672
|
+
|
|
673
|
+
`mongoIntegration`, `mongooseIntegration`, `mysqlIntegration`, `mysql2Integration`,
|
|
674
|
+
`postgresIntegration`, `tediousIntegration`
|
|
675
|
+
|
|
676
|
+
### Cache & Queues (all auto-enabled)
|
|
677
|
+
|
|
678
|
+
`redisIntegration` (ioredis + node-redis), `amqplibIntegration` (AMQP/RabbitMQ),
|
|
679
|
+
`kafkaIntegration` (KafkaJS)
|
|
680
|
+
|
|
681
|
+
### AI / LLM (all auto-enabled)
|
|
682
|
+
|
|
683
|
+
`openAIIntegration`, `anthropicAIIntegration`, `googleGenAIIntegration`,
|
|
684
|
+
`langChainIntegration`, `vercelAiIntegration`
|
|
685
|
+
|
|
686
|
+
### Must be added manually
|
|
687
|
+
|
|
688
|
+
`knexIntegration`, `dataloaderIntegration`, `supabaseIntegration`,
|
|
689
|
+
`captureConsoleIntegration`
|
|
690
|
+
|
|
691
|
+
## What Is and Isn’t Auto-Traced
|
|
692
|
+
|
|
693
|
+
### Auto-traced (no code changes needed)
|
|
694
|
+
|
|
695
|
+
| Feature | Mechanism |
|
|
696
|
+
| -------------------------------------------------- | ------------------------------------------------------------ |
|
|
697
|
+
| HTTP requests + transaction naming | `nestIntegration` + `SentryTracingInterceptor` |
|
|
698
|
+
| Middleware, guard, pipe, interceptor, filter spans | `SentryNestInstrumentation` (patches `@Injectable`/`@Catch`) |
|
|
699
|
+
| `@OnEvent` handler spans | `SentryNestEventInstrumentation` (patches `@OnEvent`) |
|
|
700
|
+
| GraphQL queries/mutations/resolvers | `graphqlIntegration` |
|
|
701
|
+
| AMQP/RabbitMQ + Kafka messages | `amqplibIntegration` + `kafkaIntegration` |
|
|
702
|
+
| Redis, MongoDB, Mongoose, MySQL, PG | Auto-integrations |
|
|
703
|
+
| Outgoing HTTP (axios, fetch, http) | `httpIntegration` + `nativeNodeFetchIntegration` |
|
|
704
|
+
| Any OTel instrumentation | Auto-forwarded via OTel bridge |
|
|
705
|
+
|
|
706
|
+
### Requires manual instrumentation
|
|
707
|
+
|
|
708
|
+
| Feature | API |
|
|
709
|
+
| ------------------------------ | -------------------------------------------------------------------- |
|
|
710
|
+
| Custom business logic spans | `Sentry.startSpan()`, `startSpanManual()`, `startInactiveSpan()` |
|
|
711
|
+
| Method-level tracing | `@SentryTraced()` decorator |
|
|
712
|
+
| Cron job monitoring | `@SentryCron()` decorator |
|
|
713
|
+
| Exception filter error capture | `@SentryExceptionCaptured()` decorator |
|
|
714
|
+
| WebSocket gateway tracing | `continueTrace()` + `startSpan()` in message handler |
|
|
715
|
+
| TCP/NATS/gRPC microservices | Manual `startSpan()` + `continueTrace()` |
|
|
716
|
+
| Bull/BullMQ job tracing | `withIsolationScope()` + `startSpan()` in `process()` / `@Process()` |
|
|
717
|
+
| Non-HTTP distributed tracing | `getTraceData()` + `continueTrace()` |
|
|
718
|
+
| TypeORM / Sequelize tracing | Community OTel packages or manual spans |
|
|
719
|
+
| Node.js profiling | `@sentry/profiling-node` + `nodeProfilingIntegration()` |
|
|
720
|
+
|
|
721
|
+
## Best Practices
|
|
722
|
+
|
|
723
|
+
- Always import `instrument.ts` as the **very first import** in `main.ts` — before
|
|
724
|
+
`@nestjs/core` or any app module
|
|
725
|
+
- Use `tracesSampler` instead of `tracesSampleRate` in production — drop health checks,
|
|
726
|
+
adjust per-route, honour distributed decisions
|
|
727
|
+
- Set `tracePropagationTargets` to avoid leaking `sentry-trace` headers to third-party
|
|
728
|
+
services
|
|
729
|
+
- Prefer `startSpan()` (auto-ends) over `startSpanManual()` — forgetting `span.end()`
|
|
730
|
+
silently drops the span
|
|
731
|
+
- Add `sentry-trace` and `baggage` to your CORS allowlist when tracing
|
|
732
|
+
browser-to-backend flows
|
|
733
|
+
- Pin `@sentry/profiling-node` to the **exact same version** as `@sentry/nestjs`
|
|
734
|
+
- Use `profileSessionSampleRate` to profile a fraction of pods rather than every pod —
|
|
735
|
+
the decision is per-process, not per-request
|
|
736
|
+
- Always wrap background job handlers (`@Process()`, `WorkerHost.process()`, `@Cron()`,
|
|
737
|
+
`@OnEvent()`) with `withIsolationScope()` before `startSpan()` — without isolation,
|
|
738
|
+
concurrent jobs share scope state
|
|
739
|
+
- If the project uses a DI wrapper for Sentry (e.g. `SENTRY_PROXY_TOKEN`), use the
|
|
740
|
+
injected service for `startSpan`, `captureException`, etc.
|
|
741
|
+
— only `instrument.ts` should import `@sentry/nestjs` directly
|
|
742
|
+
- When using a config class for `Sentry.init()`, add new SDK options to the config type
|
|
743
|
+
rather than hardcoding them — this keeps options configurable per environment
|
|
744
|
+
|
|
745
|
+
## Troubleshooting
|
|
746
|
+
|
|
747
|
+
| Issue | Solution |
|
|
748
|
+
| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
749
|
+
| No transactions appearing | Verify `tracesSampleRate > 0` or `tracesSampler` returns non-zero |
|
|
750
|
+
| Transaction names show raw URL (e.g., `/users/123`) instead of pattern | `SentryModule.forRoot()` not imported; or `instrument.ts` loaded after `@nestjs/core` |
|
|
751
|
+
| Middleware/guard/pipe spans missing | `nestIntegration` not registered; ensure `instrument.ts` is first import |
|
|
752
|
+
| `@OnEvent` spans not appearing | `@nestjs/event-emitter` < 2.0.0; or `instrument.ts` loaded after event emitter |
|
|
753
|
+
| Distributed traces broken across services | Check `sentry-trace` and `baggage` headers pass through proxies/API gateways |
|
|
754
|
+
| DB spans missing | Driver loaded before `instrument.ts`; reorder imports |
|
|
755
|
+
| Profiler crashes at startup | `@sentry/profiling-node` version doesn’t match `@sentry/nestjs` |
|
|
756
|
+
| Event spans appear as isolated transactions | Expected — `@OnEvent` uses `forceTransaction: true` by design |
|
|
757
|
+
| RPC exceptions not captured or app crashes | Use a dedicated `@Catch(RpcException)` filter; `SentryGlobalFilter` logs a warning for RPC |
|
|
758
|
+
| OTel instrumentation spans not appearing | Ensure the OTel package is loaded after `instrument.ts` |
|
|
759
|
+
| BullMQ jobs share tags/user/breadcrumbs | Wrap `process()` body with `Sentry.withIsolationScope(() => ...)` |
|
|
760
|
+
| `profilesSampleRate` not working | Deprecated in SDK 10.x — use `profileSessionSampleRate` + `profileLifecycle: "trace"` |
|
|
761
|
+
| `SentryModule.forRoot()` registered twice | Only register once — if a shared library module already imports it, skip in `AppModule` |
|
|
762
|
+
| `import * as Sentry` blocked by ESLint | Use named imports or the project’s DI proxy; namespace imports trigger `no-restricted-syntax` rules |
|