SKILL.md
$27
Run these commands to understand the project before making any recommendations:
# Check existing Sentry dependency
grep -i sentry mix.exs 2>/dev/null
# Detect Elixir version
cat .tool-versions 2>/dev/null | grep elixir
grep "elixir:" mix.exs 2>/dev/null
# Detect Phoenix or Plug
grep -E '"phoenix"|"plug"' mix.exs 2>/dev/null
# Detect Phoenix LiveView
grep "phoenix_live_view" mix.exs 2>/dev/null
# Detect Oban (job queue / crons)
grep "oban" mix.exs 2>/dev/null
# Detect Quantum (cron scheduler)
grep "quantum" mix.exs 2>/dev/null
# Detect OpenTelemetry usage
grep "opentelemetry" mix.exs 2>/dev/null
# Check for companion frontend
ls assets/ frontend/ web/ client/ 2>/dev/null
What to note:
Signal
Impact
sentry already in mix.exs?
Skip install; go to Phase 2 (configure features)
Phoenix detected?
Add Sentry.PlugCapture, Sentry.PlugContext, optionally Sentry.LiveViewHook
LiveView detected?
Add Sentry.LiveViewHook to the live_view macro in my_app_web.ex
Oban detected?
Recommend Crons + error capture via Oban integration
Quantum detected?
Recommend Crons via Quantum integration
OpenTelemetry already present?
Tracing setup only needs Sentry.OpenTelemetry.* config
Frontend directory found?
Trigger Phase 4 cross-link suggestion
Phase 2: Recommend
Based on what you found, present a concrete recommendation. Don't ask open-ended questions — lead with a proposal:
Recommended (core coverage):
- ✅ Error Monitoring — always; captures exceptions and crash reports
- ✅ Logging —
Sentry.LoggerHandlerforwards crash reports and error logs to Sentry
- ✅ Tracing — if Phoenix, Plug, or Ecto detected (via OpenTelemetry)
Optional (enhanced observability):
- ⚡ Crons — detect silent failures in scheduled jobs (Oban, Quantum, or manual GenServer)
- ⚡ Sentry Logs — forward structured logs to Sentry Logs Protocol (sentry v12.0.0+)
Recommendation logic:
Feature
Recommend when...
Error Monitoring
Always — non-negotiable baseline
Logging
Always — LoggerHandler captures crashes that aren't explicit capture_exception calls
Tracing
Phoenix, Plug, Ecto, or OpenTelemetry imports detected
Crons
Oban, Quantum, or periodic GenServer/Task patterns detected
Sentry Logs
sentry v12.0.0+ in use and structured log search is needed
Propose: "I recommend setting up Error Monitoring + Logging [+ Tracing if Phoenix/Ecto detected]. Want me to also add Crons or Sentry Logs?"
Phase 3: Guide
Option 1: Igniter Installer (Recommended)
You need to run this yourself — the Igniter installer requires interactive terminal input that the agent can't handle. Copy-paste into your terminal:
mix igniter.install sentry
Available since sentry v11.0.0. It auto-configures config/config.exs, config/prod.exs, config/runtime.exs, and lib/my_app/application.ex.
Once it finishes, come back and skip to [Verification](#verification).
If the user skips the Igniter installer, proceed with Option 2 (Manual Setup) below.
Option 2: Manual Setup
#### Install
Add to mix.exs dependencies:
# mix.exs
defp deps do
[
{:sentry, "~> 12.0"},
{:finch, "~> 0.21"}
# Add jason if using Elixir < 1.18:
# {:jason, "~> 1.4"},
]
end
mix deps.get
#### Configure
# config/config.exs
config :sentry,
dsn: System.get_env("SENTRY_DSN"),
environment_name: config_env(),
enable_source_code_context: true,
root_source_code_paths: [File.cwd!()],
in_app_otp_apps: [:my_app]
For runtime configuration (recommended for DSN and release):
# config/runtime.exs
import Config
config :sentry,
dsn: System.fetch_env!("SENTRY_DSN"),
release: System.get_env("SENTRY_RELEASE", "my-app@#{Application.spec(:my_app, :vsn)}")
#### Quick Start — Recommended Init Config
This config enables the most features with sensible defaults:
# config/config.exs
config :sentry,
dsn: System.get_env("SENTRY_DSN"),
environment_name: config_env(),
enable_source_code_context: true,
root_source_code_paths: [File.cwd!()],
in_app_otp_apps: [:my_app],
# Logger handler config — captures crash reports
logger: [
{:handler, :sentry_handler, Sentry.LoggerHandler, %{
config: %{
metadata: [:request_id],
capture_log_messages: true,
level: :error
}
}}
]
#### Activate Logger Handler
Add Logger.add_handlers/1 in Application.start/2:
# lib/my_app/application.ex
def start(_type, _args) do
Logger.add_handlers(:my_app) # activates the :sentry_handler configured above
children = [
MyAppWeb.Endpoint
# ... other children
]
Supervisor.start_link(children, strategy: :one_for_one)
end
#### Phoenix Integration
**lib/my_app_web/endpoint.ex**
defmodule MyAppWeb.Endpoint do
use Sentry.PlugCapture # Add ABOVE use Phoenix.Endpoint (Cowboy adapter only)
use Phoenix.Endpoint, otp_app: :my_app
# ...
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Phoenix.json_library()
plug Sentry.PlugContext # Add BELOW Plug.Parsers
# ...
end
Note: Sentry.PlugCapture is only needed for the Cowboy adapter. Phoenix 1.7+ defaults to Bandit, where PlugCapture is harmless but unnecessary. Sentry.PlugContext is always recommended — it enriches events with HTTP request data.
**LiveView errors — lib/my_app_web.ex**
def live_view do
quote do
use Phoenix.LiveView
on_mount Sentry.LiveViewHook # captures errors in mount/handle_event/handle_info
end
end
#### Plain Plug Application
defmodule MyApp.Router do
use Plug.Router
use Sentry.PlugCapture # Cowboy only
plug Plug.Parsers, parsers: [:urlencoded, :multipart]
plug Sentry.PlugContext
# ...
end
For Each Agreed Feature
Walk through features one at a time. Load the reference file for each, follow its steps, and verify before moving to the next:
Feature
Reference file
Load when...
Error Monitoring
${SKILL_ROOT}/references/error-monitoring.md
Always (baseline)
Tracing
${SKILL_ROOT}/references/tracing.md
Phoenix / Ecto / OpenTelemetry detected
Logging
${SKILL_ROOT}/references/logging.md
LoggerHandler or Sentry Logs setup
Crons
${SKILL_ROOT}/references/crons.md
Oban, Quantum, or periodic jobs detected
For each feature: Read ${SKILL_ROOT}/references/<feature>.md, follow steps exactly, verify it works.
Configuration Reference
Key Config Options
Option
Type
Default
Purpose
:dsn
string | nil
nil
SDK disabled if nil; env: SENTRY_DSN
:environment_name
atom | string
"production"
e.g., :prod; env: SENTRY_ENVIRONMENT
:release
string | nil
nil
e.g., "my-app@1.0.0"; env: SENTRY_RELEASE
:sample_rate
float
1.0
Error event sample rate (0.0–1.0)
:enable_source_code_context
boolean
false
Include source lines around errors
:root_source_code_paths
[path]
[]
Required when source context is enabled
:in_app_otp_apps
[atom]
[]
OTP apps whose modules are "in-app" in stacktraces
:before_send
(event -> event | nil) | {m, f}
nil
Hook to mutate or drop error events
:after_send_event
(event, result -> any) | {m, f}
nil
Hook called after event is sent
:filter
module
Sentry.DefaultEventFilter
Module implementing Sentry.EventFilter
:max_breadcrumbs
integer
100
Max breadcrumbs per process
:dedup_events
boolean
true
Deduplicate identical events within ~30 seconds
:tags
map
%{}
Global tags sent with every event
:traces_sample_rate
float | nil
nil
Non-nil enables tracing (requires OTel setup)
:traces_sampler
fn | {m, f} | nil
nil
Custom per-transaction sampling
:enable_logs
boolean
false
Enable Sentry Logs Protocol (v12.0.0+)
:test_mode
boolean
false
Capture events in-memory for testing
Default PII Guidance
Most Sentry SDKs expose a send-default-PII option. As of sentry v12, the Elixir SDK does not expose a send_default_pii config option in its documented option list or current config schema, so do not add a non-existent option. For richer user context, use Sentry.PlugContext and explicitly set allowed fields with Sentry.Context.set_user_context/1, then scrub with :before_send if needed. If a future Elixir SDK release adds send_default_pii, recommend setting it.
Environment Variables
Variable
Maps to
Purpose
SENTRY_DSN
:dsn
Data Source Name
SENTRY_RELEASE
:release
App version (e.g., my-app@1.0.0)
SENTRY_ENVIRONMENT
:environment_name
Deployment environment
Verification
Test that Sentry is receiving events:
# Send a test event from your project
MIX_ENV=dev mix sentry.send_test_event
Or add a temporary call in a controller action:
# Temporary test — remove after confirming
def index(conn, _params) do
Sentry.capture_message("Sentry Elixir SDK test event")
text(conn, "sent")
end
Check the Sentry dashboard within a few seconds. If nothing appears:
- Set
config :sentry, log_level: :debugfor verbose SDK output
- Verify
SENTRY_DSNis set and the project exists
- Confirm
:environment_nameis not set to a value Sentry filters in your alert rules
Phase 4: Cross-Link
After completing Elixir setup, check for a companion frontend missing Sentry coverage:
ls assets/ frontend/ web/ client/ ui/ 2>/dev/null
cat assets/package.json frontend/package.json 2>/dev/null | grep -E '"react"|"svelte"|"vue"|"next"'
If a frontend directory exists without Sentry configured, suggest the matching skill:
Frontend detected
Suggest skill
React / Next.js
sentry-react-sdk or sentry-nextjs-sdk
Svelte / SvelteKit
sentry-svelte-sdk
Vue
See docs.sentry.io/platforms/javascript/guides/vue/
Other JS/TS
sentry-browser-sdk
Connecting Phoenix backend and JavaScript frontend with linked Sentry projects enables distributed tracing — stack traces that span the browser, Phoenix HTTP server, and downstream services in a single trace view.
Troubleshooting
Issue
Solution
Events not appearing
Verify SENTRY_DSN is set; run mix sentry.send_test_event; set log_level: :debug
Missing stack traces on captured exceptions
Pass stacktrace: __STACKTRACE__ in the rescue block: Sentry.capture_exception(e, stacktrace: __STACKTRACE__)
PlugCapture not working on Bandit
Sentry.PlugCapture is Cowboy-only; with Bandit errors surface via LoggerHandler
Source code context missing in production
Run mix sentry.package_source_code before building your OTP release
Context not appearing on async events
Sentry.Context.* is process-scoped; pass values explicitly or propagate Logger metadata across processes
Oban integration not reporting crons
Requires Oban v2.17.6+ or Oban Pro; cron jobs must have "cron" => true in job meta
Duplicate events from Cowboy crashes
Set excluded_domains: [:cowboy] in LoggerHandler config (this is the default)
finch not starting
Ensure {:finch, "~> 0.21"} is in deps; Finch is the default HTTP client since v12.0.0
JSON encoding error
Add {:jason, "~> 1.4"} and set json_library: Jason for Elixir < 1.18