FullstackPhoenix

Self-Hosted Error Tracking for Phoenix

phoenixerror-trackingobservabilitysaas

It's a quiet Tuesday morning and your phone lights up: a customer is "seeing the page break". You jump into your logs, scroll past hundreds of access lines, and try to find the one stack trace that matters. You don't, because the relevant request was 40 minutes ago and Fly's log retention is shorter than your morning standup.

This feature installs error_tracker, an Elixir-native error tracker that stores exceptions, occurrences, breadcrumbs, and context in your existing Phoenix database. There is no external SaaS account, no per-event pricing, and no third party reading your stack traces.

See errors before customers tell you about them

The point of an error tracker is not to be fancy. It is to make a stack trace, a fingerprint, and a "how often is this happening" view available the moment someone says "the page broke". Storing the data in the same Postgres database the rest of your SaaS already uses keeps the operational surface small and means a single backup covers your errors too.

What This Feature Adds

  • The error_tracker dependency added to mix.exs
  • Configuration that points the tracker at your existing MyApp.Repo and OTP app, enabled in every environment except test
  • A generated migration that creates the error_tracker_errors and error_tracker_occurrences tables
  • The ErrorTracker.Plugins.Pruner plugin so resolved errors are cleaned up over time
  • Automatic capture of exceptions in Phoenix controllers and LiveViews, with Oban-aware capture when oban is installed
  • A LiveView dashboard mounted at /admin/errors (when admin is installed) or beside the dev LiveDashboard otherwise

How It Fits Into Your Phoenix Application

error_tracker hooks into Phoenix and LiveView through telemetry, so no per-controller wiring is needed. For background work, it picks up Oban automatically when the oban feature is present, including job metadata. You can also report explicitly when you catch an exception and want to keep the context:

try do
Billing.charge!(invoice)
rescue
exception ->
ErrorTracker.report(exception, __STACKTRACE__, %{invoice_id: invoice.id})
{:error, :charge_failed}
end

The dashboard mount point is conditional. If you install admin, the dashboard ends up under the admin sidebar at /admin/errors. If you don't, it lives beside the LiveDashboard at /dev/errors so it is still reachable in development.

Installation Notes

  • No required feature dependencies. The recommended pairing is admin (for the mount point) and oban (for background-job capture).
  • Run mix ecto.migrate after install so the error tables exist.
  • The tracker is disabled in test to keep test runs quiet.
  • Decide on a notification channel — Slack webhook, email digest, or simply checking the dashboard daily. The feature stores the errors; deciding how you find out about new ones is a step you still own.

Build This With Live SaaS Kit

Install saas_kit, then mix saaskit.feature.install error_tracker to stop relying on log scrolling and get a real exception inbox inside your own app.