Library / SDK
getsentry/sentry-elixir avatar
getsentry/sentry-elixir

sentry-elixir, the official Sentry SDK and its Logger handler

The official Elixir SDK for Sentry (sentry.io)

693 stars219 forksElixirMIT

At a glance

What is it?
sentry-elixir is the official Elixir SDK for Sentry, and its current centre of gravity is a Logger handler that reports crashes as error events and forwards log entries to Sentry's Logs UI as structured logs. It suits Phoenix and plain OTP applications that want error reporting without hand-wiring a transport, and its JSON and HTTP dependencies are choices rather than hard requirements.
Who is it for?
Adopt sentry-elixir if your Elixir or Phoenix application needs error reporting that also covers ordinary log output, because the Logger handler does both in one place and the SDK picks a JSON library and HTTP client for you unless you configure otherwise. Do not adopt it if you need an Sentry deployment outside sentry.io, since the SDK and the documentation are built around the hosted service, and note the version split between the master branch and the published release.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Elixir, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One dependency line, two libraries you choose yourself

sentry-elixir is the official Sentry SDK for Elixir, and the install is a normal Mix dependency. The interesting part is what the SDK does not bring with it: it installs no JSON library and no HTTP client by itself.

Sentry defaults to the built-in JSON module for JSON and to Finch for HTTP requests, and it can be configured to use others. To use the defaults you declare them:

elixir
defp deps do
  [
    # ...

    {:sentry, "~> 13.0"},
    {:jason, "~> 1.4"},
    {:finch, "~> 0.21"}
  ]
end

There is a version trap in that block, and the README flags it with a warning. If you are using an Elixir version before 1.18, the SDK defaults to Jason as the JSON library, and you must add it to your dependencies yourself, which the README spells out with a separate deps block using {:sentry, "~> 10.8.1"} and {:jason, "~> 1.4"}.

The repository carries several lock files for different Elixir ranges, mix-1.13-1.14.lock, mix-1.15-1.17.lock and mix-1.18.lock, which is the CI's way of proving the SDK still builds across the supported versions.

One more caveat about the README itself: it documents unreleased features from the master branch, and the released version documentation lives on the official site. The deps block above shows the constraint as it stands on master, while the published release in the version list is 14.0.0.

A Logger handler that does two jobs at once

The centre of the library is a Logger handler, Sentry.LoggerHandler, and it does two things: it reports crashes, and optionally Logger messages, to Sentry as error events, and it forwards log entries to Sentry's Logs UI as structured logs.

The opt-ins are separate and the naming is worth reading twice. Setting the :logs option in the Sentry config makes the SDK attach the handler automatically, so you do not touch your :logger configuration or your application.ex, and without :logs the handler is not attached at all. Inside that option, :level turns on structured logs and :capture_log_messages turns on reporting standalone Logger messages as error events:

elixir
# config/prod.exs
config :sentry,
  # ...your other Sentry config...
  logs: [
    # Structured logs sent to Sentry's Logs UI.
    level: :info,
    metadata: [:request_id],
    # Also turn standalone Logger messages into Sentry error events.
    # Omit these to only report crashes as error events.
    capture_log_messages: true,
    capture_level: :error,
    capture_metadata: [:request_id]
  ]

With that configuration, Logger.info/1 and higher are sent to the Logs UI, while Logger.error/1 and higher are also captured as error events, and crashes are always reported regardless.

The two channels answer different questions. Structured logs tell you what the system was doing around a failure, while captured error events give you the group, the culprit and the stacktrace. Turning on only one is a valid choice, and the README says so explicitly.

Adding the handler by hand when you need rate limiting

If you want control over the handler options, such as :rate_limiting or :tags_from_metadata, you add the handler yourself, and doing so replaces the auto-attached one. The handler is declared in your app's :logger config:

elixir
# config/prod.exs
config :my_app, :logger, [
  {:handler, :my_sentry_handler, Sentry.LoggerHandler, %{
    config: %{
      metadata: [:file, :line],
      rate_limiting: [max_events: 10, interval: _1_second = 1_000],
      # Logs all messages with level `:error` and above to Sentry.
      # Remove :capture_log_messages and :level if you only want to report crashes.
      capture_log_messages: true,
      level: :error
    }
  }}
]

That configuration then has to be added to the logger at application start, with Logger.add_handlers(:my_app) in the start callback. The alternative is to skip the :logger configuration entirely and add the handler directly in start/2 with :logger.add_handler, passing the same config map.

The rate limiting option is the reason to do this by hand. A max_events of 10 per interval of one second caps how fast a runaway loop can flood the project, which matters when you have also turned on capture of log messages as error events.

Capturing exceptions and messages directly

Most of the time the handler does the work, since an unhandled exception in a supervised process is reported as a crash. But the SDK also exposes the capture functions for the cases where you want to report something specific or something that is not an exception at all.

For an exception you already rescued, use Sentry.capture_exception/2 and pass the stacktrace:

