This guide is an introduction to ErrorTracker, an Elixir-based built-in error tracking solution. ErrorTracker provides a basic and free error-tracking solution integrated in your own application. It is designed to be easy to install and easy to use so you can integrate it in your existing project with minimal changes. The only requirement is a relational database in which errors will be tracked.
In this guide we will learn how to install ErrorTracker in an Elixir project so you can start reporting errors as soon as possible. We will also cover more advanced topics such as how to report custom errors and how to add extra context to reported errors.
This guide requires you to have set up Ecto with PostgreSQL, MySQL/MariaDB or SQLite3 beforehand.
The first step to add ErrorTracker to your application is to declare the package as a dependency in your mix.exs
file:
# mix.exs
defp deps do
[
{:error_tracker, "~> 0.5"}
]
end
Once ErrorTracker is declared as a dependency of your application, you can install it with the following command:
mix deps.get
ErrorTracker needs a few configuration options to work. This configuration should be added to your config/config.exs
file:
config :error_tracker,
repo: MyApp.Repo,
otp_app: :my_app,
enabled: true
The :repo
option specifies the repository that will be used by ErrorTracker. You can use your regular application repository or a different one if you prefer to keep errors in a different database.
The :otp_app
option specifies your application name. When an error occurs, ErrorTracker will use this information to understand which parts of the stack trace belong to your application and which parts belong to third-party dependencies. This allows you to filter in-app vs third-party frames when viewing errors.
The :enabled
option (defaults to true
if not present) allows to disable the ErrorTracker on certain environments. This is useful to avoid filling your dev database with errors, for example.
Since ErrorTracker stores errors in the database you must create a database migration to add the required tables:
mix ecto.gen.migration add_error_tracker
Open the generated migration and call the up
and down
functions on ErrorTracker.Migration
:
defmodule MyApp.Repo.Migrations.AddErrorTracker do
use Ecto.Migration
def up, do: ErrorTracker.Migration.up(version: 4)
# We specify `version: 1` in `down`, to ensure we remove all migrations.
def down, do: ErrorTracker.Migration.down(version: 1)
end
You can run the migration and apply the database changes with the following command:
mix ecto.migrate
For more information about how to handle migrations, take a look at the ErrorTracker.Migration
module docs.
At this point, ErrorTracker is ready to track errors. It will automatically start when your application boots and track errors that occur in your Phoenix controllers, Phoenix LiveViews and Oban jobs. The ErrorTracker.Integrations.Phoenix
and ErrorTracker.Integrations.Oban
provide detailed information about how this works.
If your application uses Plug but not Phoenix, you will need to add the relevant integration in your Plug.Builder
or Plug.Router
module.
defmodule MyApp.Router do
use Plug.Router
use ErrorTracker.Integrations.Plug
# Your code here
end
This is also required if you want to track errors that happen in your Phoenix endpoint, before the Phoenix router starts handling the request. Keep in mind that this won't be needed in most cases as endpoint errors are infrequent.
defmodule MyApp.Endpoint do
use Phoenix.Endpoint
use ErrorTracker.Integrations.Plug
# Your code here
end
You can learn more about this in the ErrorTracker.Integrations.Plug
module documentation.
The default integrations include some additional context when tracking errors. You can take a look at the relevant integration modules to see what is being tracked out of the box.
In certain cases, you may want to include some additional information when tracking errors. For example it may be useful to track the user ID that was using the application when an error happened. Fortunately, ErrorTracker allows you to enrich the default context with custom information.
The ErrorTracker.set_context/1
function stores the given context in the current process so any errors that occur in that process (for example, a Phoenix request or an Oban job) will include this given context along with the default integration context.
There are some requirements on the type of data that can be included in the context, so we recommend taking a look at ErrorTracker.set_context/1
documentation
ErrorTracker.set_context(%{user_id: conn.assigns.current_user.id})
You may also want to sanitize or filter out some information from the context before saving it. To do that you can take a look at the ErrorTracker.Filter
behaviour.
If you want to report custom errors that fall outside the default integration scope, you may use ErrorTracker.report/2
. This allows you to report an exception yourself:
try do
# your code
catch
e ->
ErrorTracker.report(e, __STACKTRACE__)
end
You can also use ErrorTracker.report/3
and set some custom context that will be included along with the reported error.
ErrorTracker also provides a dashboard built with Phoenix LiveView that can be used to see and manage the recorded errors.
This is completely optional, and you can find more information about it in the ErrorTracker.Web
module documentation.
Currently ErrorTracker does not support notifications out of the box.
However, it provides some detailed Telemetry events that you may use to implement your own notifications following your custom rules and notification channels.
If you want to take a look at the events you can attach to, take a look at ErrorTracker.Telemetry
module documentation.
By default errors are kept in the database indefinitely. This is not ideal for production environments where you may want to prune old errors that have been resolved.
The ErrorTracker.Plugins.Pruner
module provides automatic pruning functionality with a configurable
interval and error age.
ErrorTracker tracks every error by default. In certain cases some errors may be expected or just not interesting to track. ErrorTracker provides functionality that allows you to ignore errors based on their attributes and context.
Take a look at the ErrorTracker.Ignorer
behaviour for more information about how to implement your own ignorer.