@danieljvdm/dev-kit 1.0.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/package.json +1 -1
- package/skill-sources.jsonc +6 -29
- package/skill-sources.lock.json +23 -109
- package/skills/animate/LICENSE +21 -0
- package/skills/animate/NOTICE +10 -0
- package/skills/animate/SKILL.md +34 -0
- package/skills/animate/references/gestures.md +27 -0
- package/skills/animate/references/glossary.md +136 -0
- package/skills/animate/references/implementation.md +22 -0
- package/skills/animate/references/opportunities.md +18 -0
- package/skills/animate/references/principles.md +48 -0
- package/skills/animate/references/review.md +19 -0
- package/skills/cloudflare-workers/LICENSE +202 -0
- package/skills/cloudflare-workers/NOTICE +9 -0
- package/skills/cloudflare-workers/SKILL.md +26 -0
- package/skills/cloudflare-workers/references/durable-objects.md +68 -0
- package/skills/cloudflare-workers/references/sandbox.md +48 -0
- package/skills/cloudflare-workers/references/workers.md +63 -0
- package/skills/cloudflare-workers/references/wrangler.md +56 -0
- package/skills/design-ui/LICENSE +21 -0
- package/skills/design-ui/NOTICE +8 -0
- package/skills/design-ui/SKILL.md +29 -0
- package/skills/design-ui/references/appearance.md +22 -0
- package/skills/design-ui/references/components.md +33 -0
- package/skills/design-ui/references/exploration.md +50 -0
- package/skills/design-ui/references/libraries.md +39 -0
- package/skills/design-ui/references/themes.md +23 -0
- package/skills/dev-kit/SKILL.md +19 -38
- package/skills/dev-kit/references/cloudflare-worker-api.md +1 -1
- package/skills/dev-kit/references/skills.md +2 -2
- package/skills/effect-development/SKILL.md +27 -0
- package/skills/effect-development/agents/openai.yaml +4 -0
- package/skills/effect-development/references/api/index.md +32 -0
- package/skills/effect-development/references/api/schema-codecs.md +15 -0
- package/skills/{build-effect-apis/references → effect-development/references/api}/verification.md +10 -5
- package/skills/{effect-architecture-audit/SKILL.md → effect-development/references/architecture/index.md} +1 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-client.md +8 -6
- package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-testing.md +7 -2
- package/skills/effect-development/references/atom/index.md +40 -0
- package/skills/{build-effect-clis/references → effect-development/references/cli}/entrypoints-and-testing.md +6 -2
- package/skills/effect-development/references/cli/index.md +39 -0
- package/skills/effect-development/references/setup.md +15 -0
- package/skills/open-pull-request/SKILL.md +11 -115
- package/skills/open-pull-request/agents/openai.yaml +3 -3
- package/skills/open-pull-request/references/evidence.md +22 -0
- package/skills/open-pull-request/references/explanation.md +21 -0
- package/skills/open-pull-request/references/publication.md +21 -0
- package/skills/sentry/LICENSE +202 -0
- package/skills/sentry/LICENSE-UPSTREAM +21 -0
- package/skills/sentry/NOTICE +14 -0
- package/skills/sentry/SKILL.md +33 -0
- package/skills/sentry/references/alert-payloads.md +105 -0
- package/skills/sentry/references/alerts.md +17 -0
- package/skills/sentry/references/artifacts.md +25 -0
- package/skills/sentry/references/auth-token.md +65 -0
- package/skills/sentry/references/concepts/ai-monitoring.md +131 -0
- package/skills/sentry/references/concepts/choosing-a-signal.md +78 -0
- package/skills/sentry/references/concepts/crons.md +50 -0
- package/skills/sentry/references/concepts/data-scrubbing.md +43 -0
- package/skills/sentry/references/concepts/errors.md +40 -0
- package/skills/sentry/references/concepts/logging.md +85 -0
- package/skills/sentry/references/concepts/metrics.md +49 -0
- package/skills/sentry/references/concepts/monitors.md +78 -0
- package/skills/sentry/references/concepts/profiling.md +38 -0
- package/skills/sentry/references/concepts/reduce-volume.md +49 -0
- package/skills/sentry/references/concepts/releases.md +43 -0
- package/skills/sentry/references/concepts/session-replay.md +35 -0
- package/skills/sentry/references/concepts/tracing.md +54 -0
- package/skills/sentry/references/concepts/user-feedback.md +36 -0
- package/skills/sentry/references/debug-artifacts/android.md +68 -0
- package/skills/sentry/references/debug-artifacts/apple.md +96 -0
- package/skills/sentry/references/debug-artifacts/dotnet.md +70 -0
- package/skills/sentry/references/debug-artifacts/flutter.md +65 -0
- package/skills/sentry/references/debug-artifacts/index.md +75 -0
- package/skills/sentry/references/debug-artifacts/javascript.md +94 -0
- package/skills/sentry/references/debug-artifacts/matching.md +73 -0
- package/skills/sentry/references/debug-artifacts/react-native.md +75 -0
- package/skills/sentry/references/first-error-setup.md +25 -0
- package/skills/sentry/references/instrumentation.md +30 -0
- package/skills/sentry/references/issues.md +32 -0
- package/skills/sentry/references/new-project.md +17 -0
- package/skills/sentry/references/otel-exporter.md +30 -0
- package/skills/sentry/references/release-workflow.md +31 -0
- package/skills/sentry/references/releases/ci-pipeline.md +214 -0
- package/skills/sentry/references/releases/index.md +93 -0
- package/skills/sentry/references/releases/suspect-commits.md +155 -0
- package/skills/sentry/references/releases/tagging.md +131 -0
- package/skills/sentry/references/releases/troubleshooting.md +67 -0
- package/skills/sentry/references/sdks/android/crons.md +305 -0
- package/skills/sentry/references/sdks/android/error-monitoring.md +800 -0
- package/skills/sentry/references/sdks/android/index.md +748 -0
- package/skills/sentry/references/sdks/android/integrations.md +48 -0
- package/skills/sentry/references/sdks/android/logging.md +374 -0
- package/skills/sentry/references/sdks/android/metrics.md +288 -0
- package/skills/sentry/references/sdks/android/profiling.md +397 -0
- package/skills/sentry/references/sdks/android/session-replay.md +406 -0
- package/skills/sentry/references/sdks/android/tracing.md +861 -0
- package/skills/sentry/references/sdks/browser/error-monitoring.md +861 -0
- package/skills/sentry/references/sdks/browser/index.md +714 -0
- package/skills/sentry/references/sdks/browser/logging.md +315 -0
- package/skills/sentry/references/sdks/browser/profiling.md +236 -0
- package/skills/sentry/references/sdks/browser/session-replay.md +586 -0
- package/skills/sentry/references/sdks/browser/tracing.md +561 -0
- package/skills/sentry/references/sdks/browser/user-feedback.md +354 -0
- package/skills/sentry/references/sdks/cloudflare/ai-monitoring.md +661 -0
- package/skills/sentry/references/sdks/cloudflare/crons.md +231 -0
- package/skills/sentry/references/sdks/cloudflare/durable-objects.md +381 -0
- package/skills/sentry/references/sdks/cloudflare/error-monitoring.md +329 -0
- package/skills/sentry/references/sdks/cloudflare/index.md +698 -0
- package/skills/sentry/references/sdks/cloudflare/logging.md +169 -0
- package/skills/sentry/references/sdks/cloudflare/nodejs-compat.md +134 -0
- package/skills/sentry/references/sdks/cloudflare/tracing.md +475 -0
- package/skills/sentry/references/sdks/cocoa/error-monitoring.md +394 -0
- package/skills/sentry/references/sdks/cocoa/index.md +497 -0
- package/skills/sentry/references/sdks/cocoa/logging.md +209 -0
- package/skills/sentry/references/sdks/cocoa/metrics.md +136 -0
- package/skills/sentry/references/sdks/cocoa/profiling.md +223 -0
- package/skills/sentry/references/sdks/cocoa/session-replay.md +257 -0
- package/skills/sentry/references/sdks/cocoa/tracing.md +524 -0
- package/skills/sentry/references/sdks/cocoa/user-feedback.md +310 -0
- package/skills/sentry/references/sdks/dotnet/crons.md +465 -0
- package/skills/sentry/references/sdks/dotnet/error-monitoring.md +1100 -0
- package/skills/sentry/references/sdks/dotnet/index.md +614 -0
- package/skills/sentry/references/sdks/dotnet/logging.md +556 -0
- package/skills/sentry/references/sdks/dotnet/metrics.md +229 -0
- package/skills/sentry/references/sdks/dotnet/profiling.md +296 -0
- package/skills/sentry/references/sdks/dotnet/tracing.md +897 -0
- package/skills/sentry/references/sdks/elixir/crons.md +371 -0
- package/skills/sentry/references/sdks/elixir/error-monitoring.md +335 -0
- package/skills/sentry/references/sdks/elixir/index.md +383 -0
- package/skills/sentry/references/sdks/elixir/logging.md +239 -0
- package/skills/sentry/references/sdks/elixir/tracing.md +233 -0
- package/skills/sentry/references/sdks/flutter/ecosystem-integrations.md +70 -0
- package/skills/sentry/references/sdks/flutter/error-monitoring.md +312 -0
- package/skills/sentry/references/sdks/flutter/index.md +728 -0
- package/skills/sentry/references/sdks/flutter/logging.md +387 -0
- package/skills/sentry/references/sdks/flutter/metrics.md +310 -0
- package/skills/sentry/references/sdks/flutter/profiling.md +214 -0
- package/skills/sentry/references/sdks/flutter/session-replay.md +308 -0
- package/skills/sentry/references/sdks/flutter/tracing.md +502 -0
- package/skills/sentry/references/sdks/go/crons.md +270 -0
- package/skills/sentry/references/sdks/go/error-monitoring.md +361 -0
- package/skills/sentry/references/sdks/go/index.md +324 -0
- package/skills/sentry/references/sdks/go/logging.md +354 -0
- package/skills/sentry/references/sdks/go/metrics.md +273 -0
- package/skills/sentry/references/sdks/go/profiling.md +46 -0
- package/skills/sentry/references/sdks/go/tracing.md +366 -0
- package/skills/sentry/references/sdks/index.md +41 -0
- package/skills/sentry/references/sdks/nestjs/ai-monitoring.md +410 -0
- package/skills/sentry/references/sdks/nestjs/crons.md +268 -0
- package/skills/sentry/references/sdks/nestjs/error-monitoring.md +729 -0
- package/skills/sentry/references/sdks/nestjs/index.md +699 -0
- package/skills/sentry/references/sdks/nestjs/logging.md +174 -0
- package/skills/sentry/references/sdks/nestjs/metrics.md +243 -0
- package/skills/sentry/references/sdks/nestjs/profiling.md +127 -0
- package/skills/sentry/references/sdks/nestjs/tracing.md +762 -0
- package/skills/sentry/references/sdks/nextjs/ai-monitoring.md +494 -0
- package/skills/sentry/references/sdks/nextjs/crons.md +383 -0
- package/skills/sentry/references/sdks/nextjs/error-monitoring.md +974 -0
- package/skills/sentry/references/sdks/nextjs/index.md +491 -0
- package/skills/sentry/references/sdks/nextjs/logging.md +381 -0
- package/skills/sentry/references/sdks/nextjs/metrics.md +411 -0
- package/skills/sentry/references/sdks/nextjs/profiling.md +403 -0
- package/skills/sentry/references/sdks/nextjs/session-replay.md +462 -0
- package/skills/sentry/references/sdks/nextjs/tracing.md +628 -0
- package/skills/sentry/references/sdks/node/ai-monitoring.md +303 -0
- package/skills/sentry/references/sdks/node/crons.md +432 -0
- package/skills/sentry/references/sdks/node/error-monitoring.md +1125 -0
- package/skills/sentry/references/sdks/node/index.md +942 -0
- package/skills/sentry/references/sdks/node/logging.md +380 -0
- package/skills/sentry/references/sdks/node/metrics.md +278 -0
- package/skills/sentry/references/sdks/node/profiling.md +373 -0
- package/skills/sentry/references/sdks/node/tracing.md +878 -0
- package/skills/sentry/references/sdks/php/ai-monitoring.md +310 -0
- package/skills/sentry/references/sdks/php/crons.md +265 -0
- package/skills/sentry/references/sdks/php/error-monitoring.md +626 -0
- package/skills/sentry/references/sdks/php/index.md +362 -0
- package/skills/sentry/references/sdks/php/laravel.md +542 -0
- package/skills/sentry/references/sdks/php/logging.md +242 -0
- package/skills/sentry/references/sdks/php/metrics.md +193 -0
- package/skills/sentry/references/sdks/php/profiling.md +115 -0
- package/skills/sentry/references/sdks/php/symfony.md +552 -0
- package/skills/sentry/references/sdks/php/tracing.md +516 -0
- package/skills/sentry/references/sdks/python/ai-monitoring.md +351 -0
- package/skills/sentry/references/sdks/python/crons.md +218 -0
- package/skills/sentry/references/sdks/python/error-monitoring.md +292 -0
- package/skills/sentry/references/sdks/python/index.md +361 -0
- package/skills/sentry/references/sdks/python/logging.md +234 -0
- package/skills/sentry/references/sdks/python/metrics.md +154 -0
- package/skills/sentry/references/sdks/python/profiling.md +120 -0
- package/skills/sentry/references/sdks/python/tracing.md +364 -0
- package/skills/sentry/references/sdks/react/error-monitoring.md +1607 -0
- package/skills/sentry/references/sdks/react/index.md +492 -0
- package/skills/sentry/references/sdks/react/logging.md +364 -0
- package/skills/sentry/references/sdks/react/profiling.md +322 -0
- package/skills/sentry/references/sdks/react/react-features.md +1272 -0
- package/skills/sentry/references/sdks/react/session-replay.md +1193 -0
- package/skills/sentry/references/sdks/react/tracing.md +1415 -0
- package/skills/sentry/references/sdks/react-native/error-monitoring.md +1481 -0
- package/skills/sentry/references/sdks/react-native/expo-config-plugin.md +45 -0
- package/skills/sentry/references/sdks/react-native/index.md +1030 -0
- package/skills/sentry/references/sdks/react-native/logging.md +444 -0
- package/skills/sentry/references/sdks/react-native/profiling.md +386 -0
- package/skills/sentry/references/sdks/react-native/session-replay.md +704 -0
- package/skills/sentry/references/sdks/react-native/tracing.md +1086 -0
- package/skills/sentry/references/sdks/react-native/user-feedback.md +815 -0
- package/skills/sentry/references/sdks/react-router-framework/error-monitoring.md +127 -0
- package/skills/sentry/references/sdks/react-router-framework/index.md +411 -0
- package/skills/sentry/references/sdks/react-router-framework/logging.md +66 -0
- package/skills/sentry/references/sdks/react-router-framework/profiling.md +57 -0
- package/skills/sentry/references/sdks/react-router-framework/react-router-framework-features.md +110 -0
- package/skills/sentry/references/sdks/react-router-framework/session-replay.md +67 -0
- package/skills/sentry/references/sdks/react-router-framework/tracing.md +96 -0
- package/skills/sentry/references/sdks/react-router-framework/user-feedback.md +71 -0
- package/skills/sentry/references/sdks/ruby/crons.md +184 -0
- package/skills/sentry/references/sdks/ruby/error-monitoring.md +248 -0
- package/skills/sentry/references/sdks/ruby/index.md +297 -0
- package/skills/sentry/references/sdks/ruby/logging.md +168 -0
- package/skills/sentry/references/sdks/ruby/metrics.md +196 -0
- package/skills/sentry/references/sdks/ruby/migration.md +321 -0
- package/skills/sentry/references/sdks/ruby/profiling.md +107 -0
- package/skills/sentry/references/sdks/ruby/tracing.md +388 -0
- package/skills/sentry/references/sdks/svelte/error-monitoring.md +456 -0
- package/skills/sentry/references/sdks/svelte/index.md +467 -0
- package/skills/sentry/references/sdks/svelte/logging.md +344 -0
- package/skills/sentry/references/sdks/svelte/session-replay.md +369 -0
- package/skills/sentry/references/sdks/svelte/tracing.md +406 -0
- package/skills/sentry/references/sdks/tanstack-start/error-monitoring.md +149 -0
- package/skills/sentry/references/sdks/tanstack-start/index.md +381 -0
- package/skills/sentry/references/sdks/tanstack-start/logging.md +74 -0
- package/skills/sentry/references/sdks/tanstack-start/session-replay.md +76 -0
- package/skills/sentry/references/sdks/tanstack-start/tanstackstart-features.md +128 -0
- package/skills/sentry/references/sdks/tanstack-start/tracing.md +123 -0
- package/skills/sentry/references/sdks/tanstack-start/user-feedback.md +81 -0
- package/skills/sentry/references/search-query-language.md +226 -0
- package/skills/sentry/references/semantics/angular.md +7 -0
- package/skills/sentry/references/semantics/app.md +28 -0
- package/skills/sentry/references/semantics/art.md +17 -0
- package/skills/sentry/references/semantics/aws.md +43 -0
- package/skills/sentry/references/semantics/browser.md +34 -0
- package/skills/sentry/references/semantics/cache.md +12 -0
- package/skills/sentry/references/semantics/client.md +8 -0
- package/skills/sentry/references/semantics/cloud.md +12 -0
- package/skills/sentry/references/semantics/cloudflare.md +23 -0
- package/skills/sentry/references/semantics/code.md +11 -0
- package/skills/sentry/references/semantics/culture.md +11 -0
- package/skills/sentry/references/semantics/db.md +21 -0
- package/skills/sentry/references/semantics/device.md +43 -0
- package/skills/sentry/references/semantics/error.md +7 -0
- package/skills/sentry/references/semantics/event.md +8 -0
- package/skills/sentry/references/semantics/exception.md +10 -0
- package/skills/sentry/references/semantics/faas.md +19 -0
- package/skills/sentry/references/semantics/file.md +8 -0
- package/skills/sentry/references/semantics/flag.md +7 -0
- package/skills/sentry/references/semantics/gcp.md +16 -0
- package/skills/sentry/references/semantics/gen_ai.md +53 -0
- package/skills/sentry/references/semantics/general.md +11 -0
- package/skills/sentry/references/semantics/graphql.md +9 -0
- package/skills/sentry/references/semantics/grpc.md +19 -0
- package/skills/sentry/references/semantics/http.md +34 -0
- package/skills/sentry/references/semantics/index.md +63 -0
- package/skills/sentry/references/semantics/jsonrpc.md +8 -0
- package/skills/sentry/references/semantics/jvm.md +12 -0
- package/skills/sentry/references/semantics/koa.md +7 -0
- package/skills/sentry/references/semantics/logger.md +7 -0
- package/skills/sentry/references/semantics/mcp.md +37 -0
- package/skills/sentry/references/semantics/mdc.md +7 -0
- package/skills/sentry/references/semantics/messaging.md +23 -0
- package/skills/sentry/references/semantics/middleware.md +7 -0
- package/skills/sentry/references/semantics/navigation.md +9 -0
- package/skills/sentry/references/semantics/nel.md +11 -0
- package/skills/sentry/references/semantics/network.md +17 -0
- package/skills/sentry/references/semantics/os.md +15 -0
- package/skills/sentry/references/semantics/otel.md +10 -0
- package/skills/sentry/references/semantics/params.md +7 -0
- package/skills/sentry/references/semantics/process.md +14 -0
- package/skills/sentry/references/semantics/react.md +7 -0
- package/skills/sentry/references/semantics/remix.md +7 -0
- package/skills/sentry/references/semantics/resource.md +7 -0
- package/skills/sentry/references/semantics/rpc.md +10 -0
- package/skills/sentry/references/semantics/score.md +10 -0
- package/skills/sentry/references/semantics/sentry.md +69 -0
- package/skills/sentry/references/semantics/server.md +8 -0
- package/skills/sentry/references/semantics/service.md +8 -0
- package/skills/sentry/references/semantics/session.md +7 -0
- package/skills/sentry/references/semantics/state.md +7 -0
- package/skills/sentry/references/semantics/thread.md +8 -0
- package/skills/sentry/references/semantics/timber.md +7 -0
- package/skills/sentry/references/semantics/trpc.md +8 -0
- package/skills/sentry/references/semantics/ui.md +18 -0
- package/skills/sentry/references/semantics/url.md +15 -0
- package/skills/sentry/references/semantics/user.md +17 -0
- package/skills/sentry/references/semantics/user_agent.md +7 -0
- package/skills/sentry/references/semantics/vercel.md +42 -0
- package/skills/sentry/references/setup-verification.md +39 -0
- package/skills/sentry/references/snapshots/github-actions-fanout.md +206 -0
- package/skills/sentry/references/snapshots/github-actions-simple.md +102 -0
- package/skills/sentry/references/snapshots/github-actions-swift-snapshot-testing.md +118 -0
- package/skills/sentry/references/snapshots/index.md +19 -0
- package/skills/sentry/references/snapshots/snapshot-previews.md +100 -0
- package/skills/sentry/references/snapshots/snapshots.md +123 -0
- package/skills/sentry/references/snapshots/wizard-setup.md +134 -0
- package/skills/testing/LICENSE +21 -0
- package/skills/testing/NOTICE +7 -0
- package/skills/testing/SKILL.md +13 -19
- package/skills/testing/agents/openai.yaml +1 -2
- package/skills/testing/references/selection.md +23 -0
- package/skills/testing/references/tdd.md +19 -0
- package/skills/testing/references/test-design.md +17 -0
- package/src/catalog.ts +1 -7
- package/skills/build-effect-apis/SKILL.md +0 -81
- package/skills/build-effect-apis/agents/openai.yaml +0 -4
- package/skills/build-effect-clis/SKILL.md +0 -92
- package/skills/build-effect-clis/agents/openai.yaml +0 -4
- package/skills/effect-architecture-audit/agents/openai.yaml +0 -4
- package/skills/effect-atom-state/SKILL.md +0 -97
- package/skills/effect-atom-state/agents/openai.yaml +0 -4
- package/skills/effect-ts/SKILL.md +0 -35
- package/skills/effect-ts/agents/openai.yaml +0 -4
- /package/skills/{build-effect-apis/references → effect-development/references/api}/cloudflare-workers.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/runtime-assembly.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/server-and-middleware.md +0 -0
- /package/skills/{build-effect-apis/references → effect-development/references/api}/shared-contracts.md +0 -0
- /package/skills/{effect-architecture-audit/references → effect-development/references/architecture}/service-and-boundary-audit.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-lifecycle.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-workflows.md +0 -0
- /package/skills/{effect-atom-state/references → effect-development/references/atom}/tanstack-start.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/command-design.md +0 -0
- /package/skills/{build-effect-clis/references → effect-development/references/cli}/processes-and-platform.md +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Logging — Sentry Ruby SDK
|
|
2
|
+
|
|
3
|
+
> Minimum SDK: `sentry-ruby` v5.27.0+ Logs are sent as independent events to Sentry Logs
|
|
4
|
+
> — separate from breadcrumbs and error events.
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- [Configuration](#configuration)
|
|
9
|
+
- [Logging Methods](#logging-methods)
|
|
10
|
+
- [Filtering Logs](#filtering-logs)
|
|
11
|
+
- [Breadcrumb Loggers](#breadcrumb-loggers)
|
|
12
|
+
- [Ruby stdlib Logger integration](#ruby-stdlib-logger-integration)
|
|
13
|
+
- [Rails Logger](#rails-logger)
|
|
14
|
+
- [Best Practices](#best-practices)
|
|
15
|
+
- [Troubleshooting](#troubleshooting)
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
| Option | Type | Default | Purpose |
|
|
20
|
+
| -------------------- | ------- | ------- | ------------------------------------------------------------- |
|
|
21
|
+
| `enable_logs` | Boolean | `false` | Enable Sentry structured Logs — must be `true` |
|
|
22
|
+
| `before_send_log` | Lambda | `nil` | Mutate or drop log events before sending |
|
|
23
|
+
| `breadcrumbs_logger` | Array | `[]` | Loggers for automatic breadcrumbs (separate from Sentry Logs) |
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
Sentry.init do |config|
|
|
27
|
+
config.dsn = ENV["SENTRY_DSN"]
|
|
28
|
+
config.enable_logs = true # required — disabled by default
|
|
29
|
+
end
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Logging Methods
|
|
33
|
+
|
|
34
|
+
`Sentry.logger` provides six levels:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
Sentry.logger.trace("entering payment flow")
|
|
38
|
+
Sentry.logger.debug("cache miss for key: %{key}", key: cache_key)
|
|
39
|
+
Sentry.logger.info("User %{name} logged in", name: user.email)
|
|
40
|
+
Sentry.logger.warn("Retry %{attempt} of %{max}", attempt: 3, max: 5)
|
|
41
|
+
Sentry.logger.error("Payment failed: %{message}", message: e.message)
|
|
42
|
+
Sentry.logger.fatal("Database unreachable — shutting down")
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Parameterized messages
|
|
46
|
+
|
|
47
|
+
Use `%{key}` named parameters.
|
|
48
|
+
Parameters are sent as structured attributes, enabling filtering and aggregation in
|
|
49
|
+
Sentry:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
# Named parameters (preferred)
|
|
53
|
+
Sentry.logger.info(
|
|
54
|
+
"Order %{order_id} placed for %{amount}",
|
|
55
|
+
order_id: order.id,
|
|
56
|
+
amount: order.total
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Positional parameters
|
|
60
|
+
Sentry.logger.info("Order %s placed", [order.id])
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Extra attributes
|
|
64
|
+
|
|
65
|
+
Pass keyword arguments beyond the message to attach searchable data:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
Sentry.logger.error(
|
|
69
|
+
"Failed to process payment for order %{order_id}",
|
|
70
|
+
order_id: order.id,
|
|
71
|
+
amount: order.total,
|
|
72
|
+
payment_provider: "stripe",
|
|
73
|
+
error_code: stripe_error.code
|
|
74
|
+
)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Filtering Logs
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
config.before_send_log = lambda do |log|
|
|
81
|
+
# Drop debug-level logs in production
|
|
82
|
+
return nil if log.level == :debug
|
|
83
|
+
|
|
84
|
+
# Scrub sensitive content
|
|
85
|
+
log.message = log.message.gsub(/token=\S+/, "token=[FILTERED]")
|
|
86
|
+
|
|
87
|
+
log
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `before_send_log` parameter
|
|
92
|
+
|
|
93
|
+
The `log` argument passed to the callback exposes:
|
|
94
|
+
|
|
95
|
+
| Property | Type | Description |
|
|
96
|
+
| ------------ | ------ | -------------------------------------------------------- |
|
|
97
|
+
| `level` | Symbol | `:trace`, `:debug`, `:info`, `:warn`, `:error`, `:fatal` |
|
|
98
|
+
| `message` | String | The formatted log message |
|
|
99
|
+
| `body` | String | Raw template string (e.g., `"Order %{order_id} placed"`) |
|
|
100
|
+
| `attributes` | Hash | Structured parameters passed as keyword arguments |
|
|
101
|
+
|
|
102
|
+
## Breadcrumb Loggers
|
|
103
|
+
|
|
104
|
+
Breadcrumbs are different from Sentry Logs — they are attached to the next error event,
|
|
105
|
+
not sent independently.
|
|
106
|
+
See `error-monitoring.md` for the full logger table and configuration options.
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
config.breadcrumbs_logger = [:active_support_logger, :http_logger, :redis_logger, :sentry_logger]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Filtering breadcrumbs
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
config.before_breadcrumb = lambda do |breadcrumb, hint|
|
|
116
|
+
# Drop Redis noise in high-traffic environments
|
|
117
|
+
return nil if breadcrumb.category == "redis"
|
|
118
|
+
breadcrumb
|
|
119
|
+
end
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Ruby stdlib Logger integration
|
|
123
|
+
|
|
124
|
+
Capture writes from existing Ruby `Logger` instances as Sentry breadcrumbs.
|
|
125
|
+
This requires enabling the `:logger` patch first — without it `std_lib_logger_filter` is
|
|
126
|
+
never called:
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
config.breadcrumbs_logger = [:sentry_logger]
|
|
130
|
+
config.enabled_patches << :logger # required — activates the Logger patch
|
|
131
|
+
|
|
132
|
+
# Optional: filter by severity
|
|
133
|
+
config.std_lib_logger_filter = proc do |logger, message, severity|
|
|
134
|
+
[:error, :fatal].include?(severity)
|
|
135
|
+
end
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Rails Logger
|
|
139
|
+
|
|
140
|
+
In Rails, `Rails.logger` writes automatically appear as breadcrumbs when
|
|
141
|
+
`:active_support_logger` is enabled — no extra configuration needed.
|
|
142
|
+
|
|
143
|
+
To also send key Rails log lines as Sentry Logs (not just breadcrumbs), call
|
|
144
|
+
`Sentry.logger` explicitly alongside your existing logging:
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
Rails.logger.error("Payment failed: #{e.message}")
|
|
148
|
+
Sentry.logger.error("Payment failed: %{message}", message: e.message)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Best Practices
|
|
152
|
+
|
|
153
|
+
- Always use parameterized messages (`%{key}` syntax) rather than string interpolation —
|
|
154
|
+
this enables structured log aggregation and search in Sentry
|
|
155
|
+
- Use `Sentry.logger` for observability-grade messages (errors, key business events);
|
|
156
|
+
let high-volume debug logging stay local
|
|
157
|
+
- Set `before_send_log` to drop `:trace` and `:debug` levels in production
|
|
158
|
+
- Combine `Sentry.logger.error(...)` with `Sentry.capture_exception(e)` for errors — the
|
|
159
|
+
log provides context, the exception provides the stack trace
|
|
160
|
+
|
|
161
|
+
## Troubleshooting
|
|
162
|
+
|
|
163
|
+
| Issue | Solution |
|
|
164
|
+
| ---------------------------------- | ----------------------------------------------------------------------------------------- |
|
|
165
|
+
| Logs not appearing in Sentry | Set `config.enable_logs = true`; verify `sentry-ruby` ≥ 5.27.0 |
|
|
166
|
+
| Breadcrumbs not attached to events | Check `breadcrumbs_logger` includes the right symbol for your stack |
|
|
167
|
+
| `Sentry.logger` call crashes | Ensure `Sentry.init` was called before `Sentry.logger` is accessed |
|
|
168
|
+
| High log volume | Use `before_send_log` to filter by level; set `:debug` and `:trace` to drop in production |
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Metrics — Sentry Ruby SDK
|
|
2
|
+
|
|
3
|
+
> Minimum SDK: `sentry-ruby` v6.3.0+ Metrics are enabled by default
|
|
4
|
+
> (`config.enable_metrics = true`). The v6.3.0 release replaced the beta `increment` API
|
|
5
|
+
> with `count`.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [Configuration](#configuration)
|
|
10
|
+
- [Metric Types](#metric-types)
|
|
11
|
+
- [Unit Reference](#unit-reference)
|
|
12
|
+
- [Sidekiq Metrics](#sidekiq-metrics)
|
|
13
|
+
- [Detecting Existing Metric Patterns](#detecting-existing-metric-patterns)
|
|
14
|
+
- [`before_send_metric` Hook](#before_send_metric-hook)
|
|
15
|
+
- [Best Practices](#best-practices)
|
|
16
|
+
- [Troubleshooting](#troubleshooting)
|
|
17
|
+
|
|
18
|
+
## Configuration
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
Sentry.init do |config|
|
|
22
|
+
config.dsn = ENV["SENTRY_DSN"]
|
|
23
|
+
# Metrics on by default. To filter or enrich before sending:
|
|
24
|
+
config.before_send_metric = lambda do |metric|
|
|
25
|
+
return nil if metric.name.start_with?("internal.")
|
|
26
|
+
metric.attributes[:environment] ||= Rails.env
|
|
27
|
+
metric
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Metric Types
|
|
33
|
+
|
|
34
|
+
### Counter — occurrence counts
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
Sentry.metrics.count("api.requests", attributes: { endpoint: "/orders", status: "200" })
|
|
38
|
+
Sentry.metrics.count("user.signup", attributes: { plan: "pro" })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Gauge — current value (can go up or down)
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
Sentry.metrics.gauge("sidekiq.queue.depth", Sidekiq::Stats.new.enqueued)
|
|
45
|
+
Sentry.metrics.gauge("cache.size", Rails.cache.stats[:curr_items])
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Distribution — statistical spread of a value
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
Sentry.metrics.distribution("http.response_time", duration_ms, unit: "millisecond",
|
|
52
|
+
attributes: { route: "/api/orders" })
|
|
53
|
+
Sentry.metrics.distribution("db.query_time", query_ms, unit: "millisecond",
|
|
54
|
+
attributes: { table: "orders" })
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Unit Reference
|
|
58
|
+
|
|
59
|
+
| Category | Values |
|
|
60
|
+
| --------- | ---------------------------------------------------------------------------------- |
|
|
61
|
+
| Duration | `"nanosecond"`, `"microsecond"`, `"millisecond"`, `"second"`, `"minute"`, `"hour"` |
|
|
62
|
+
| Data | `"byte"`, `"kilobyte"`, `"megabyte"`, `"gigabyte"` |
|
|
63
|
+
| Fractions | `"ratio"`, `"percent"` |
|
|
64
|
+
| None | `"none"` (default) |
|
|
65
|
+
|
|
66
|
+
## Sidekiq Metrics
|
|
67
|
+
|
|
68
|
+
Two complementary approaches cover different aspects of Sidekiq observability:
|
|
69
|
+
|
|
70
|
+
### Option A — Server middleware (per-job metrics)
|
|
71
|
+
|
|
72
|
+
A Sidekiq server middleware fires for every job execution — the right tool for job
|
|
73
|
+
duration, throughput, and error rate broken down by queue and worker class.
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
# lib/sentry_job_metrics.rb
|
|
77
|
+
class SentryJobMetrics
|
|
78
|
+
def call(worker, job, queue)
|
|
79
|
+
start = Time.now
|
|
80
|
+
yield
|
|
81
|
+
attrs = { queue: queue, worker: worker.class.name }
|
|
82
|
+
Sentry.metrics.distribution("sidekiq.job.duration",
|
|
83
|
+
(Time.now - start) * 1000, unit: "millisecond", attributes: attrs)
|
|
84
|
+
Sentry.metrics.count("sidekiq.job.success", attributes: attrs)
|
|
85
|
+
rescue => e
|
|
86
|
+
Sentry.metrics.count("sidekiq.job.failure",
|
|
87
|
+
attributes: { queue: queue, worker: worker.class.name })
|
|
88
|
+
raise
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# config/initializers/sidekiq.rb
|
|
93
|
+
Sidekiq.configure_server do |config|
|
|
94
|
+
config.server_middleware do |chain|
|
|
95
|
+
chain.add SentryJobMetrics
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**What this gives you:** `sidekiq.job.duration` (p50/p95/p99 per queue + worker),
|
|
101
|
+
`sidekiq.job.success` and `sidekiq.job.failure` counters.
|
|
102
|
+
|
|
103
|
+
**What it cannot give you:** queue depth, queue latency (oldest job age), retry/dead
|
|
104
|
+
queue sizes — these are aggregate stats that require polling `Sidekiq::Stats`.
|
|
105
|
+
|
|
106
|
+
### Option B — Aggregate queue stats (periodic sampling)
|
|
107
|
+
|
|
108
|
+
For queue depth and latency, poll `Sidekiq::Stats` on a schedule.
|
|
109
|
+
A lightweight background thread or a recurring Sidekiq job both work:
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
# config/initializers/sentry_sidekiq_stats.rb
|
|
113
|
+
Thread.new do
|
|
114
|
+
loop do
|
|
115
|
+
begin
|
|
116
|
+
stats = Sidekiq::Stats.new
|
|
117
|
+
Sentry.metrics.gauge("sidekiq.enqueued", stats.enqueued)
|
|
118
|
+
Sentry.metrics.gauge("sidekiq.retries", stats.retry_size)
|
|
119
|
+
Sentry.metrics.gauge("sidekiq.dead", stats.dead_size)
|
|
120
|
+
|
|
121
|
+
Sidekiq::Queue.all.first(10).each do |q|
|
|
122
|
+
attrs = { queue: q.name }
|
|
123
|
+
Sentry.metrics.gauge("sidekiq.queue.depth", q.size, attributes: attrs)
|
|
124
|
+
Sentry.metrics.gauge("sidekiq.queue.latency", q.latency,
|
|
125
|
+
unit: "second", attributes: attrs)
|
|
126
|
+
end
|
|
127
|
+
rescue => e
|
|
128
|
+
# don't crash the thread on transient Redis errors
|
|
129
|
+
end
|
|
130
|
+
sleep 30
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
> **Production note:** In forking servers (Puma, Unicorn), start the polling thread in
|
|
136
|
+
> `on_worker_boot` / `after_fork` — threads don’t survive `fork()`. Consider using a
|
|
137
|
+
> Sidekiq periodic job instead of a bare thread for better reliability and error
|
|
138
|
+
> visibility.
|
|
139
|
+
|
|
140
|
+
**Use both together** for complete Sidekiq visibility: the middleware captures per-job
|
|
141
|
+
detail, the poller captures queue health over time.
|
|
142
|
+
|
|
143
|
+
## Detecting Existing Metric Patterns
|
|
144
|
+
|
|
145
|
+
Before adding Sentry metrics, scan for existing instrumentation to migrate or
|
|
146
|
+
complement:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# StatsD / Datadog / Prometheus calls
|
|
150
|
+
grep -rE "(statsd|dogstatsd|prometheus|\.gauge|\.distribution|\.histogram|\.increment|\.timing)" \
|
|
151
|
+
app/ lib/ --include="*.rb" | grep -v "_spec\|_test"
|
|
152
|
+
|
|
153
|
+
# Sidekiq::Stats usage (shows what's already being tracked)
|
|
154
|
+
grep -rn "Sidekiq::Stats\|Sidekiq::Queue" app/ lib/ --include="*.rb"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## `before_send_metric` Hook
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
config.before_send_metric = lambda do |metric|
|
|
161
|
+
return nil if metric.name.start_with?("internal.")
|
|
162
|
+
metric.attributes.delete(:user_id) # strip PII
|
|
163
|
+
metric
|
|
164
|
+
end
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`MetricEvent` properties:
|
|
168
|
+
|
|
169
|
+
| Property | Type | Description |
|
|
170
|
+
| ------------ | --------- | ---------------------------------------- |
|
|
171
|
+
| `name` | `String` | Metric identifier |
|
|
172
|
+
| `type` | `Symbol` | `:counter`, `:gauge`, or `:distribution` |
|
|
173
|
+
| `value` | `Numeric` | Measurement value |
|
|
174
|
+
| `unit` | `String?` | Measurement unit |
|
|
175
|
+
| `attributes` | `Hash` | Custom key-value pairs |
|
|
176
|
+
| `trace_id` | `String?` | Auto-linked when inside a transaction |
|
|
177
|
+
|
|
178
|
+
## Best Practices
|
|
179
|
+
|
|
180
|
+
- Use `count` for events, `gauge` for current state, `distribution` for latency/sizes
|
|
181
|
+
- Always set `unit:` on distributions — enables proper chart rendering
|
|
182
|
+
- Use `attributes:` to slice by queue name, route, status code — these become filter
|
|
183
|
+
dimensions
|
|
184
|
+
- Use `before_send_metric` to strip PII (user IDs, email addresses) from attribute
|
|
185
|
+
values
|
|
186
|
+
- Metrics emitted inside a Sentry transaction are trace-linked automatically
|
|
187
|
+
|
|
188
|
+
## Troubleshooting
|
|
189
|
+
|
|
190
|
+
| Issue | Solution |
|
|
191
|
+
| ---------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
192
|
+
| Metrics not in Sentry | Verify `enable_metrics` is not `false`; check DSN |
|
|
193
|
+
| `count` values look wrong | Sentry diffs lifetime counters — reporting deltas directly avoids confusion |
|
|
194
|
+
| `before_send_metric` not filtering | Return `nil`, not `false`, to drop a metric |
|
|
195
|
+
| Per-job breakdown missing | Ensure `SentryJobMetrics` middleware is added to `server_middleware`, not `client_middleware` |
|
|
196
|
+
| Queue depth always zero | Verify the stats polling thread is running; check Redis connectivity |
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Migrating to Sentry — Ruby SDK
|
|
2
|
+
|
|
3
|
+
> Minimum SDK: `sentry-ruby` v5.0.0+ (Rails: also add `sentry-rails`) Covers migrations
|
|
4
|
+
> from: AppSignal, Honeybadger, Bugsnag, Rollbar, Airbrake
|
|
5
|
+
|
|
6
|
+
## Contents
|
|
7
|
+
|
|
8
|
+
- [Step 1: Detect What’s in the Codebase](#step-1-detect-whats-in-the-codebase)
|
|
9
|
+
- [AppSignal → Sentry](#appsignal--sentry)
|
|
10
|
+
- [Honeybadger → Sentry](#honeybadger--sentry)
|
|
11
|
+
- [Bugsnag → Sentry](#bugsnag--sentry)
|
|
12
|
+
- [Rollbar → Sentry](#rollbar--sentry)
|
|
13
|
+
- [Airbrake → Sentry](#airbrake--sentry)
|
|
14
|
+
- [Universal Migration Checklist](#universal-migration-checklist)
|
|
15
|
+
- [Troubleshooting](#troubleshooting)
|
|
16
|
+
|
|
17
|
+
## Step 1: Detect What’s in the Codebase
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Find competitor gems
|
|
21
|
+
grep -iE '\bappsignal\b|\bhoneybadger\b|\bbugsnag\b|\brollbar\b|\bairbrake\b' Gemfile Gemfile.lock 2>/dev/null
|
|
22
|
+
|
|
23
|
+
# Find call sites across the app
|
|
24
|
+
grep -rn "Appsignal\.\|Honeybadger\.\|Bugsnag\.\|Rollbar\.\|Airbrake\." \
|
|
25
|
+
app/ lib/ config/ --include="*.rb" | grep -v "_spec\|_test"
|
|
26
|
+
|
|
27
|
+
# Find config files to remove after migration
|
|
28
|
+
ls config/appsignal.yml \
|
|
29
|
+
config/honeybadger.yml .honeybadger.yml \
|
|
30
|
+
config/initializers/bugsnag.rb \
|
|
31
|
+
config/initializers/rollbar.rb \
|
|
32
|
+
config/initializers/airbrake.rb 2>/dev/null
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## AppSignal → Sentry
|
|
38
|
+
|
|
39
|
+
**Gemfile:**
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
# Remove:
|
|
43
|
+
gem "appsignal"
|
|
44
|
+
|
|
45
|
+
# Add:
|
|
46
|
+
gem "sentry-ruby"
|
|
47
|
+
gem "sentry-rails" # if Rails
|
|
48
|
+
gem "sentry-sidekiq" # if Sidekiq
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Delete:** `config/appsignal.yml`, `config/initializers/appsignal.rb`
|
|
52
|
+
|
|
53
|
+
### API mapping
|
|
54
|
+
|
|
55
|
+
| AppSignal | Sentry |
|
|
56
|
+
| --------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
57
|
+
| `Appsignal.report_error(e)` | `Sentry.capture_exception(e)` |
|
|
58
|
+
| `Appsignal.send_error(e)` | `Sentry.capture_exception(e)` |
|
|
59
|
+
| `Appsignal.set_error(e)` | `Sentry.capture_exception(e)` |
|
|
60
|
+
| `Appsignal.listen_for_error { }` | `begin … rescue => e; Sentry.capture_exception(e); raise; end` |
|
|
61
|
+
| `Appsignal.tag_request(key: val)` | `Sentry.set_tags(key: val)` |
|
|
62
|
+
| `Appsignal.add_tags(key: val)` | `Sentry.set_tags(key: val)` |
|
|
63
|
+
| `Appsignal.add_custom_data(hash)` | `Sentry.set_context("custom", hash)` |
|
|
64
|
+
| `Appsignal.set_action("name")` | `Sentry.get_current_scope.set_transaction_name("name")` |
|
|
65
|
+
| `Appsignal.add_breadcrumb(cat, action, msg)` | `Sentry.add_breadcrumb(Sentry::Breadcrumb.new(category: cat, message: msg))` |
|
|
66
|
+
| `Appsignal.instrument("name") { }` | `Sentry.with_child_span(op: "name") { }` |
|
|
67
|
+
| `Appsignal.set_gauge("m", val, tags)` | `Sentry.metrics.gauge("m", val, attributes: tags)` |
|
|
68
|
+
| `Appsignal.increment_counter("m", val, tags)` | `Sentry.metrics.count("m", value: val, attributes: tags)` |
|
|
69
|
+
|
|
70
|
+
### Find call sites
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
grep -rn "Appsignal\.\(report_error\|send_error\|set_error\|listen_for_error\|tag_request\|add_tags\|add_custom_data\|instrument\|set_gauge\|increment_counter\)" \
|
|
74
|
+
app/ lib/ --include="*.rb"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Initializer
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
# config/initializers/sentry.rb
|
|
81
|
+
Sentry.init do |config|
|
|
82
|
+
config.dsn = ENV["SENTRY_DSN"]
|
|
83
|
+
config.breadcrumbs_logger = [:active_support_logger, :http_logger]
|
|
84
|
+
config.send_default_pii = true
|
|
85
|
+
config.traces_sample_rate = 1.0
|
|
86
|
+
config.enable_logs = true
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Honeybadger → Sentry
|
|
93
|
+
|
|
94
|
+
**Gemfile:**
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
# Remove:
|
|
98
|
+
gem "honeybadger"
|
|
99
|
+
|
|
100
|
+
# Add:
|
|
101
|
+
gem "sentry-ruby"
|
|
102
|
+
gem "sentry-rails"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Delete:** `config/honeybadger.yml`, `.honeybadger.yml`,
|
|
106
|
+
`config/initializers/honeybadger.rb`
|
|
107
|
+
|
|
108
|
+
### API mapping
|
|
109
|
+
|
|
110
|
+
| Honeybadger | Sentry |
|
|
111
|
+
| ----------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
112
|
+
| `Honeybadger.notify(e)` | `Sentry.capture_exception(e)` |
|
|
113
|
+
| `Honeybadger.notify("message")` | `Sentry.capture_message("message")` |
|
|
114
|
+
| `Honeybadger.notify(e, context: hash)` | `Sentry.with_scope { \|s\| s.set_context("ctx", hash); Sentry.capture_exception(e) }` |
|
|
115
|
+
| `Honeybadger.context(key: val)` | `Sentry.set_tags(key: val)` |
|
|
116
|
+
| `Honeybadger.context { \|c\| c[:key] = val }` | `Sentry.configure_scope { \|s\| s.set_context("app", {key: val}) }` |
|
|
117
|
+
| `Honeybadger.context.clear!` | `Sentry.get_current_scope.clear` |
|
|
118
|
+
| `Honeybadger.add_breadcrumb(msg, metadata: h)` | `Sentry.add_breadcrumb(Sentry::Breadcrumb.new(message: msg, data: h))` |
|
|
119
|
+
| `Honeybadger.exception_filter { \|n\| n.halt! if … }` | `config.before_send = lambda { \|e, _h\| … ? nil : e }` |
|
|
120
|
+
|
|
121
|
+
### Find call sites
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
grep -rn "Honeybadger\.\(notify\|context\|add_breadcrumb\|exception_filter\)" \
|
|
125
|
+
app/ lib/ --include="*.rb"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Bugsnag → Sentry
|
|
131
|
+
|
|
132
|
+
**Gemfile:**
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
# Remove:
|
|
136
|
+
gem "bugsnag"
|
|
137
|
+
|
|
138
|
+
# Add:
|
|
139
|
+
gem "sentry-ruby"
|
|
140
|
+
gem "sentry-rails" # if Rails
|
|
141
|
+
gem "sentry-sidekiq" # if Sidekiq
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Delete:** `config/initializers/bugsnag.rb`
|
|
145
|
+
|
|
146
|
+
### API mapping
|
|
147
|
+
|
|
148
|
+
| Bugsnag | Sentry |
|
|
149
|
+
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
150
|
+
| `Bugsnag.notify(e)` | `Sentry.capture_exception(e)` |
|
|
151
|
+
| `Bugsnag.notify(e) { \|event\| event.severity = "warning" }` | `Sentry.capture_exception(e, level: :warning)` |
|
|
152
|
+
| `Bugsnag.notify(e) { \|event\| event.add_metadata(:ctx, hash) }` | `Sentry.with_scope { \|s\| s.set_context("ctx", hash); Sentry.capture_exception(e) }` |
|
|
153
|
+
| `Bugsnag.notify(e) { \|event\| event.set_user(id, email, name) }` | `Sentry.set_user(id: id, email: email, username: name)` |
|
|
154
|
+
| `Bugsnag.leave_breadcrumb(name, meta, type)` | `Sentry.add_breadcrumb(Sentry::Breadcrumb.new(message: name, data: meta, category: type))` |
|
|
155
|
+
| `Bugsnag.add_metadata(:section, hash)` | `Sentry.set_context("section", hash)` |
|
|
156
|
+
| `Bugsnag.configure { \|c\| c.discard_classes << "MyError" }` | `config.before_send = lambda { \|e, h\| h[:exception].is_a?(MyError) ? nil : e }` |
|
|
157
|
+
| `event.ignore!` (in on_error callback) | Return `nil` from `config.before_send` |
|
|
158
|
+
|
|
159
|
+
### Find call sites
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
grep -rn "Bugsnag\.\(notify\|leave_breadcrumb\|add_metadata\|clear_metadata\|start_session\)" \
|
|
163
|
+
app/ lib/ --include="*.rb"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Rollbar → Sentry
|
|
169
|
+
|
|
170
|
+
**Gemfile:**
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
# Remove:
|
|
174
|
+
gem "rollbar"
|
|
175
|
+
|
|
176
|
+
# Add:
|
|
177
|
+
gem "sentry-ruby"
|
|
178
|
+
gem "sentry-rails" # if Rails
|
|
179
|
+
gem "sentry-sidekiq" # if Sidekiq
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Delete:** `config/initializers/rollbar.rb`
|
|
183
|
+
|
|
184
|
+
### API mapping
|
|
185
|
+
|
|
186
|
+
| Rollbar | Sentry |
|
|
187
|
+
| ------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
188
|
+
| `Rollbar.error(e)` | `Sentry.capture_exception(e)` |
|
|
189
|
+
| `Rollbar.warning(msg)` | `Sentry.capture_message(msg, level: :warning)` |
|
|
190
|
+
| `Rollbar.info(msg, extra)` | `Sentry.with_scope { \|s\| s.set_context("extra", extra); Sentry.capture_message(msg, level: :info) }` |
|
|
191
|
+
| `Rollbar.critical(e)` | `Sentry.capture_exception(e, level: :fatal)` |
|
|
192
|
+
| `Rollbar.debug(msg)` | `Sentry.capture_message(msg, level: :debug)` |
|
|
193
|
+
| `Rollbar.log(level, e)` | `Sentry.capture_exception(e, level: { "critical" => :fatal }.fetch(level, level.to_sym))` |
|
|
194
|
+
| `Rollbar.scoped(person: p) { }` | `Sentry.with_scope { \|s\| s.set_user(p); ... }` |
|
|
195
|
+
| `Rollbar.scope!(person: p)` | `Sentry.set_user(p)` |
|
|
196
|
+
| `Rollbar.silenced { }` | `# remove — no Sentry equivalent needed` |
|
|
197
|
+
|
|
198
|
+
Rollbar uses `'warning'` level; Sentry uses `:warning`. Rollbar uses `'critical'`; map
|
|
199
|
+
to Sentry’s `:fatal`.
|
|
200
|
+
|
|
201
|
+
### Find call sites
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
grep -rn "Rollbar\.\(error\|warning\|warn\|info\|debug\|critical\|log\|scoped\|scope\)" \
|
|
205
|
+
app/ lib/ --include="*.rb"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Airbrake → Sentry
|
|
211
|
+
|
|
212
|
+
**Gemfile:**
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
# Remove:
|
|
216
|
+
gem "airbrake"
|
|
217
|
+
gem "airbrake-ruby" # if present separately
|
|
218
|
+
|
|
219
|
+
# Add:
|
|
220
|
+
gem "sentry-ruby"
|
|
221
|
+
gem "sentry-rails" # if Rails
|
|
222
|
+
gem "sentry-sidekiq" # if Sidekiq
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Delete:** `config/initializers/airbrake.rb`
|
|
226
|
+
|
|
227
|
+
Also check for and remove: `require 'airbrake/capistrano'` in `Capfile`,
|
|
228
|
+
`require 'airbrake/rake'` in `Rakefile`, and any Sidekiq/DelayedJob/Resque middleware
|
|
229
|
+
references.
|
|
230
|
+
|
|
231
|
+
### API mapping
|
|
232
|
+
|
|
233
|
+
| Airbrake | Sentry |
|
|
234
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------ |
|
|
235
|
+
| `Airbrake.notify(e)` | `Sentry.capture_exception(e)` |
|
|
236
|
+
| `Airbrake.notify(e, params)` | `Sentry.with_scope { \|s\| s.set_context("params", params); Sentry.capture_exception(e) }` |
|
|
237
|
+
| `Airbrake.notify_sync(e)` | `Sentry.capture_exception(e)` (Sentry handles delivery asynchronously) |
|
|
238
|
+
| `Airbrake.notify("message")` | `Sentry.capture_message("message")` |
|
|
239
|
+
| `Airbrake.merge_context(hash)` | `Sentry.set_context("app", hash)` |
|
|
240
|
+
| `Airbrake.add_filter { \|n\| n.ignore! if ... }` | `config.before_send = lambda { \|e, _h\| ... ? nil : e }` |
|
|
241
|
+
| `Airbrake.add_filter(MyFilter)` | `config.before_send = lambda { \|e, _h\| ... }` |
|
|
242
|
+
| `notice[:context][:user_id] = id` | `Sentry.set_user(id: id)` |
|
|
243
|
+
| `Airbrake.notify_deploy(info)` | Use Sentry release tracking via `SENTRY_RELEASE` env var |
|
|
244
|
+
| `Airbrake.notify_request(...)` | Automatic via `sentry-rails` tracing |
|
|
245
|
+
| `Airbrake.notify_query(...)` | Automatic via `sentry-rails` ActiveRecord spans |
|
|
246
|
+
|
|
247
|
+
### Find call sites
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
grep -rn "Airbrake\.\(notify\|notify_sync\|merge_context\|add_filter\|notify_request\|notify_query\)" \
|
|
251
|
+
app/ lib/ --include="*.rb"
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Universal Migration Checklist
|
|
257
|
+
|
|
258
|
+
Works for any tool not covered above:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Error capture
|
|
262
|
+
grep -rn "\.\(notify\|report_error\|send_error\|notice_error\)" \
|
|
263
|
+
app/ lib/ --include="*.rb" | grep -v "_spec\|_test"
|
|
264
|
+
|
|
265
|
+
# Context / tagging
|
|
266
|
+
grep -rn "\.\(context\|tag_request\|add_tags\|add_custom_attributes\)" \
|
|
267
|
+
app/ lib/ --include="*.rb" | grep -v "_spec\|_test"
|
|
268
|
+
|
|
269
|
+
# Custom spans / instrumentation
|
|
270
|
+
grep -rn "\.\(instrument\|monitor\|in_transaction\)" \
|
|
271
|
+
app/ lib/ --include="*.rb" | grep -v "_spec\|_test"
|
|
272
|
+
|
|
273
|
+
# Metric calls
|
|
274
|
+
grep -rn "\.\(set_gauge\|increment_counter\|record_metric\|gauge\|histogram\|timing\)" \
|
|
275
|
+
app/ lib/ --include="*.rb" | grep -v "_spec\|_test"
|
|
276
|
+
|
|
277
|
+
# Environment variables to update
|
|
278
|
+
grep -rn "APPSIGNAL\|HONEYBADGER\|BUGSNAG\|ROLLBAR\|AIRBRAKE" \
|
|
279
|
+
.env .env.* config/ --include="*.rb" --include="*.yml" 2>/dev/null
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Environment variable mapping
|
|
283
|
+
|
|
284
|
+
| Tool | Old env var | Sentry |
|
|
285
|
+
| ----------- | ---------------------------------------------- | ------------ |
|
|
286
|
+
| AppSignal | `APPSIGNAL_PUSH_API_KEY` | `SENTRY_DSN` |
|
|
287
|
+
| Honeybadger | `HONEYBADGER_API_KEY` | `SENTRY_DSN` |
|
|
288
|
+
| Bugsnag | `BUGSNAG_API_KEY` | `SENTRY_DSN` |
|
|
289
|
+
| Rollbar | `ROLLBAR_ACCESS_TOKEN` | `SENTRY_DSN` |
|
|
290
|
+
| Airbrake | `AIRBRAKE_PROJECT_ID` + `AIRBRAKE_PROJECT_KEY` | `SENTRY_DSN` |
|
|
291
|
+
|
|
292
|
+
### Rollout strategy
|
|
293
|
+
|
|
294
|
+
Run both tools in parallel for one release cycle, then remove the old gem once Sentry is
|
|
295
|
+
receiving events in production.
|
|
296
|
+
|
|
297
|
+
```ruby
|
|
298
|
+
# Temporary dual-capture shim — remove after rollout validation:
|
|
299
|
+
module ErrorCapture
|
|
300
|
+
def self.capture(exception, context: {})
|
|
301
|
+
Sentry.with_scope do |scope|
|
|
302
|
+
scope.set_context("extra", context) unless context.empty?
|
|
303
|
+
Sentry.capture_exception(exception)
|
|
304
|
+
end
|
|
305
|
+
begin
|
|
306
|
+
OldTool.notify(exception) # replace OldTool with actual constant
|
|
307
|
+
rescue => e
|
|
308
|
+
Sentry.logger.warn("OldTool capture failed: %{message}", message: e.message)
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Troubleshooting
|
|
315
|
+
|
|
316
|
+
| Issue | Solution |
|
|
317
|
+
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
|
|
318
|
+
| Missing errors after migration | Ensure `sentry-rails` is present — `sentry-ruby` alone doesn’t hook Rails error handlers |
|
|
319
|
+
| Context missing from events | Old tools often set context via middleware; replicate with a `before_action` calling `Sentry.set_user` / `Sentry.set_tags` |
|
|
320
|
+
| Old gem still loading | Check `Gemfile.lock` — it may be a transitive dependency |
|
|
321
|
+
| Distributed traces broken | Ensure all services have migrated and propagate `sentry-trace` + `baggage` headers |
|