elixir
try do
  ThisWillError.really()
rescue
  my_exception ->
    Sentry.capture_exception(my_exception, stacktrace: __STACKTRACE__)
end

For a message that is not an exception, use Sentry.capture_message/2, where the first argument names the event and the extra option attaches a map of additional information:

elixir
Sentry.capture_message("custom_event_name", extra: %{extra: information})

Neither call needs the Logger handler, so a system that only wants manual reporting can ignore the :logs option entirely.

A Mix task to prove the configuration actually sends

The README recommends running an included Mix task to check that the configuration is right, and it says the task can be tested on different Mix environments and will tell you if the setup is not currently configured to send events in that environment.

bash
MIX_ENV=dev mix sentry.send_test_event

This is the step most people skip and most people should not. A DSN that is wrong, an environment name that does not match, or a missing dependency produces no visible error at boot, and the first sign of a problem is an empty Sentry project. One command in each environment tells you whether events will flow.

The repository also documents how to test that specific actions cause a report, which is what Sentry itself does using Bypass. The warning there is a real one: when you modify the environment configuration the test case should not run asynchronously, because you are modifying global configuration, and failing to return it to its original state can affect other tests depending on how the Sentry configuration interacts with them. The suggested fix is the on_exit/2 callback that ships with ExUnit, and the example shows setting the DSN to a Bypass port with Sentry.put_config(:dsn, ...) and Sentry.put_config(:send_result, :sync).

A young version history and a wide compatibility range

The release list is short and recent: 13.5.0 on 2026-08-20, 13.5.1 on 2026-09-02 and 14.0.0 on 2026-10-08, with the last push to master on 2026-10-19. The repository topics mark it as a production-tagged SDK in the team-web-backend category, and it is published on Hex as sentry with documentation on hexdocs.

The project structure is conventional Elixir. There is a lib/ directory, config/, test/ and a separate test_integrations/ directory, plus mix.exs, mix.lock, a .formatter.exs and a .dialyzer_ignore.exs, which means the project runs Dialyzer and keeps a formatter configuration. There is a coveralls.json for coverage reporting, an AGENTS.md and a CLAUDE.md, a CHANGELOG.md, and an assets/ directory plus pages/ for the documentation site.

The licence is MIT, so the SDK can be used in commercial applications without conditions beyond keeping the notice, and the code can be vendored and modified if you need to. The notable operational cost is not the licence but the version churn: the SDK tracks the hosted service's product surface, so the structured logs and Logs UI behaviour described in the master README is newer than what older hexdocs versions describe, and a self-hosted Sentry will not have the Logs UI that the handler's structured log path targets.

Editorial conclusion

Adopt sentry-elixir if your Elixir or Phoenix application needs error reporting that also covers ordinary log output, because the Logger handler does both in one place and the SDK picks a JSON library and HTTP client for you unless you configure otherwise. Do not adopt it if you need an Sentry deployment outside sentry.io, since the SDK and the documentation are built around the hosted service, and note the version split between the master branch and the published release. Before you ship, read the master branch README rather than the hexdocs page for the current release, run MIX_ENV=dev mix sentry.send_test_event to confirm the DSN and environment settings actually send, check that your Elixir version picks the JSON library you expect, since versions before 1.18 default to Jason and you must add it yourself, and confirm the last push was on 2026-10-19 with version 14.0.0 released on 2026-10-08.

Frequently asked questions

How do I add the Sentry SDK to an Elixir project?

Add it to the deps list in mix.exs. The README shows {:sentry, "~> 13.0"} together with {:jason, "~> 1.4"} and {:finch, "~> 0.21"}, because the SDK installs no JSON library or HTTP client by itself and defaults to the built-in JSON module and Finch.

How does the sentry-elixir Logger handler work?

Sentry.LoggerHandler reports crashes and optionally Logger messages to Sentry as error events, and forwards log entries to Sentry's Logs UI as structured logs. Setting the :logs option attaches it automatically, with :level enabling structured logs and :capture_log_messages enabling standalone Logger messages as error events.

How do I check that my Sentry configuration works in Elixir?

Run the included Mix task, MIX_ENV=dev mix sentry.send_test_event, which can be run against different Mix environments and reports whether the current environment is configured to send events.

Do I need to add Jason to my dependencies for sentry-elixir?

On Elixir versions before 1.18 the SDK defaults to Jason as the JSON library and you must add it yourself. On 1.18 and later the built-in JSON module is the default, and Jason and Finch are listed in the deps example to use the defaults explicitly.

How do I rate limit the events sentry-elixir reports?

Add the Sentry.LoggerHandler yourself instead of letting the SDK attach it, and pass a rate_limiting option in the handler config, for example rate_limiting: [max_events: 10, interval: _1_second = 1_000], then add the handler to the logger in your application start callback.

Official sources

  1. getsentry/sentry-elixir on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/getsentry-sentry-elixir.svg)](https://hysenlabs.com/projects/getsentry-sentry-elixir)

Was this useful?