@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,270 @@
|
|
|
1
|
+
# Crons — Sentry Go SDK
|
|
2
|
+
|
|
3
|
+
> Minimum SDK: `github.com/getsentry/sentry-go` v0.18.0+
|
|
4
|
+
|
|
5
|
+
Sentry Cron Monitoring detects two failure modes:
|
|
6
|
+
|
|
7
|
+
- **Missed jobs** — the job never ran (schedule was skipped)
|
|
8
|
+
- **Timed-out jobs** — the job started but ran too long
|
|
9
|
+
|
|
10
|
+
## Configuration
|
|
11
|
+
|
|
12
|
+
No extra `ClientOptions` are required beyond a valid DSN:
|
|
13
|
+
|
|
14
|
+
```go
|
|
15
|
+
sentry.Init(sentry.ClientOptions{
|
|
16
|
+
Dsn: os.Getenv("SENTRY_DSN"),
|
|
17
|
+
})
|
|
18
|
+
defer sentry.Flush(2 * time.Second)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
> Check-ins are async by default — always `defer sentry.Flush()` before program exit.
|
|
22
|
+
|
|
23
|
+
## Core Types
|
|
24
|
+
|
|
25
|
+
### `CheckIn`
|
|
26
|
+
|
|
27
|
+
```go
|
|
28
|
+
type CheckIn struct {
|
|
29
|
+
ID EventID // leave zero on start; use *id from start call on completion
|
|
30
|
+
MonitorSlug string // slug of the monitor in Sentry
|
|
31
|
+
Status CheckInStatus // in_progress | ok | error
|
|
32
|
+
Duration time.Duration // optional; set on final check-in
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### `CheckInStatus` constants
|
|
37
|
+
|
|
38
|
+
```go
|
|
39
|
+
sentry.CheckInStatusInProgress // "in_progress" — job started
|
|
40
|
+
sentry.CheckInStatusOK // "ok" — job completed successfully
|
|
41
|
+
sentry.CheckInStatusError // "error" — job failed
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### `MonitorConfig`
|
|
45
|
+
|
|
46
|
+
```go
|
|
47
|
+
type MonitorConfig struct {
|
|
48
|
+
Schedule MonitorSchedule // when the job should run
|
|
49
|
+
CheckInMargin int64 // minutes of grace period before "missed"
|
|
50
|
+
MaxRuntime int64 // minutes before in-progress job times out
|
|
51
|
+
Timezone string // tz database name, e.g. "America/New_York"
|
|
52
|
+
FailureIssueThreshold int64 // consecutive failures before creating an issue
|
|
53
|
+
RecoveryThreshold int64 // consecutive successes before auto-resolving
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Schedule constructors
|
|
58
|
+
|
|
59
|
+
```go
|
|
60
|
+
// Standard 5-field cron expression
|
|
61
|
+
sentry.CrontabSchedule("*/10 * * * *")
|
|
62
|
+
|
|
63
|
+
// Interval-based
|
|
64
|
+
sentry.IntervalSchedule(1, sentry.MonitorScheduleUnitHour)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`MonitorScheduleUnit` constants: `MonitorScheduleUnitMinute`, `MonitorScheduleUnitHour`,
|
|
68
|
+
`MonitorScheduleUnitDay`, `MonitorScheduleUnitWeek`, `MonitorScheduleUnitMonth`,
|
|
69
|
+
`MonitorScheduleUnitYear`.
|
|
70
|
+
|
|
71
|
+
> `IntervalSchedule` takes `int64`, not `int`.
|
|
72
|
+
|
|
73
|
+
## Code Examples
|
|
74
|
+
|
|
75
|
+
### Check-in pattern (recommended)
|
|
76
|
+
|
|
77
|
+
Sends both a start and a completion check-in.
|
|
78
|
+
Detects **missed** and **timed-out** jobs.
|
|
79
|
+
|
|
80
|
+
```go
|
|
81
|
+
func runHourlyReport() error {
|
|
82
|
+
monitorConfig := &sentry.MonitorConfig{
|
|
83
|
+
Schedule: sentry.CrontabSchedule("0 * * * *"),
|
|
84
|
+
MaxRuntime: 5, // alert if still running after 5 minutes
|
|
85
|
+
CheckInMargin: 2, // allow 2 minutes late before "missed"
|
|
86
|
+
FailureIssueThreshold: 2, // create issue after 2 consecutive failures
|
|
87
|
+
RecoveryThreshold: 1, // auto-resolve after 1 success
|
|
88
|
+
Timezone: "America/New_York",
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Send in_progress — pass MonitorConfig here (only needed on first call)
|
|
92
|
+
checkinID := sentry.CaptureCheckIn(
|
|
93
|
+
&sentry.CheckIn{
|
|
94
|
+
MonitorSlug: "hourly-report",
|
|
95
|
+
Status: sentry.CheckInStatusInProgress,
|
|
96
|
+
},
|
|
97
|
+
monitorConfig,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
err := generateReport()
|
|
101
|
+
|
|
102
|
+
// Send ok or error — dereference the *EventID returned by start
|
|
103
|
+
status := sentry.CheckInStatusOK
|
|
104
|
+
if err != nil {
|
|
105
|
+
status = sentry.CheckInStatusError
|
|
106
|
+
}
|
|
107
|
+
sentry.CaptureCheckIn(
|
|
108
|
+
&sentry.CheckIn{
|
|
109
|
+
ID: *checkinID, // dereference *EventID
|
|
110
|
+
MonitorSlug: "hourly-report",
|
|
111
|
+
Status: status,
|
|
112
|
+
},
|
|
113
|
+
nil, // no config needed on completion
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return err
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Heartbeat pattern
|
|
121
|
+
|
|
122
|
+
Sends only a completion check-in.
|
|
123
|
+
Detects **missed** jobs only (no timeout detection).
|
|
124
|
+
|
|
125
|
+
```go
|
|
126
|
+
func runDailyCleanup() {
|
|
127
|
+
start := time.Now()
|
|
128
|
+
|
|
129
|
+
cleanupOldRecords()
|
|
130
|
+
|
|
131
|
+
sentry.CaptureCheckIn(
|
|
132
|
+
&sentry.CheckIn{
|
|
133
|
+
MonitorSlug: "daily-cleanup",
|
|
134
|
+
Status: sentry.CheckInStatusOK,
|
|
135
|
+
Duration: time.Since(start),
|
|
136
|
+
},
|
|
137
|
+
&sentry.MonitorConfig{
|
|
138
|
+
Schedule: sentry.CrontabSchedule("0 0 * * *"), // midnight daily
|
|
139
|
+
},
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Error handling in jobs
|
|
145
|
+
|
|
146
|
+
```go
|
|
147
|
+
func runSyncJob(ctx context.Context) {
|
|
148
|
+
id := sentry.CaptureCheckIn(
|
|
149
|
+
&sentry.CheckIn{MonitorSlug: "data-sync", Status: sentry.CheckInStatusInProgress},
|
|
150
|
+
&sentry.MonitorConfig{
|
|
151
|
+
Schedule: sentry.IntervalSchedule(10, sentry.MonitorScheduleUnitMinute),
|
|
152
|
+
MaxRuntime: 2,
|
|
153
|
+
},
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
err := syncData(ctx)
|
|
157
|
+
if err != nil {
|
|
158
|
+
// Capture the error AND complete the check-in as error
|
|
159
|
+
sentry.CaptureException(err)
|
|
160
|
+
sentry.CaptureCheckIn(
|
|
161
|
+
&sentry.CheckIn{ID: *id, MonitorSlug: "data-sync", Status: sentry.CheckInStatusError},
|
|
162
|
+
nil,
|
|
163
|
+
)
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
sentry.CaptureCheckIn(
|
|
168
|
+
&sentry.CheckIn{ID: *id, MonitorSlug: "data-sync", Status: sentry.CheckInStatusOK},
|
|
169
|
+
nil,
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Integration with robfig/cron
|
|
175
|
+
|
|
176
|
+
The SDK provides no built-in cron library wrappers — wrap manually:
|
|
177
|
+
|
|
178
|
+
```go
|
|
179
|
+
import "github.com/robfig/cron/v3"
|
|
180
|
+
|
|
181
|
+
c := cron.New()
|
|
182
|
+
c.AddFunc("@every 1h", func() {
|
|
183
|
+
id := sentry.CaptureCheckIn(
|
|
184
|
+
&sentry.CheckIn{
|
|
185
|
+
MonitorSlug: "hourly-job",
|
|
186
|
+
Status: sentry.CheckInStatusInProgress,
|
|
187
|
+
},
|
|
188
|
+
&sentry.MonitorConfig{
|
|
189
|
+
Schedule: sentry.CrontabSchedule("0 * * * *"),
|
|
190
|
+
MaxRuntime: 5,
|
|
191
|
+
CheckInMargin: 2,
|
|
192
|
+
},
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
err := doWork()
|
|
196
|
+
|
|
197
|
+
status := sentry.CheckInStatusOK
|
|
198
|
+
if err != nil {
|
|
199
|
+
status = sentry.CheckInStatusError
|
|
200
|
+
}
|
|
201
|
+
sentry.CaptureCheckIn(
|
|
202
|
+
&sentry.CheckIn{ID: *id, MonitorSlug: "hourly-job", Status: status},
|
|
203
|
+
nil,
|
|
204
|
+
)
|
|
205
|
+
})
|
|
206
|
+
c.Start()
|
|
207
|
+
defer c.Stop()
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Linking errors to the monitor
|
|
211
|
+
|
|
212
|
+
```go
|
|
213
|
+
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
|
214
|
+
scope.SetContext("monitor", sentry.Context{"slug": "my-monitor-slug"})
|
|
215
|
+
})
|
|
216
|
+
// Errors captured in this scope will be linked to the monitor in Sentry
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## CaptureCheckIn API
|
|
220
|
+
|
|
221
|
+
```go
|
|
222
|
+
// Package-level (uses CurrentHub)
|
|
223
|
+
func CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *EventID
|
|
224
|
+
|
|
225
|
+
// Hub method
|
|
226
|
+
func (hub *Hub) CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *EventID
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Both return `*EventID`. Always dereference with `*id` when passing to the completion
|
|
230
|
+
call. Returns `nil` if no client is bound — guard with `if id != nil`.
|
|
231
|
+
|
|
232
|
+
## MonitorConfig Guidance
|
|
233
|
+
|
|
234
|
+
| Field | Recommended value | Notes |
|
|
235
|
+
| ----------------------- | ----------------------------------------- | ---------------------------------- |
|
|
236
|
+
| `Schedule` | Match your actual cron expression | Required |
|
|
237
|
+
| `CheckInMargin` | 1–5 min for fast jobs; 10–30 min for slow | Grace period before “missed” alert |
|
|
238
|
+
| `MaxRuntime` | 2–3× expected runtime | Triggers timeout alert |
|
|
239
|
+
| `Timezone` | e.g., `"America/New_York"` | Defaults to UTC if unset |
|
|
240
|
+
| `FailureIssueThreshold` | `2` | Avoid noise from one-off failures |
|
|
241
|
+
| `RecoveryThreshold` | `1` | Auto-resolve on first success |
|
|
242
|
+
|
|
243
|
+
Pass `MonitorConfig` on the **start** check-in only; pass `nil` on the completion call.
|
|
244
|
+
|
|
245
|
+
## Rate Limits
|
|
246
|
+
|
|
247
|
+
Sentry limits check-ins to **6 per minute per monitor + environment combination**. For
|
|
248
|
+
jobs running more frequently than every 10 seconds, consider sampling.
|
|
249
|
+
|
|
250
|
+
## Best Practices
|
|
251
|
+
|
|
252
|
+
- Always send both a start (`InProgress`) and a completion (`OK`/`Error`) check-in —
|
|
253
|
+
this enables timeout detection
|
|
254
|
+
- Use `defer sentry.Flush(2 * time.Second)` in `main()` — check-ins are queued async
|
|
255
|
+
- Set `MaxRuntime` to roughly 2–3× your expected job duration
|
|
256
|
+
- Set `FailureIssueThreshold: 2` to avoid noisy alerts from transient failures
|
|
257
|
+
- Create the monitor in the Sentry UI first, then use its slug — or let the SDK
|
|
258
|
+
auto-create it on first check-in
|
|
259
|
+
- Don’t reuse the same `MonitorSlug` for different jobs
|
|
260
|
+
|
|
261
|
+
## Troubleshooting
|
|
262
|
+
|
|
263
|
+
| Issue | Solution |
|
|
264
|
+
| ------------------------------------- | ---------------------------------------------------------------------------- |
|
|
265
|
+
| Check-ins not appearing | Check DSN; ensure `sentry.Flush()` is called; set `Debug: true` |
|
|
266
|
+
| Monitor shows “missed” unexpectedly | Increase `CheckInMargin`; ensure `InProgress` is sent before work starts |
|
|
267
|
+
| Monitor shows “timeout” | Increase `MaxRuntime`; check for job hangs |
|
|
268
|
+
| Nil pointer on `*checkinID` | `CaptureCheckIn` returns `nil` if no client — check `sentry.Init` was called |
|
|
269
|
+
| Duplicate issues for the same failure | Set `FailureIssueThreshold: 2` to batch consecutive failures |
|
|
270
|
+
| Check-ins rate limited | Reduce frequency; batch work; check Sentry plan limits |
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Error Monitoring — Sentry Go SDK
|
|
2
|
+
|
|
3
|
+
> Minimum SDK: `github.com/getsentry/sentry-go` v0.9.0+
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
Key `ClientOptions` fields for error monitoring:
|
|
8
|
+
|
|
9
|
+
| Option | Type | Default | Purpose |
|
|
10
|
+
| ------------------ | ------------------------------------------------ | ------- | ----------------------------------------------- |
|
|
11
|
+
| `Dsn` | `string` | `""` | SDK disabled if empty |
|
|
12
|
+
| `AttachStacktrace` | `bool` | `false` | Stack traces on `CaptureMessage` calls |
|
|
13
|
+
| `SendDefaultPII` | `bool` | `false` | Include IP, request headers |
|
|
14
|
+
| `SampleRate` | `float64` | `1.0` | Error event sample rate (0.0 treated as 1.0) |
|
|
15
|
+
| `MaxBreadcrumbs` | `int` | `100` | Max breadcrumbs per event (negative = disabled) |
|
|
16
|
+
| `MaxErrorDepth` | `int` | `100` | Max depth for unwrapping error chains |
|
|
17
|
+
| `IgnoreErrors` | `[]string` | `nil` | Regex patterns; matched errors are dropped |
|
|
18
|
+
| `BeforeSend` | `func(*Event, *EventHint) *Event` | `nil` | Mutate or drop error events before sending |
|
|
19
|
+
| `BeforeBreadcrumb` | `func(*Breadcrumb, *BreadcrumbHint) *Breadcrumb` | `nil` | Mutate or drop breadcrumbs |
|
|
20
|
+
|
|
21
|
+
## Code Examples
|
|
22
|
+
|
|
23
|
+
### Basic setup
|
|
24
|
+
|
|
25
|
+
```go
|
|
26
|
+
import (
|
|
27
|
+
"log"
|
|
28
|
+
"os"
|
|
29
|
+
"time"
|
|
30
|
+
"github.com/getsentry/sentry-go"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
func main() {
|
|
34
|
+
err := sentry.Init(sentry.ClientOptions{
|
|
35
|
+
Dsn: os.Getenv("SENTRY_DSN"),
|
|
36
|
+
Environment: os.Getenv("SENTRY_ENVIRONMENT"),
|
|
37
|
+
Release: release, // inject via -ldflags
|
|
38
|
+
AttachStacktrace: true,
|
|
39
|
+
SendDefaultPII: true,
|
|
40
|
+
})
|
|
41
|
+
if err != nil {
|
|
42
|
+
log.Fatalf("sentry.Init: %s", err)
|
|
43
|
+
}
|
|
44
|
+
defer sentry.Flush(2 * time.Second)
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Capturing errors and messages
|
|
49
|
+
|
|
50
|
+
```go
|
|
51
|
+
// Error (any value implementing error interface) — unwraps full chain
|
|
52
|
+
sentry.CaptureException(err)
|
|
53
|
+
|
|
54
|
+
// Plain message (use AttachStacktrace: true for stack traces)
|
|
55
|
+
sentry.CaptureMessage("queue depth exceeded threshold")
|
|
56
|
+
|
|
57
|
+
// Fully manual event
|
|
58
|
+
sentry.CaptureEvent(&sentry.Event{
|
|
59
|
+
Message: "payment gateway timeout",
|
|
60
|
+
Level: sentry.LevelError,
|
|
61
|
+
Tags: map[string]string{"gateway": "stripe"},
|
|
62
|
+
Fingerprint: []string{"payment-gateway", "timeout"},
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Panic recovery
|
|
67
|
+
|
|
68
|
+
```go
|
|
69
|
+
// Simplest — defer in any function
|
|
70
|
+
func riskyOperation() {
|
|
71
|
+
defer sentry.Recover()
|
|
72
|
+
panic("something catastrophic")
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// With context — makes context available in BeforeSend via hint.Context
|
|
76
|
+
func handleRequest(ctx context.Context) {
|
|
77
|
+
defer sentry.RecoverWithContext(ctx)
|
|
78
|
+
processRequest()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Manual — needed when you must flush before process exit
|
|
82
|
+
func main() {
|
|
83
|
+
defer func() {
|
|
84
|
+
if err := recover(); err != nil {
|
|
85
|
+
sentry.CurrentHub().Recover(err)
|
|
86
|
+
sentry.Flush(5 * time.Second)
|
|
87
|
+
}
|
|
88
|
+
}()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// HTTP middleware recovery pattern
|
|
92
|
+
func SentryMiddleware(next http.Handler) http.Handler {
|
|
93
|
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
94
|
+
defer func() {
|
|
95
|
+
if err := recover(); err != nil {
|
|
96
|
+
sentry.CurrentHub().Recover(err)
|
|
97
|
+
sentry.Flush(2 * time.Second)
|
|
98
|
+
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
|
99
|
+
}
|
|
100
|
+
}()
|
|
101
|
+
next.ServeHTTP(w, r)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Hub and scope — context enrichment
|
|
107
|
+
|
|
108
|
+
```go
|
|
109
|
+
// ConfigureScope — persistent modification of the current scope
|
|
110
|
+
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
|
111
|
+
scope.SetUser(sentry.User{
|
|
112
|
+
ID: "user-42",
|
|
113
|
+
Email: "user@example.com",
|
|
114
|
+
})
|
|
115
|
+
scope.SetTag("region", "us-east-1")
|
|
116
|
+
scope.SetContext("request_metadata", map[string]interface{}{
|
|
117
|
+
"trace_id": traceID,
|
|
118
|
+
"account_id": accountID,
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
// WithScope — isolated temporary scope; changes are discarded after the callback
|
|
123
|
+
sentry.WithScope(func(scope *sentry.Scope) {
|
|
124
|
+
scope.SetTag("component", "checkout")
|
|
125
|
+
scope.SetLevel(sentry.LevelWarning)
|
|
126
|
+
sentry.CaptureException(err)
|
|
127
|
+
})
|
|
128
|
+
// ← scope changes above do NOT affect subsequent events
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Hub cloning for goroutines
|
|
132
|
+
|
|
133
|
+
```go
|
|
134
|
+
// ALWAYS clone the hub before spawning goroutines — global hub is not goroutine-safe
|
|
135
|
+
go func(hub *sentry.Hub) {
|
|
136
|
+
hub.ConfigureScope(func(scope *sentry.Scope) {
|
|
137
|
+
scope.SetTag("worker_id", "w-1")
|
|
138
|
+
})
|
|
139
|
+
hub.CaptureException(err)
|
|
140
|
+
}(sentry.CurrentHub().Clone())
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Breadcrumbs
|
|
144
|
+
|
|
145
|
+
```go
|
|
146
|
+
sentry.AddBreadcrumb(&sentry.Breadcrumb{
|
|
147
|
+
Category: "auth",
|
|
148
|
+
Message: "user authenticated",
|
|
149
|
+
Level: sentry.LevelInfo,
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
sentry.AddBreadcrumb(&sentry.Breadcrumb{
|
|
153
|
+
Type: "http",
|
|
154
|
+
Category: "http",
|
|
155
|
+
Data: map[string]interface{}{
|
|
156
|
+
"url": "https://api.example.com/orders",
|
|
157
|
+
"method": "POST",
|
|
158
|
+
"status_code": 503,
|
|
159
|
+
},
|
|
160
|
+
Level: sentry.LevelError,
|
|
161
|
+
})
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Error wrapping and chains
|
|
165
|
+
|
|
166
|
+
The SDK automatically traverses the full error chain from `CaptureException`. Each error
|
|
167
|
+
becomes a separate exception entry in Sentry.
|
|
168
|
+
|
|
169
|
+
```go
|
|
170
|
+
// %w wrapping — both errors captured; dbErr shown as root cause
|
|
171
|
+
dbErr := errors.New("connection refused")
|
|
172
|
+
appErr := fmt.Errorf("failed to load user %d: %w", userID, dbErr)
|
|
173
|
+
sentry.CaptureException(appErr)
|
|
174
|
+
|
|
175
|
+
// errors.Join (Go 1.20+) — captured as Sentry exception group
|
|
176
|
+
combined := errors.Join(errors.New("email invalid"), errors.New("token expired"))
|
|
177
|
+
sentry.CaptureException(combined)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
| Wrapping pattern | Interface | Mechanism |
|
|
181
|
+
| ----------------------- | ------------------ | ----------- |
|
|
182
|
+
| `fmt.Errorf("%w", err)` | `Unwrap() error` | `"unwrap"` |
|
|
183
|
+
| `errors.Join(...)` | `Unwrap() []error` | `"chained"` |
|
|
184
|
+
| `pkg/errors` | `Cause() error` | `"cause"` |
|
|
185
|
+
|
|
186
|
+
Limit chain depth with `MaxErrorDepth` (default 100).
|
|
187
|
+
|
|
188
|
+
### BeforeSend hook
|
|
189
|
+
|
|
190
|
+
```go
|
|
191
|
+
sentry.Init(sentry.ClientOptions{
|
|
192
|
+
Dsn: os.Getenv("SENTRY_DSN"),
|
|
193
|
+
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
|
194
|
+
// Drop events from health check endpoints
|
|
195
|
+
if event.Request != nil && strings.HasPrefix(event.Request.URL, "/health") {
|
|
196
|
+
return nil // discard
|
|
197
|
+
}
|
|
198
|
+
// Scrub PII
|
|
199
|
+
event.User.Email = ""
|
|
200
|
+
event.User.IPAddress = ""
|
|
201
|
+
// Enrich from original exception type
|
|
202
|
+
if dbErr, ok := hint.OriginalException.(*DatabaseError); ok {
|
|
203
|
+
event.Tags["db.table"] = dbErr.Table
|
|
204
|
+
}
|
|
205
|
+
// Access context set by RecoverWithContext
|
|
206
|
+
if hint.Context != nil {
|
|
207
|
+
if reqID, ok := hint.Context.Value(RequestIDKey).(string); ok {
|
|
208
|
+
event.Tags["request_id"] = reqID
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return event
|
|
212
|
+
},
|
|
213
|
+
// BeforeSend is NOT called for transaction events — use BeforeSendTransaction for those
|
|
214
|
+
BeforeSendTransaction: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
|
215
|
+
if event.Transaction == "GET /healthz" {
|
|
216
|
+
return nil
|
|
217
|
+
}
|
|
218
|
+
return event
|
|
219
|
+
},
|
|
220
|
+
})
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Event processors
|
|
224
|
+
|
|
225
|
+
```go
|
|
226
|
+
// Scope-level (per-request enrichment — preferred)
|
|
227
|
+
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
|
228
|
+
scope.AddEventProcessor(func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
|
229
|
+
event.Tags["request_id"] = r.Header.Get("X-Request-ID")
|
|
230
|
+
event.Tags["tenant_id"] = r.Header.Get("X-Tenant-ID")
|
|
231
|
+
return event
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
// Client-level (all events from this client)
|
|
236
|
+
client, _ := sentry.NewClient(sentry.ClientOptions{Dsn: os.Getenv("SENTRY_DSN")})
|
|
237
|
+
client.AddEventProcessor(func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
|
238
|
+
event.Tags["build_sha"] = os.Getenv("GIT_SHA")
|
|
239
|
+
return event
|
|
240
|
+
})
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Processor execution order: scope processors (LIFO) → client processors → `BeforeSend`.
|
|
244
|
+
|
|
245
|
+
### Fingerprinting and custom grouping
|
|
246
|
+
|
|
247
|
+
```go
|
|
248
|
+
// One-off — override grouping for a specific error type
|
|
249
|
+
sentry.WithScope(func(scope *sentry.Scope) {
|
|
250
|
+
scope.SetFingerprint([]string{"database-connection-error"})
|
|
251
|
+
sentry.CaptureException(err)
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
// Extend default grouping (keeps stack trace + adds discriminators)
|
|
255
|
+
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
|
|
256
|
+
if rpcErr, ok := hint.OriginalException.(MyRPCError); ok {
|
|
257
|
+
event.Fingerprint = []string{
|
|
258
|
+
"{{ default }}",
|
|
259
|
+
rpcErr.FunctionName(),
|
|
260
|
+
strconv.Itoa(rpcErr.ErrorCode()),
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return event
|
|
264
|
+
},
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Flush patterns
|
|
268
|
+
|
|
269
|
+
```go
|
|
270
|
+
// Recommended: defer in main()
|
|
271
|
+
defer sentry.Flush(2 * time.Second)
|
|
272
|
+
|
|
273
|
+
// os.Exit() bypasses defer — call explicitly
|
|
274
|
+
sentry.Flush(2 * time.Second)
|
|
275
|
+
os.Exit(1)
|
|
276
|
+
|
|
277
|
+
// Context-based
|
|
278
|
+
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
279
|
+
defer cancel()
|
|
280
|
+
sentry.FlushWithContext(ctx)
|
|
281
|
+
|
|
282
|
+
// Synchronous transport (no flush needed — every send blocks)
|
|
283
|
+
transport := sentry.NewHTTPSyncTransport()
|
|
284
|
+
transport.Timeout = 3 * time.Second
|
|
285
|
+
sentry.Init(sentry.ClientOptions{Dsn: "...", Transport: transport})
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Scope API Reference
|
|
289
|
+
|
|
290
|
+
```go
|
|
291
|
+
scope.SetUser(sentry.User{ID: "42", Email: "user@example.com"})
|
|
292
|
+
scope.SetTag("key", "value")
|
|
293
|
+
scope.SetTags(map[string]string{"k": "v"})
|
|
294
|
+
scope.SetContext("key", map[string]interface{}{"field": "value"})
|
|
295
|
+
scope.SetLevel(sentry.LevelError) // "debug" | "info" | "warning" | "error" | "fatal"
|
|
296
|
+
scope.SetRequest(r *http.Request)
|
|
297
|
+
scope.SetFingerprint([]string{"my-group"})
|
|
298
|
+
scope.AddBreadcrumb(bc, limit)
|
|
299
|
+
scope.ClearBreadcrumbs()
|
|
300
|
+
scope.AddEventProcessor(func(*sentry.Event, *sentry.EventHint) *sentry.Event)
|
|
301
|
+
scope.Clear()
|
|
302
|
+
scope.Clone() *sentry.Scope
|
|
303
|
+
|
|
304
|
+
// Attributes — attach typed key-value pairs to logs and metrics
|
|
305
|
+
scope.SetAttributes(attribute.String("key", "value"), attribute.Int("count", 42))
|
|
306
|
+
scope.RemoveAttribute("key")
|
|
307
|
+
|
|
308
|
+
// Removed in sentry-go v0.34.0 — do not use
|
|
309
|
+
// scope.SetExtra("key", value) // REMOVED — use SetTag / SetContext or SetAttributes
|
|
310
|
+
// scope.SetExtras(map[string]interface{}{}) // REMOVED
|
|
311
|
+
// scope.RemoveExtra("key") // REMOVED — use RemoveTag / RemoveContext or RemoveAttribute
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Migration from removed Extra APIs (removed in v0.34.0):**
|
|
315
|
+
|
|
316
|
+
```go
|
|
317
|
+
// Before (removed)
|
|
318
|
+
scope.SetExtra("key.string", "str")
|
|
319
|
+
scope.SetExtra("key.int", 42)
|
|
320
|
+
|
|
321
|
+
// After — for error events, use tags and contexts:
|
|
322
|
+
scope.SetTag("key.string", "str")
|
|
323
|
+
scope.SetContext("my_data", sentry.Context{"key.int": 42})
|
|
324
|
+
|
|
325
|
+
// After — for logs and metrics, use attributes:
|
|
326
|
+
scope.SetAttributes(
|
|
327
|
+
attribute.String("key.string", "str"),
|
|
328
|
+
attribute.Int("key.int", 42),
|
|
329
|
+
)
|
|
330
|
+
scope.RemoveAttribute("key.string") // replaces RemoveExtra
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Best Practices
|
|
334
|
+
|
|
335
|
+
- Call `sentry.Init()` once in `main()`, before any goroutines or handlers start
|
|
336
|
+
- Always check the error returned by `sentry.Init()`
|
|
337
|
+
- Always `defer sentry.Flush(2 * time.Second)` in `main()`; call it explicitly before
|
|
338
|
+
`os.Exit()`
|
|
339
|
+
- Clone the hub before passing it to goroutines: `hub := sentry.CurrentHub().Clone()`
|
|
340
|
+
- Use `WithScope` for one-off context; use `ConfigureScope` for persistent session
|
|
341
|
+
context
|
|
342
|
+
- Use `SetTag` or `SetContext` for error event data —
|
|
343
|
+
`SetExtra`/`SetExtras`/`RemoveExtra` were **removed in v0.34.0** and no longer compile
|
|
344
|
+
- Use `SetAttributes` / `RemoveAttribute` to attach typed key-value pairs to logs and
|
|
345
|
+
metrics (attributes do not appear on error events)
|
|
346
|
+
- Use `BeforeSend` to strip PII — never send raw email/IP unless `SendDefaultPII: true`
|
|
347
|
+
is intentional
|
|
348
|
+
- Set `MaxErrorDepth` to a sensible value (5–10) for deeply wrapped error chains
|
|
349
|
+
|
|
350
|
+
## Troubleshooting
|
|
351
|
+
|
|
352
|
+
| Issue | Solution |
|
|
353
|
+
| -------------------------------------- | ------------------------------------------------------------------------------ |
|
|
354
|
+
| Events not appearing | Set `Debug: true`; verify DSN; ensure `sentry.Flush()` is called |
|
|
355
|
+
| Missing stack traces on messages | Set `AttachStacktrace: true` in `ClientOptions` |
|
|
356
|
+
| Goroutine events missing scope data | Clone hub before goroutine: `sentry.CurrentHub().Clone()` |
|
|
357
|
+
| Panics not captured | Register framework middleware before handlers; or add `defer sentry.Recover()` |
|
|
358
|
+
| `defer sentry.Flush` not running | `os.Exit()` skips defers — call `sentry.Flush()` explicitly |
|
|
359
|
+
| `SampleRate: 0.0` still sending | `0.0` is treated as `1.0`; to drop all, set `Dsn: ""` |
|
|
360
|
+
| Error chain shows only top error | Check `MaxErrorDepth`; ensure errors use `%w` or implement `Unwrap()` |
|
|
361
|
+
| BeforeSend not called for transactions | Use `BeforeSendTransaction` for transaction/performance events |
|