View Source Sentry (Sentry v9.1.0)
Provides the functionality to submit events to Sentry.
This library can be used to submit events to Sentry from any Elixir application. It supports several ways of reporting events:
Manually — see
capture_exception/2
andcapture_message/2
.Through an Elixir
Logger
backend — seeSentry.LoggerBackend
.Automatically for Plug/Phoenix applications — see the Setup with Plug and Phoenix guide, and the
Sentry.PlugCapture
andSentry.PlugContext
modules.
usage
Usage
Add the following to your production configuration:
# In config/prod.exs
config :sentry, dsn: "https://public:secret@app.getsentry.com/1",
included_environments: [:prod],
environment_name: :prod,
tags: %{
env: "production"
}
The :environment_name
and :included_environments
options work together to determine
if and when Sentry should record exceptions. The :environment_name
is the
name of the current environment. In the example above, we have explicitly set
the environment to :prod
which works well if you are inside an environment
specific configuration config/prod.exs
.
An alternative is to use Config.config_env/0
in your general config/config.exs
configuration file:
config :sentry, dsn: "https://public:secret@app.getsentry.com/1",
included_environments: [:prod],
environment_name: config_env()
This will set the environment name to whatever the current environment
is, but it will only send events if the current environment is :prod
,
since that is the only entry in the :included_environments
key.
You can even rely on more specific logic to determine the environment name. It's
not uncommon for most applications to have a "staging" environment. In order
to handle this without adding an additional Mix environment, you can set an
environment variable that determines the release level. By default, Sentry
picks up the SENTRY_ENVIRONMENT
variable. Otherwise, you can read the
variable at runtime. Do this only in config/runtime.exs
so that it will
work both for local development as well as Mix releases.
# In config/runtime.exs
config :sentry, dsn: "https://public:secret@app.getsentry.com/1",
included_environments: ["production", "staging"],
environment_name: System.get_env("RELEASE_LEVEL", "development")
In this example, we are getting the environment name from the RELEASE_LEVEL
environment variable. If that variable does not exist, we default to "development"
.
Now, on our servers, we can set the environment variable appropriately. On
our local development machines, exceptions will never be sent, because the
default value is not in the list of :included_environments
.
Using the DSN To Send Events
We recommend to use the
:dsn
configuration to control whether to report events. If:dsn
is not set (or set tonil
), then we won't report events to Sentry. Thanks to this behavior, you can essentially only set:dsn
in environments where you want to report events to Sentry. In the future, we might remove the:included_environments
configuration altogether.
Sentry supports many configuration options. See the Configuration section for complete documentation.
configuration
Configuration
You can configure Sentry through the application environment. Configure
the following keys under the :sentry
application. For example, you can
do this in config/config.exs
:
# config/config.exs
config :sentry,
# ...
The basic configuration options are:
:dsn
(String.t/0
) - the DSN for your Sentry project. If this is not set, Sentry will not be enabled. If theSENTRY_DSN
environment variable is set, it will be used as the default value.:release
(String.t/0
) - the release version of your application. This is used to correlate events with source code. If theSENTRY_RELEASE
environment variable is set, it will be used as the default value.:environment_name
(atom/0
orString.t/0
) - the current environment name. This is used to determine if Sentry should be enabled and if events should be sent. For events to be sent, the value of this option must appear in the:included_environments
list. If theSENTRY_ENVIRONMENT
environment variable is set, it will be used as the defaults value. Otherwise, defaults to"dev"
.:included_environments
(list ofatom/0
orString.t/0
, or the atom:all
) - the environments in which Sentry can report events. If this is a list, then:environment_name
needs to be in this list for events to be reported. If this is:all
, then Sentry will report events regardless of the value of:environment_name
. Defaults to:all
.:tags
(map/0
) - a map of tags to be sent with every event. Defaults to%{}
.:server_name
(String.t/0
) - the name of the server running the application. Not used by default.:filter
(module/0
) - a module that implements theSentry.Filter
behaviour. Defaults toSentry.DefaultEventFilter
. See the Filtering Exceptions section below.:json_library
(module/0
) - a module that implements the "standard" Elixir JSON behaviour, that is, exports theencode/1
anddecode/1
functions. Defaults toJason
, which requires:jason
to be a dependency of your application.:log_level
(Logger.level/0
) - the level to use when Sentry fails to send an event due to an API failure or other reasons. Defaults to:warning
.
To customize what happens when sending an event, you can use these options:
:sample_rate
(float/0
between0.0
and1.0
) - the percentage of events to send to Sentry. Defaults to1.0
(100% of events).:send_result
(atom/0
) - controls what to return when reporting exceptions to Sentry. Defaults to:none
.:send_max_attempts
(integer/0
) - the maximum number of attempts to send an event to Sentry. Defaults to4
.:max_breadcrumbs
(integer/0
) - the maximum number of breadcrumbs to keep. Defaults to100
. SeeSentry.Context.add_breadcrumb/1
.:before_send_event
(before_send_event_callback/0
) - allows performing operations on the event before it is sent as well as filtering out the event altogether. If the callback returnsnil
orfalse
, the event is not reported. If it returns an updatedSentry.Event
, then the updated event is used instead. See the Event Callbacks section below for more information.:after_send_event
(after_send_event_callback/0
) - callback that is called after attempting to send an event. The result of the HTTP call as well as the event will be passed as arguments. The return value of the callback is not returned. See the Event Callbacks section below for more information.:in_app_module_allow_list
(list ofmodule/0
) - a list of modules that is used to distinguish among stacktrace frames that belong to your app and ones that are part of libraries or core Elixir. This is used to better display the significant part of stacktraces. The logic is "greedy", so if your app's root module isMyApp
and you configure this option to[MyApp]
,MyApp
as well as any submodules (likeMyApp.Submodule
) would be considered part of your app. Defaults to[]
.
To customize the behaviour of the HTTP client used by Sentry, you can use these options:
:client
(module/0
) - a module that implements theSentry.HTTPClient
behaviour. Defaults toSentry.HackneyClient
, which uses hackney as the HTTP client.:hackney_opts
(keyword/0
) - options to be passed tohackney
. Only applied if:client
is set toSentry.HackneyClient
. Defaults to[pool: :sentry_pool]
.:hackney_pool_max_connections
(integer/0
) - the maximum number of connections to keep in the pool. Only applied if:client
is set toSentry.HackneyClient
. Defaults to50
.:hackney_pool_timeout
(integer/0
) - the maximum time to wait for a connection to become available. Only applied if:client
is set toSentry.HackneyClient
. Defaults to5000
.
To customize options related to reporting source code context, you can use these options:
:report_deps
(boolean/0
) - whether to report Mix dependencies of your application alongside events. Iftrue
, this attempts to load dependencies at compile time. Defaults totrue
.:enable_source_code_context
(boolean/0
) - whether to report source code context alongside events. Defaults tofalse
.:root_source_code_paths
(list ofPath.t/0
) - a list of paths to the root of your application's source code. This is used to determine the relative path of files in stack traces. Usually, you'll want to set this to[File.cwd!()]
. For umbrella apps, you should set this to all the application paths in your umbrella (such as[Path.join(File.cwd!(), "apps/app1"), ...]
). Required if:enabled_source_code_context
istrue
.:source_code_path_pattern
(String.t/0
) - a glob pattern used to determine which files to report source code context for. The glon "starts" from:root_source_code_paths
. Defaults to"**/*.ex"
.:source_code_exclude_patterns
(list ofRegex.t/0
) - a list of regular expressions used to determine which files to exclude from source code context. Defaults to[~r"/_build/", ~r"/deps/", ~r"/priv/"]
.:context_lines
(integer/0
) - the number of lines of source code before and after the line that caused the exception to report. Defaults to3
.
Compile-time Configuration
These options are only available at compile-time:
:enable_source_code_context
:root_source_code_paths
:report_deps
:source_code_path_pattern
:source_code_exclude_patterns
If you change the value of any of these, you'll need to recompile Sentry itself. You can run
mix deps.compile sentry
to do that.
configuration-through-system-environment
Configuration Through System Environment
Sentry supports loading configuration from the system environment. You can do this
by setting SENTRY_<name>
environment variables. For example, to set the :release
option through the system environment, you can set the SENTRY_RELEASE
environment
variable.
The supported SENTRY_<name>
environment variables are:
SENTRY_RELEASE
SENTRY_ENVIRONMENT
SENTRY_DSN
filtering-exceptions
Filtering Exceptions
If you would like to prevent Sentry from sending certain exceptions, you can
use the :before_send_event
configuration option. See the Event Callbacks
section below.
Before v9.0.0, the recommended way to filter out exceptions was to use a filter,
that is, a module implementing the Sentry.EventFilter
behaviour. This is still supported,
but is not deprecated. See Sentry.EventFilter
for more information.
event-callbacks
Event Callbacks
You can configure the :before_send_event
and :after_send_event
options to
customize what happens before and/or after sending an event. The :before_send_event
callback must be of type before_send_event_callback/0
and the :after_send_event
callback must be of type after_send_event_callback/0
. For example, you
can set:
config :sentry,
before_send_event: {MyModule, :before_send},
after_send_event: {MyModule, :after_send}
MyModule
could look like this:
defmodule MyModule do
def before_send(event) do
metadata = Map.new(Logger.metadata())
%Sentry.Event{event | extra: Map.merge(event.extra, metadata)}
end
def after_send_event(event, result) do
case result do
{:ok, id} ->
Logger.info("Successfully sent event!")
{:error, _reason} ->
Logger.info(fn -> "Did not successfully send event! #{inspect(event)}" end)
end
end
end
reporting-source-code
Reporting Source Code
Sentry supports reporting the source code of (and around) the line that caused an issue. To support this functionality, this library stores the text of source files during compilation. An example configuration to enable this functionality is:
config :sentry,
dsn: "https://public:secret@app.getsentry.com/1",
enable_source_code_context: true,
root_source_code_paths: [File.cwd!()],
context_lines: 5
File contents are saved when Sentry is compiled, which can cause some complications. If a file is changed, and Sentry is not recompiled, it will still report old source code.
The best way to ensure source code is up to date is to recompile Sentry
itself via mix deps.compile sentry --force
. It's possible to create a Mix
task alias in mix.exs
to do this. The example below would allow you to
run mix sentry_recompile && mix compile
which will force recompilation of Sentry so
it has the newest source and then compile the project. The second mix compile
is required due to Mix only invoking the same task once in an alias.
defp aliases do
[sentry_recompile: ["compile", "deps.compile sentry --force"]]
end
This is an important to note especially when building for production. If your build or deployment system caches prior builds, it may not recompile Sentry and could cause issues with reported source code being out of date.
Due to Sentry reading the file system and defaulting to a recursive search
of directories, it is important to check your configuration and compilation
environment to avoid a folder recursion issue. Problems may be seen when
deploying to the root folder, so it is best to follow the practice of
compiling your application in its own folder. Modifying the
:source_code_path_pattern
configuration option from its default is also
an avenue to avoid compile problems.
Link to this section Summary
Types
A callback to use with the :after_send_event
configuration option.
A callback to use with the :before_send_event
configuration option.
configuration options.k
The strategy to use when sending an event to Sentry.
Functions
Parses and submits an exception to Sentry
Reports a message to Sentry.
Gets the last event ID sent to the server from the process dictionary. Since it uses the process dictionary, it will only return the last event ID sent within the current process.
Puts the last event ID sent to the server for the current process in the process dictionary.
Sends an event to Sentry.
Link to this section Types
@type after_send_event_callback() :: (Sentry.Event.t(), result :: term() -> term()) | {module(), function_name :: atom()}
A callback to use with the :after_send_event
configuration option.
If this is {module, function_name}
, then module.function_name(event, result)
will
be called, where event
is of type Sentry.Event.t/0
.
@type before_send_event_callback() :: (Sentry.Event.t() -> as_boolean(Sentry.Event.t())) | {module(), function_name :: atom()}
A callback to use with the :before_send_event
configuration option.
configuration options.k
If this is {module, function_name}
, then module.function_name(event)
will
be called, where event
is of type Sentry.Event.t/0
.
See the Configuration section in the module documentation for more information on configuration.
@type send_type() :: :sync | :none
The strategy to use when sending an event to Sentry.
Link to this section Functions
@spec capture_exception( Exception.t(), keyword() ) :: send_result()
Parses and submits an exception to Sentry
This only sends the exception if the current Sentry environment is in
the :included_environments
. See the Configuration section
in the module documentation.
The opts
argument is passed as the second argument to send_event/2
.
@spec capture_message( String.t(), keyword() ) :: send_result()
Reports a message to Sentry.
opts
argument is passed as the second argument to Sentry.send_event/2
.
Gets the last event ID sent to the server from the process dictionary. Since it uses the process dictionary, it will only return the last event ID sent within the current process.
Puts the last event ID sent to the server for the current process in the process dictionary.
@spec send_event( Sentry.Event.t(), keyword() ) :: send_result()
Sends an event to Sentry.
An event is the most generic payload you can send to Sentry. It encapsulates
information about an exception, a message, or any other event that you want to
report. To manually build events, see the functions in Sentry.Event
.
options
Options
The supported options are:
:result
- Allows specifying how the result should be returned. The possible values are::sync
- Sentry will make an API call synchronously (including retries) and will return{:ok, event_id}
if successful.:none
- Sentry will send the event in the background, in a fire-and-forget fashion. The function will return{:ok, ""}
regardless of whether the API call ends up being successful or not.:async
- Not supported anymore, see the information below.
:sample_rate
- The sampling factor to apply to events. A value of0.0
will deny sending any events, and a value of1.0
will send 100% of events. Sampling is applied after the:before_send_event
callback. See where the Sentry documentation suggests this.Other options, such as
:stacktrace
or:extra
, will be passed toSentry.Event.create_event/1
downstream. SeeSentry.Event.create_event/1
for available options.
Async Send
Before v9.0.0 of this library, the
:result
option also supported the:async
value. This would spawn aTask
to make the API call, and would return a{:ok, Task.t()}
tuple. You could useTask
operations to wait for the result asynchronously. Since v9.0.0, this option is not present anymore. Instead, you can spawn a task yourself that then calls this function withresult: :sync
. The effect is exactly the same.
Sending Exceptions and Messages
This function is low-level, and mostly intended for library developers, or folks that want to have full control on what they report to Sentry. For most use cases, use
capture_exception/2
orcapture_message/2
.