@danieljvdm/dev-kit 1.0.2 → 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 +2 -33
- package/skill-sources.lock.json +15 -117
- 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 +10 -70
- 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,878 @@
|
|
|
1
|
+
# Tracing — Sentry Node.js SDK
|
|
2
|
+
|
|
3
|
+
> Minimum SDK: `@sentry/node` ≥8.0.0 (Node.js, Bun)\
|
|
4
|
+
> `@sentry/deno` for Deno runtime\
|
|
5
|
+
> `ignoreSpans`: ≥8.x\
|
|
6
|
+
> `inheritOrSampleWith`: ≥9.x
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## How Tracing Works in v8+
|
|
11
|
+
|
|
12
|
+
`@sentry/node` v8 is **built on OpenTelemetry natively**. When you call `Sentry.init()`,
|
|
13
|
+
it registers:
|
|
14
|
+
|
|
15
|
+
- **`SentrySpanProcessor`** — captures OTel spans and sends them to Sentry
|
|
16
|
+
- **`SentryPropagator`** — injects/extracts `sentry-trace` and `baggage` headers
|
|
17
|
+
- **`SentrySampler`** — applies `tracesSampleRate` / `tracesSampler` decisions
|
|
18
|
+
- **`SentryContextManager`** — manages active span context via AsyncLocalStorage
|
|
19
|
+
|
|
20
|
+
This means **any OTel-compatible library** (custom or third-party) automatically
|
|
21
|
+
produces spans visible in Sentry — no Sentry-specific code needed in those libraries.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Activating Tracing
|
|
26
|
+
|
|
27
|
+
Set **either** `tracesSampleRate` **or** `tracesSampler` in `Sentry.init()`. Without one
|
|
28
|
+
of these, no spans are created.
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// instrument.ts (must run before your app)
|
|
32
|
+
import * as Sentry from "@sentry/node";
|
|
33
|
+
|
|
34
|
+
Sentry.init({
|
|
35
|
+
dsn: process.env.SENTRY_DSN,
|
|
36
|
+
tracesSampleRate: 1.0, // 100% in development, lower in production
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
> **To disable tracing entirely:** omit both `tracesSampleRate` and `tracesSampler`.
|
|
41
|
+
> Setting `tracesSampleRate: 0` activates the OTel machinery but drops all traces — not
|
|
42
|
+
> the same as disabled.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## `tracesSampleRate` — Uniform Sampling
|
|
47
|
+
|
|
48
|
+
A number between `0.0` and `1.0`:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
Sentry.init({
|
|
52
|
+
tracesSampleRate: process.env.NODE_ENV === "development" ? 1.0 : 0.1,
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| Value | Effect |
|
|
57
|
+
| ------- | ----------------------------------- |
|
|
58
|
+
| `1.0` | Capture 100% of traces |
|
|
59
|
+
| `0.1` | Capture 10% of traces |
|
|
60
|
+
| `0.0` | Initialize tracing but send nothing |
|
|
61
|
+
| omitted | Tracing disabled entirely |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## `tracesSampler` — Dynamic Per-Request Sampling
|
|
66
|
+
|
|
67
|
+
When defined, `tracesSampler` **takes precedence** over `tracesSampleRate`. Receives a
|
|
68
|
+
`SamplingContext` and returns a number `0`–`1` (or boolean).
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// TypeScript: SamplingContext shape
|
|
72
|
+
interface SamplingContext {
|
|
73
|
+
name: string; // e.g. "GET /api/users"
|
|
74
|
+
attributes: SpanAttributes | undefined;
|
|
75
|
+
parentSampled: boolean | undefined; // parent's sampling decision
|
|
76
|
+
parentSampleRate: number | undefined;
|
|
77
|
+
inheritOrSampleWith: (fallbackRate: number) => number; // ≥9.x
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Route-Based Sampling
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
Sentry.init({
|
|
85
|
+
tracesSampler: ({ name, inheritOrSampleWith }) => {
|
|
86
|
+
// Always drop health checks
|
|
87
|
+
if (name.includes("/health") || name.includes("/ping")) return 0;
|
|
88
|
+
|
|
89
|
+
// Always sample critical flows
|
|
90
|
+
if (name.includes("/checkout") || name.includes("/payment")) return 1.0;
|
|
91
|
+
|
|
92
|
+
// Honor parent's decision, fall back to 10%
|
|
93
|
+
return inheritOrSampleWith(0.1);
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `inheritOrSampleWith()` (≥9.x)
|
|
99
|
+
|
|
100
|
+
Respects the upstream trace’s sampling decision.
|
|
101
|
+
If no parent decision exists, applies your fallback rate.
|
|
102
|
+
Always prefer this over checking `parentSampled` directly — it propagates rates
|
|
103
|
+
accurately through distributed traces and sets the correct `sentry-sampled` value in
|
|
104
|
+
`baggage`.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// Without inheritOrSampleWith (manual check)
|
|
108
|
+
tracesSampler: ({ parentSampled }) => {
|
|
109
|
+
if (parentSampled !== undefined) return parentSampled ? 1 : 0;
|
|
110
|
+
return 0.1;
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
// With inheritOrSampleWith (cleaner, accurate metric extrapolation)
|
|
114
|
+
tracesSampler: ({ inheritOrSampleWith }) => inheritOrSampleWith(0.1),
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Sampling Precedence
|
|
118
|
+
|
|
119
|
+
1. `tracesSampler` function (if defined) — evaluated first
|
|
120
|
+
2. Parent’s sampling decision (propagated via `sentry-trace` header)
|
|
121
|
+
3. `tracesSampleRate` (uniform fallback)
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Auto-Instrumented Libraries
|
|
126
|
+
|
|
127
|
+
`@sentry/node` v8 ships with **28+ auto-instrumented packages** via bundled OTel
|
|
128
|
+
instrumentations. No additional configuration needed — they activate automatically on
|
|
129
|
+
`Sentry.init()`.
|
|
130
|
+
|
|
131
|
+
### HTTP & Web
|
|
132
|
+
|
|
133
|
+
| Library | `op` | What’s captured |
|
|
134
|
+
| ------------------------------------- | ------------- | ----------------------------------------------------------------------- |
|
|
135
|
+
| `node:http` / `node:https` (incoming) | `http.server` | Method, URL, status code, duration |
|
|
136
|
+
| `node:http` / `node:https` (outgoing) | `http.client` | Method, URL, status code, duration |
|
|
137
|
+
| `fetch` / `undici` | `http.client` | Method, URL, status code (headers opt-in via `headersToSpanAttributes`) |
|
|
138
|
+
| `axios` | `http.client` | Method, URL, status code |
|
|
139
|
+
|
|
140
|
+
#### Capturing HTTP Headers on Fetch Spans
|
|
141
|
+
|
|
142
|
+
Since `@opentelemetry/instrumentation-undici@0.22.0`, response headers like
|
|
143
|
+
`content-length` are **no longer captured automatically** on outgoing `fetch`/`undici`
|
|
144
|
+
spans. To restore header capture or add custom headers, use `headersToSpanAttributes` on
|
|
145
|
+
`nativeNodeFetchIntegration()`:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import * as Sentry from "@sentry/node";
|
|
149
|
+
|
|
150
|
+
Sentry.init({
|
|
151
|
+
dsn: process.env.SENTRY_DSN,
|
|
152
|
+
tracesSampleRate: 1.0,
|
|
153
|
+
integrations: [
|
|
154
|
+
Sentry.nativeNodeFetchIntegration({
|
|
155
|
+
headersToSpanAttributes: {
|
|
156
|
+
requestHeaders: ["x-request-id", "x-custom-header"],
|
|
157
|
+
responseHeaders: ["content-length", "content-type"],
|
|
158
|
+
},
|
|
159
|
+
}),
|
|
160
|
+
],
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Matched headers appear as span attributes: `http.request.header.<name>` and
|
|
165
|
+
`http.response.header.<name>`.
|
|
166
|
+
|
|
167
|
+
| Option | Type | Default | Description |
|
|
168
|
+
| ----------------------------------------- | ---------- | ----------- | --------------------------------------------------- |
|
|
169
|
+
| `headersToSpanAttributes.requestHeaders` | `string[]` | `undefined` | Request header names to capture as span attributes |
|
|
170
|
+
| `headersToSpanAttributes.responseHeaders` | `string[]` | `undefined` | Response header names to capture as span attributes |
|
|
171
|
+
|
|
172
|
+
### Databases
|
|
173
|
+
|
|
174
|
+
| Library | `op` | What’s captured |
|
|
175
|
+
| ----------------- | ---------- | -------------------------- |
|
|
176
|
+
| `pg` (PostgreSQL) | `db.query` | SQL query text, duration |
|
|
177
|
+
| `mysql2` | `db.query` | SQL query text, duration |
|
|
178
|
+
| `mysql` | `db.query` | SQL query text, duration |
|
|
179
|
+
| `mongodb` | `db` | Collection, operation name |
|
|
180
|
+
| `redis` | `db.redis` | Command, key |
|
|
181
|
+
| `ioredis` | `db.redis` | Command, key |
|
|
182
|
+
| `prisma` (v5+) | `db.query` | SQL query, model |
|
|
183
|
+
| `sequelize` | `db.query` | SQL query text |
|
|
184
|
+
| `typeorm` | `db.query` | SQL query text |
|
|
185
|
+
| `knex` | `db.query` | SQL query text |
|
|
186
|
+
|
|
187
|
+
### Message Queues & Async
|
|
188
|
+
|
|
189
|
+
| Library | `op` | What’s captured |
|
|
190
|
+
| ---------------------- | --------------------------------- | --------------------- |
|
|
191
|
+
| `kafkajs` | `queue.publish` / `queue.process` | Topic, partition |
|
|
192
|
+
| `amqplib` | `queue.publish` / `queue.process` | Exchange, routing key |
|
|
193
|
+
| `@google-cloud/pubsub` | `queue.publish` / `queue.process` | Topic, subscription |
|
|
194
|
+
| `@aws-sdk/*` (SNS/SQS) | `queue.publish` / `queue.process` | Queue URL, message ID |
|
|
195
|
+
| `bull` | `queue.process` | Job name, queue name |
|
|
196
|
+
| `bullmq` | `queue.process` | Job name, queue name |
|
|
197
|
+
|
|
198
|
+
### GraphQL & RPC
|
|
199
|
+
|
|
200
|
+
| Library | `op` | What’s captured |
|
|
201
|
+
| --------------------------- | ----------------- | -------------------------- |
|
|
202
|
+
| `graphql` / `apollo-server` | `graphql.resolve` | Operation name, field path |
|
|
203
|
+
|
|
204
|
+
### AI/LLM
|
|
205
|
+
|
|
206
|
+
| Library | `op` | What’s captured |
|
|
207
|
+
| ----------------------- | --------------- | -------------------------------- |
|
|
208
|
+
| `@openai/sdk` | `ai.pipeline.*` | Model, tokens, prompt/completion |
|
|
209
|
+
| `@anthropic-ai/sdk` | `ai.pipeline.*` | Model, tokens |
|
|
210
|
+
| `langchain` | `ai.pipeline.*` | Chain, retriever, LLM operation |
|
|
211
|
+
| `ai` (Vercel AI SDK) | `ai.pipeline.*` | Model, tokens |
|
|
212
|
+
| `@google/generative-ai` | `ai.pipeline.*` | Model name |
|
|
213
|
+
|
|
214
|
+
> **Note:** AI library instrumentation may require `Sentry.init()` with
|
|
215
|
+
> `skipOpenTelemetrySetup: false` (the default).
|
|
216
|
+
> See the AI Monitoring reference for full configuration.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Custom Spans
|
|
221
|
+
|
|
222
|
+
### `Sentry.startSpan()` — Active, Auto-Ending (Recommended)
|
|
223
|
+
|
|
224
|
+
Creates an active span (children nest under it automatically) that ends when the
|
|
225
|
+
callback returns or resolves:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Async
|
|
229
|
+
const data = await Sentry.startSpan(
|
|
230
|
+
{
|
|
231
|
+
name: "fetchUserProfile",
|
|
232
|
+
op: "http.client",
|
|
233
|
+
attributes: { "user.id": userId, "cache.hit": false },
|
|
234
|
+
},
|
|
235
|
+
async () => {
|
|
236
|
+
const res = await fetch(`/api/users/${userId}`);
|
|
237
|
+
return res.json();
|
|
238
|
+
},
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
// Sync
|
|
242
|
+
const result = Sentry.startSpan({ name: "computeScore", op: "function" }, () =>
|
|
243
|
+
expensiveComputation(),
|
|
244
|
+
);
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Nested Spans (Parent–Child Hierarchy)
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
await Sentry.startSpan({ name: "checkout-flow", op: "function" }, async () => {
|
|
251
|
+
// Automatically children of "checkout-flow"
|
|
252
|
+
const cart = await Sentry.startSpan({ name: "fetchCart", op: "db.query" }, () =>
|
|
253
|
+
db.cart.findUnique({ where: { userId } }),
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
const payment = await Sentry.startSpan({ name: "processPayment", op: "http.client" }, () =>
|
|
257
|
+
stripe.paymentIntents.create({ amount: cart.total }),
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
return { cart, payment };
|
|
261
|
+
});
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### `Sentry.startSpanManual()` — Active, Manual End
|
|
265
|
+
|
|
266
|
+
Use when the span lifetime cannot be enclosed in a callback (e.g., middleware with async
|
|
267
|
+
continuations):
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
function authMiddleware(req: Request, res: Response, next: NextFunction) {
|
|
271
|
+
return Sentry.startSpanManual({ name: "auth.verify", op: "middleware" }, (span) => {
|
|
272
|
+
res.once("finish", () => {
|
|
273
|
+
span.setStatus({ code: res.statusCode < 400 ? 1 : 2 });
|
|
274
|
+
span.end(); // ← required; leaks if omitted
|
|
275
|
+
});
|
|
276
|
+
return next();
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### `Sentry.startInactiveSpan()` — Not Active, Manual End
|
|
282
|
+
|
|
283
|
+
Creates a span that is **never** automatically made active.
|
|
284
|
+
Use for parallel work or spans that don’t fit the call stack:
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
// Parallel independent operations
|
|
288
|
+
const spanA = Sentry.startInactiveSpan({ name: "operation-a" });
|
|
289
|
+
const spanB = Sentry.startInactiveSpan({ name: "operation-b" });
|
|
290
|
+
|
|
291
|
+
await Promise.all([doA(), doB()]);
|
|
292
|
+
|
|
293
|
+
spanA.end();
|
|
294
|
+
spanB.end();
|
|
295
|
+
|
|
296
|
+
// Explicit parent assignment
|
|
297
|
+
const parent = Sentry.startInactiveSpan({ name: "parent" });
|
|
298
|
+
const child = Sentry.startInactiveSpan({ name: "child", parentSpan: parent });
|
|
299
|
+
child.end();
|
|
300
|
+
parent.end();
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### `Sentry.withActiveSpan()` — Temporarily Activate a Span
|
|
304
|
+
|
|
305
|
+
Makes an inactive span active for the duration of a callback.
|
|
306
|
+
Does **not** end the span:
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
const backgroundSpan = Sentry.startInactiveSpan({ name: "background-task", op: "task" });
|
|
310
|
+
|
|
311
|
+
await Sentry.withActiveSpan(backgroundSpan, async () => {
|
|
312
|
+
// Any nested startSpan() calls are children of backgroundSpan
|
|
313
|
+
await sendEmails();
|
|
314
|
+
await db.save(results);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
backgroundSpan.end();
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Span Options Reference
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
interface StartSpanOptions {
|
|
326
|
+
name: string; // Required: label shown in the UI
|
|
327
|
+
op?: string; // Operation category (see table below)
|
|
328
|
+
attributes?: Record<string, string | number | boolean>;
|
|
329
|
+
parentSpan?: Span; // Override automatic parent
|
|
330
|
+
onlyIfParent?: boolean; // Skip span if no active parent exists
|
|
331
|
+
forceTransaction?: boolean; // Force display as root transaction in UI
|
|
332
|
+
startTime?: number; // Unix timestamp in seconds
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Common `op` values:**
|
|
337
|
+
|
|
338
|
+
| `op` | Use for |
|
|
339
|
+
| ------------------------- | ----------------------------- |
|
|
340
|
+
| `http.client` | Outgoing HTTP requests |
|
|
341
|
+
| `http.server` | Incoming HTTP requests |
|
|
342
|
+
| `db` / `db.query` | Database queries |
|
|
343
|
+
| `db.redis` | Redis operations |
|
|
344
|
+
| `function` | General function calls |
|
|
345
|
+
| `queue.publish` | Publishing to message queues |
|
|
346
|
+
| `queue.process` | Consuming from message queues |
|
|
347
|
+
| `cache.get` / `cache.put` | Cache reads/writes |
|
|
348
|
+
| `task` | Background / scheduled work |
|
|
349
|
+
| `ai.pipeline.*` | AI/LLM inference calls |
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Span Enrichment
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
// Set attributes on the currently active span
|
|
357
|
+
const span = Sentry.getActiveSpan();
|
|
358
|
+
if (span) {
|
|
359
|
+
span.setAttribute("db.table", "users");
|
|
360
|
+
span.setAttributes({
|
|
361
|
+
"http.method": "POST",
|
|
362
|
+
"order.total": 99.99,
|
|
363
|
+
"user.tier": "premium",
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Status: 0=unset, 1=ok, 2=error
|
|
367
|
+
span.setStatus({ code: 1 });
|
|
368
|
+
span.setStatus({ code: 2, message: "Payment declined" });
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Record an exception on the active span
|
|
372
|
+
const span = Sentry.getActiveSpan();
|
|
373
|
+
if (span) span.recordException(error);
|
|
374
|
+
|
|
375
|
+
// Rename a span at runtime
|
|
376
|
+
Sentry.updateSpanName(span, "GET /users/:id");
|
|
377
|
+
|
|
378
|
+
// Modify all spans globally before sending
|
|
379
|
+
Sentry.init({
|
|
380
|
+
beforeSendSpan(span) {
|
|
381
|
+
// Add deployment metadata to every span
|
|
382
|
+
span.data = { ...span.data, "deployment.region": process.env.AWS_REGION };
|
|
383
|
+
return span; // return null to drop (prefer ignoreSpans for filtering)
|
|
384
|
+
},
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Advanced Span APIs
|
|
391
|
+
|
|
392
|
+
### `continueTrace()` — Continue an Incoming Trace
|
|
393
|
+
|
|
394
|
+
For message queues, cron triggers, and other non-HTTP channels that carry trace headers:
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
Sentry.continueTrace(
|
|
398
|
+
{
|
|
399
|
+
sentryTrace: message.headers["sentry-trace"],
|
|
400
|
+
baggage: message.headers["baggage"],
|
|
401
|
+
},
|
|
402
|
+
() => {
|
|
403
|
+
return Sentry.startSpan({ name: "processJob", op: "queue.process" }, () => doWork());
|
|
404
|
+
},
|
|
405
|
+
);
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
> HTTP servers handled by framework integrations (Express, Fastify, etc.)
|
|
409
|
+
> call `continueTrace()` automatically.
|
|
410
|
+
> You only need it for non-HTTP channels.
|
|
411
|
+
|
|
412
|
+
### `startNewTrace()` — Force a New Trace
|
|
413
|
+
|
|
414
|
+
Breaks the distributed chain — creates an independent trace with a new `traceId`:
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
Sentry.startNewTrace(() => {
|
|
418
|
+
return Sentry.startSpan({ name: "isolated-background-job" }, () => doWork());
|
|
419
|
+
});
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### `suppressTracing()` — Prevent Span Capture
|
|
423
|
+
|
|
424
|
+
Suppresses span creation inside the callback, even for auto-instrumented code:
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
// Health check polling — don't create spans
|
|
428
|
+
const result = await Sentry.suppressTracing(() => {
|
|
429
|
+
return fetch("/internal/health");
|
|
430
|
+
});
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### `getActiveSpan()`, `getRootSpan()`
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
const span = Sentry.getActiveSpan();
|
|
437
|
+
if (span) {
|
|
438
|
+
const root = Sentry.getRootSpan(span);
|
|
439
|
+
console.log(Sentry.spanToJSON(root).name);
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### `forceTransaction` and `onlyIfParent`
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
// Force span to appear as root transaction in Sentry UI
|
|
447
|
+
Sentry.startSpan({ name: "background-job", op: "function", forceTransaction: true }, () =>
|
|
448
|
+
runBackgroundJob(),
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
// Only create span when an active parent exists (drop orphan spans)
|
|
452
|
+
Sentry.startSpan({ name: "optional-metric", onlyIfParent: true }, () => measureSomething());
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## `ignoreSpans` — Filtering Spans
|
|
458
|
+
|
|
459
|
+
Drop specific spans before they are sent.
|
|
460
|
+
Accepts strings (substring match), RegExp, functions, or objects with an optional
|
|
461
|
+
`attributes` field for attribute-based matching:
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
Sentry.init({
|
|
465
|
+
ignoreSpans: [
|
|
466
|
+
// Drop health check spans (string substring match)
|
|
467
|
+
"health",
|
|
468
|
+
// Drop spans by name pattern (RegExp)
|
|
469
|
+
/health|heartbeat|ping/,
|
|
470
|
+
// Drop internal DB keepalive queries (function)
|
|
471
|
+
(span) => span.op === "db.query" && span.description?.includes("SELECT 1"),
|
|
472
|
+
// Drop spans matching specific attributes (object form, SDK ≥9.x)
|
|
473
|
+
{
|
|
474
|
+
name: /health/, // optional: name/op substring or RegExp
|
|
475
|
+
attributes: {
|
|
476
|
+
"http.url": "/health", // string = substring match
|
|
477
|
+
"http.status_code": 200, // non-string = strict equality
|
|
478
|
+
},
|
|
479
|
+
},
|
|
480
|
+
],
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
The `attributes` field on an object entry matches span attributes: string values use
|
|
485
|
+
substring/RegExp matching, non-string values (numbers, booleans, arrays) use strict
|
|
486
|
+
equality.
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
## Distributed Tracing
|
|
491
|
+
|
|
492
|
+
### How It Works
|
|
493
|
+
|
|
494
|
+
Sentry injects two headers into outgoing HTTP requests:
|
|
495
|
+
|
|
496
|
+
| Header | Format | Purpose |
|
|
497
|
+
| -------------- | -------------------------------- | ------------------------------------ |
|
|
498
|
+
| `sentry-trace` | `{traceId}-{spanId}-{sampled}` | Carries trace context |
|
|
499
|
+
| `baggage` | W3C Baggage with `sentry-*` keys | Carries sampling decision + metadata |
|
|
500
|
+
|
|
501
|
+
Backends must allowlist these for CORS:
|
|
502
|
+
|
|
503
|
+
```
|
|
504
|
+
Access-Control-Allow-Headers: sentry-trace, baggage
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### `tracePropagationTargets`
|
|
508
|
+
|
|
509
|
+
Controls which outgoing requests get trace headers.
|
|
510
|
+
Accepts strings (substring match) and/or RegExp:
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
Sentry.init({
|
|
514
|
+
tracePropagationTargets: [
|
|
515
|
+
"localhost", // any URL containing "localhost"
|
|
516
|
+
/^https:\/\/api\.yourapp\.com/, // your API
|
|
517
|
+
/^https:\/\/auth\.yourapp\.com/, // auth service
|
|
518
|
+
],
|
|
519
|
+
});
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
**Default:** `['localhost', /^\//]` — only localhost and relative paths.\
|
|
523
|
+
**Disable entirely:** `tracePropagationTargets: []`
|
|
524
|
+
|
|
525
|
+
> ⚠️ If your API is at `http://localhost:3001`, use `"localhost:3001"` or a regex
|
|
526
|
+
> matching the port — `"localhost"` alone won’t match.
|
|
527
|
+
|
|
528
|
+
### Manual Trace Propagation (Non-HTTP Channels)
|
|
529
|
+
|
|
530
|
+
For Kafka, AMQP, WebSockets, and other protocols:
|
|
531
|
+
|
|
532
|
+
```typescript
|
|
533
|
+
// Publisher — extract current trace context
|
|
534
|
+
import * as Sentry from "@sentry/node";
|
|
535
|
+
|
|
536
|
+
await Sentry.startSpan({ name: "Publish order event", op: "queue.publish" }, async () => {
|
|
537
|
+
const traceData = Sentry.getTraceData();
|
|
538
|
+
// Returns: { "sentry-trace": "...", "baggage": "..." }
|
|
539
|
+
|
|
540
|
+
await kafka.send({
|
|
541
|
+
topic: "orders",
|
|
542
|
+
messages: [
|
|
543
|
+
{
|
|
544
|
+
value: JSON.stringify({ orderId: 123 }),
|
|
545
|
+
headers: {
|
|
546
|
+
"sentry-trace": traceData["sentry-trace"],
|
|
547
|
+
baggage: traceData["baggage"],
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
],
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// Consumer — continue the trace
|
|
555
|
+
consumer.run({
|
|
556
|
+
eachMessage: async ({ message }) => {
|
|
557
|
+
Sentry.continueTrace(
|
|
558
|
+
{
|
|
559
|
+
sentryTrace: message.headers["sentry-trace"]?.toString(),
|
|
560
|
+
baggage: message.headers["baggage"]?.toString(),
|
|
561
|
+
},
|
|
562
|
+
() =>
|
|
563
|
+
Sentry.startSpan({ name: "Process order", op: "queue.process" }, () =>
|
|
564
|
+
processOrder(message),
|
|
565
|
+
),
|
|
566
|
+
);
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### Head-Based Sampling
|
|
572
|
+
|
|
573
|
+
The originating (head) service makes the sampling decision and propagates it via
|
|
574
|
+
`sentry-trace`. All downstream services either all sample or all drop — ensuring
|
|
575
|
+
complete traces, never partial ones.
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## Framework Auto-Instrumentation
|
|
580
|
+
|
|
581
|
+
Framework integrations are included in `@sentry/node` and activated automatically.
|
|
582
|
+
You don’t add them via `integrations: []` — they are registered when you call
|
|
583
|
+
`Sentry.init()` and `setupXxxErrorHandler()`.
|
|
584
|
+
|
|
585
|
+
### Express
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
import express from "express";
|
|
589
|
+
import * as Sentry from "@sentry/node";
|
|
590
|
+
|
|
591
|
+
// instrument.ts must load FIRST — before express is required
|
|
592
|
+
Sentry.init({ dsn: "...", tracesSampleRate: 1.0 });
|
|
593
|
+
|
|
594
|
+
const app = express();
|
|
595
|
+
|
|
596
|
+
app.get("/api/users/:id", async (req, res) => {
|
|
597
|
+
// DB queries are automatically child spans of this HTTP transaction
|
|
598
|
+
const user = await db.users.findUnique({ where: { id: req.params.id } });
|
|
599
|
+
res.json(user);
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
// Error handler AFTER all routes
|
|
603
|
+
Sentry.setupExpressErrorHandler(app);
|
|
604
|
+
app.listen(3000);
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Sentry automatically traces all incoming requests.
|
|
608
|
+
Each `GET /api/users/:id` becomes an `http.server` transaction with DB query spans as
|
|
609
|
+
children.
|
|
610
|
+
|
|
611
|
+
### Fastify
|
|
612
|
+
|
|
613
|
+
```typescript
|
|
614
|
+
import Fastify from "fastify";
|
|
615
|
+
import * as Sentry from "@sentry/node";
|
|
616
|
+
|
|
617
|
+
Sentry.init({ dsn: "...", tracesSampleRate: 1.0 });
|
|
618
|
+
|
|
619
|
+
const fastify = Fastify();
|
|
620
|
+
|
|
621
|
+
// Error handler BEFORE routes (Fastify-specific — not async, unlike Hapi)
|
|
622
|
+
Sentry.setupFastifyErrorHandler(fastify);
|
|
623
|
+
|
|
624
|
+
fastify.get("/api/data", async (request, reply) => {
|
|
625
|
+
return fetchData();
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
await fastify.listen({ port: 3000 });
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
### Koa
|
|
632
|
+
|
|
633
|
+
```typescript
|
|
634
|
+
import Koa from "koa";
|
|
635
|
+
import * as Sentry from "@sentry/node";
|
|
636
|
+
|
|
637
|
+
Sentry.init({ dsn: "...", tracesSampleRate: 1.0 });
|
|
638
|
+
|
|
639
|
+
const app = new Koa();
|
|
640
|
+
Sentry.setupKoaErrorHandler(app); // FIRST middleware
|
|
641
|
+
|
|
642
|
+
app.use(async (ctx) => {
|
|
643
|
+
ctx.body = await fetchData();
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
app.listen(3000);
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
### Hapi
|
|
650
|
+
|
|
651
|
+
```typescript
|
|
652
|
+
import Hapi from "@hapi/hapi";
|
|
653
|
+
import * as Sentry from "@sentry/node";
|
|
654
|
+
|
|
655
|
+
Sentry.init({ dsn: "...", tracesSampleRate: 1.0 });
|
|
656
|
+
|
|
657
|
+
const server = Hapi.server({ port: 3000 });
|
|
658
|
+
await Sentry.setupHapiErrorHandler(server); // must await
|
|
659
|
+
|
|
660
|
+
server.route({
|
|
661
|
+
method: "GET",
|
|
662
|
+
path: "/api/data",
|
|
663
|
+
handler: async (request) => fetchData(),
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
await server.start();
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### NestJS
|
|
670
|
+
|
|
671
|
+
> **NestJS has a dedicated skill: [[`nestjs`](../nestjs/index.md)](../nestjs/index.md)**
|
|
672
|
+
> It covers `SentryModule.forRoot()`, `@SentryTraced` decorator for custom spans,
|
|
673
|
+
> `SentryTracingInterceptor`, and GraphQL resolver tracing.
|
|
674
|
+
|
|
675
|
+
---
|
|
676
|
+
|
|
677
|
+
## Configuration Reference
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
Sentry.init({
|
|
681
|
+
dsn: process.env.SENTRY_DSN,
|
|
682
|
+
environment: process.env.NODE_ENV,
|
|
683
|
+
|
|
684
|
+
// Sampling
|
|
685
|
+
tracesSampleRate: 0.1,
|
|
686
|
+
// OR:
|
|
687
|
+
tracesSampler: ({ name, inheritOrSampleWith }) => {
|
|
688
|
+
if (name.includes("/health")) return 0;
|
|
689
|
+
if (name.includes("/checkout")) return 1.0;
|
|
690
|
+
return inheritOrSampleWith(0.1);
|
|
691
|
+
},
|
|
692
|
+
|
|
693
|
+
// Propagation — which outgoing requests get trace headers
|
|
694
|
+
tracePropagationTargets: ["localhost", /^https:\/\/api\.yourapp\.com/],
|
|
695
|
+
|
|
696
|
+
// Drop specific spans before sending
|
|
697
|
+
ignoreSpans: [
|
|
698
|
+
/health|ping/,
|
|
699
|
+
(span) => span.op === "db.query" && span.description?.includes("SELECT 1"),
|
|
700
|
+
],
|
|
701
|
+
|
|
702
|
+
// Modify all spans before sending (or return null to drop)
|
|
703
|
+
beforeSendSpan(span) {
|
|
704
|
+
if (span.op === "http.client" && span.data?.url?.includes("/internal")) {
|
|
705
|
+
return null; // drop internal health check spans
|
|
706
|
+
}
|
|
707
|
+
return span;
|
|
708
|
+
},
|
|
709
|
+
|
|
710
|
+
// Capture HTTP headers on outgoing fetch/undici spans
|
|
711
|
+
integrations: [
|
|
712
|
+
Sentry.nativeNodeFetchIntegration({
|
|
713
|
+
headersToSpanAttributes: {
|
|
714
|
+
requestHeaders: ["x-request-id"],
|
|
715
|
+
responseHeaders: ["content-length", "content-type"],
|
|
716
|
+
},
|
|
717
|
+
}),
|
|
718
|
+
],
|
|
719
|
+
});
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
**Environment variables:**
|
|
723
|
+
|
|
724
|
+
| Variable | Effect |
|
|
725
|
+
| --------------------------- | ----------------------- |
|
|
726
|
+
| `SENTRY_TRACES_SAMPLE_RATE` | Sets `tracesSampleRate` |
|
|
727
|
+
| `SENTRY_ENVIRONMENT` | Sets `environment` |
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
731
|
+
## Runtime Differences
|
|
732
|
+
|
|
733
|
+
### Node.js
|
|
734
|
+
|
|
735
|
+
Full tracing support via `@sentry/node`. All 28+ auto-instrumentations available.
|
|
736
|
+
Profiling available via `@sentry/profiling-node`.
|
|
737
|
+
|
|
738
|
+
```typescript
|
|
739
|
+
import * as Sentry from "@sentry/node";
|
|
740
|
+
|
|
741
|
+
Sentry.init({
|
|
742
|
+
dsn: "...",
|
|
743
|
+
tracesSampleRate: 1.0,
|
|
744
|
+
});
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
### Bun
|
|
748
|
+
|
|
749
|
+
`@sentry/bun` wraps `@sentry/node` — tracing is 99% identical to Node.js.
|
|
750
|
+
The same auto-instrumentation table applies.
|
|
751
|
+
Profiling is **not** available (native addon incompatible with Bun).
|
|
752
|
+
|
|
753
|
+
```typescript
|
|
754
|
+
// bun-instrument.ts — loaded via --preload
|
|
755
|
+
import * as Sentry from "@sentry/bun";
|
|
756
|
+
|
|
757
|
+
Sentry.init({
|
|
758
|
+
dsn: "...",
|
|
759
|
+
tracesSampleRate: 1.0,
|
|
760
|
+
});
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
bun --preload ./bun-instrument.ts run app.ts
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
`Bun.serve()` is automatically instrumented — each request becomes an `http.server`
|
|
768
|
+
transaction.
|
|
769
|
+
|
|
770
|
+
### Deno
|
|
771
|
+
|
|
772
|
+
`@sentry/deno` uses `npm:@sentry/deno`. Auto-instrumented libraries are limited — Deno
|
|
773
|
+
doesn’t load Node.js OTel instrumentations.
|
|
774
|
+
Custom spans work identically.
|
|
775
|
+
|
|
776
|
+
```typescript
|
|
777
|
+
import * as Sentry from "npm:@sentry/deno";
|
|
778
|
+
|
|
779
|
+
Sentry.init({
|
|
780
|
+
dsn: "...",
|
|
781
|
+
tracesSampleRate: 1.0,
|
|
782
|
+
});
|
|
783
|
+
|
|
784
|
+
// Deno.serve — wrap handlers manually (not auto-instrumented)
|
|
785
|
+
Deno.serve(async (req) => {
|
|
786
|
+
return Sentry.startSpan(
|
|
787
|
+
{ name: `${req.method} ${new URL(req.url).pathname}`, op: "http.server" },
|
|
788
|
+
async () => {
|
|
789
|
+
const data = await handleRequest(req);
|
|
790
|
+
return new Response(JSON.stringify(data));
|
|
791
|
+
},
|
|
792
|
+
);
|
|
793
|
+
});
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
**Runtime comparison:**
|
|
797
|
+
|
|
798
|
+
| Feature | Node.js | Bun | Deno |
|
|
799
|
+
| ---------------------------------- | -------------- | ----------- | -------------- |
|
|
800
|
+
| Tracing (OTel) | ✅ Full | ✅ Via Node | ✅ Custom OTel |
|
|
801
|
+
| HTTP auto-instrumentation | ✅ | ✅ | ⚠️ Manual |
|
|
802
|
+
| Database auto-instrumentation | ✅ 10+ drivers | ✅ | ❌ |
|
|
803
|
+
| Message queue auto-instrumentation | ✅ | ✅ | ❌ |
|
|
804
|
+
| Profiling | ✅ | ❌ | ❌ |
|
|
805
|
+
| Custom spans | ✅ | ✅ | ✅ |
|
|
806
|
+
| Distributed tracing | ✅ | ✅ | ✅ |
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
|
|
810
|
+
## Complete Example
|
|
811
|
+
|
|
812
|
+
```typescript
|
|
813
|
+
// instrument.ts — loaded first via --require or --import
|
|
814
|
+
import * as Sentry from "@sentry/node";
|
|
815
|
+
|
|
816
|
+
Sentry.init({
|
|
817
|
+
dsn: process.env.SENTRY_DSN,
|
|
818
|
+
environment: process.env.NODE_ENV,
|
|
819
|
+
|
|
820
|
+
tracesSampler: ({ name, inheritOrSampleWith }) => {
|
|
821
|
+
if (name.includes("/health") || name.includes("/ping")) return 0;
|
|
822
|
+
if (name.includes("/checkout") || name.includes("/payment")) return 1.0;
|
|
823
|
+
return inheritOrSampleWith(0.1);
|
|
824
|
+
},
|
|
825
|
+
|
|
826
|
+
tracePropagationTargets: [
|
|
827
|
+
"localhost",
|
|
828
|
+
/^https:\/\/api\.myapp\.com/,
|
|
829
|
+
/^https:\/\/auth\.myapp\.com/,
|
|
830
|
+
],
|
|
831
|
+
|
|
832
|
+
ignoreSpans: [/health|heartbeat/],
|
|
833
|
+
});
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
```typescript
|
|
837
|
+
// orders.service.ts
|
|
838
|
+
import * as Sentry from "@sentry/node";
|
|
839
|
+
|
|
840
|
+
export async function createOrder(userId: string, items: Item[]) {
|
|
841
|
+
return Sentry.startSpan({ name: "createOrder", op: "function" }, async () => {
|
|
842
|
+
// DB queries are automatically child spans
|
|
843
|
+
const user = await db.users.findUnique({ where: { id: userId } });
|
|
844
|
+
|
|
845
|
+
const total = await Sentry.startSpan({ name: "calculateTotal", op: "function" }, () =>
|
|
846
|
+
computeTotal(items),
|
|
847
|
+
);
|
|
848
|
+
|
|
849
|
+
// Enrich the active span
|
|
850
|
+
const span = Sentry.getActiveSpan();
|
|
851
|
+
if (span) {
|
|
852
|
+
span.setAttributes({ "order.total": total, "order.item_count": items.length });
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// Outgoing HTTP — automatically traced
|
|
856
|
+
const payment = await stripe.paymentIntents.create({ amount: total });
|
|
857
|
+
|
|
858
|
+
return db.orders.create({ data: { userId, items, total, paymentId: payment.id } });
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
---
|
|
864
|
+
|
|
865
|
+
## Troubleshooting
|
|
866
|
+
|
|
867
|
+
| Issue | Solution |
|
|
868
|
+
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
869
|
+
| No transactions in Performance dashboard | Verify `tracesSampleRate` or `tracesSampler` is set; `Sentry.init()` must run before any imports |
|
|
870
|
+
| Spans missing for DB queries | Confirm the driver is in the auto-instrumentation table above; `Sentry.init()` must run first |
|
|
871
|
+
| Distributed trace not linking services | Add the target URL to `tracePropagationTargets`; verify `Access-Control-Allow-Headers: sentry-trace, baggage` |
|
|
872
|
+
| `tracePropagationTargets` port not matching | `"localhost"` won’t match `localhost:3001` — use `"localhost:3001"` or a regex |
|
|
873
|
+
| `continueTrace()` not linking to parent | Confirm incoming headers are `"sentry-trace"` and `"baggage"` (not `traceparent`) |
|
|
874
|
+
| High transaction volume | Use `tracesSampler` to return `0` for health checks; lower default rate |
|
|
875
|
+
| `tracesSampler` not working | When both `tracesSampler` and `tracesSampleRate` are set, `tracesSampler` wins — expected |
|
|
876
|
+
| Spans show generic names (raw URLs) | Use `beforeSendSpan` or framework route parameterization to normalize names |
|
|
877
|
+
| Bun profiling not working | Profiling requires `@sentry/profiling-node` native addon — incompatible with Bun |
|
|
878
|
+
| Deno DB spans missing | Deno doesn’t load Node.js OTel instrumentations; use `startSpan()` manually |
|