AppSignal is a powerful error tracking and performance monitoring tool that can help you maintain reliability and speed in your Elixir applications.
In this tutorial, the first of a two-part series, you'll learn how to integrate AppSignal into your Elixir application, configure it for error tracking, interpret error reports, and leverage AppSignal's features to debug and resolve issues.
Whether you're a seasoned Elixir developer looking to improve your application's error handling or a beginner who wants to understand how error tracking works, this step-by-step tutorial will give you a firm foundation for using AppSignal to track errors in your Elixir app.
Prerequisites
To follow along with this tutorial, you need:
- An Elixir development environment. If you don't have Elixir installed, follow the steps in this guide for your operating system.
- An existing Elixir app. If you don't have one, go ahead and fork this app.
- Some experience working with Elixir/Phoenix.
Let's get started!
Integrating AppSignal Into a Phoenix App
Quick tip: As of writing this article, AppSignal currently supports pure Elixir, Plug, and Phoenix apps. The examples used for this tutorial are centered around a Phoenix app featuring video games, users, and reviews, but the steps taken should be relatively similar for the other supported flavors.
AppSignal provides excellent support for the Phoenix framework and the installation process is very seamless. First, sign up for a free 30-day trial, no card details required.
Then open the Phoenix app's dependencies file and add AppSignal's Phoenix package:
# mix.exs
...
defp deps do
[
...
{:appsignal_phoenix, "~> 2.0"}
]
end
...
Run mix deps.get
to add the package to your app. Once it's added successfully, install it by running the command below:
mix appsignal.install <PUSH_API_KEY>
Note: You can get your PUSH_API_KEY from the AppSignal dashboard.
When you run this command, you'll be presented with some options to customize the installation:
Validating Push API key: Valid! 🎉
What is your application's name? [game_reviews_app]: <APP NAME>
There are two methods of configuring AppSignal in your application.
Option 1: Using a "config/appsignal.exs" file. (1)
Option 2: Using system environment variables. (2)
- The first option is your app's name as you want it to appear on the AppSignal dashboard.
- The second option is how to configure AppSignal: via a configuration file or a system variable.
Configuring AppSignal
For your app to send data to AppSignal, you should have a minimal configuration in config/appsignal.exs
, as shown below:
# config/appsignal.exs
import Config
config :appsignal, :config,
otp_app: :game_reviews_app,
name: "Phoenix API app",
push_api_key: <AppSignal Push API key>,
env: Mix.env
Or you can set this up using system environment variables. One thing to note is that this file can be configured to your liking using a variety of options.
Assuming the configuration proceeds without a hitch, you should now see your app automatically added to the AppSignal dashboard, as shown below:
Note: It may take a couple of minutes for your app's data to start showing.
Great, now let's see how we can instrument an error in AppSignal.
Instrumenting Elixir Errors
This example app is a simple Phoenix LiveView app featuring a video game and reviews.
Once you've cloned the application to your development environment, run mix deps.get
to install all the dependencies, then you can run the app with:
mix phx.server
This will make the app available on http://localhost:4000
.
Go ahead and test it by creating a few games with the following command:
curl --location --request POST 'http://localhost:4000/api/games' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'Host: localhost:4000' \
--header 'Connection: keep-alive' \
--data-raw '{
"game": {
"title": "Hell divers",
"genre": "Action",
"publisher": "Arrowhead Studios"
}
}'
Having made a couple of games this way, you can now make a GET request for the games list (I use Insomnia for this, but you can use whatever you like):
Which should execute successfully, as you can see above.
Now, let's deliberately cause an error to see how it will be shown on the AppSignal dashboard.
Firstly, create a function defining a custom exception:
# lib/exceptions/plug_exception.ex
defmodule GameReviewsApp.PlugException do
defexception [:plug_status, message: ""]
end
Then, modify the index action in the games controller to call this function:
defmodule GameReviewsAppWeb.GameController do
...
def index(conn, _params) do
raise GameReviewsApp.PlugException, plug_status: 403, message: "You're not allowed!"
games = Games.list_games()
render(conn, :index, games: games)
end
...
end
Now when we make a request to the games list, this custom exception is raised:
And the same is shown on the AppSignal dashboard:
If you click on the displayed error link, AppSignal gives you more context on the error, which should help you resolve it:
Next up, let's learn how we can track Ecto queries inside AppSignal.
Instrumenting Ecto queries in AppSignal
Ecto is the most popular database abstraction library for Elixir apps.
AppSignal provides native support for Ecto by hooking into the Ecto query telemetry layer, giving you query profiling, identification of slow queries, and more, with no extra work on your part (as long as the otp_app
name within the AppSignal configuration file matches the name of your app in config.exs
):
# config/config.exs
...
# General application configuration
import Config
config :game_reviews_app,
...
# config/appsignal.exs
import Config
config :appsignal, :config,
otp_app: :game_reviews_app,
...
With our configuration done, AppSignal's instrumentation will now automatically pick up Ecto queries and display them on this dashboard:
Now this might be good enough for normal Ecto queries. But to pick up query types such as preloads in the right way, you'll need to edit your app's repo:
# lib/game_reviews_app/repo.ex
defmodule PhxRestApiApp.Repo do
# use Ecto.Repo, #...replace this default line with the one below...
use Appsignal.Ecto.Repo,
otp_app: :game_reviews_app,
adapter: Ecto.Adapters.SQLite3
end
Next, let's learn how to track Phoenix LiveViews using AppSignal.
Instrument Phoenix LiveView with AppSignal
With the latest AppSignal for Elixir package (version 2.12.0 as of writing), you can instrument LiveView dashboards in AppSignal.
Simply adding the package is enough to automatically add your app's live views using the AppSignal package's telemetry handlers. Or you can configure the instrumentation manually using helpers made available by the package.
The code below shows how easy it is to manually configure LiveView instrumentation by adding a single line within application.ex
:
# lib/game_reviews_app/application.ex
...
def start(_type, _args) do
Appsignal.Phoenix.LiveView.attach() # <= ...added this line
children = [
...
]
...
end
...
And with that, you're able to view LiveView mount
, handle_event
, and handle_param
events in the AppSignal dashboard, like so:
Additionally, with the AppSignal LiveView instrumentation helpers, you can wrap LiveView action definitions within an instrument/3
block for even more granular visualizations, like so:
# live/welcome_live.ex
defmodule GameReviewsAppWeb.WelcomeLive do
use GameReviewsAppWeb, :live_view
import Appsignal.Phoenix.LiveView, only: [instrument: 4]
def mount(_params, _session, socket) do
instrument(__MODULE__, "timer instrumentation", socket, fn ->
:timer.send_interval(1000, self(), :tick)
{
:ok,
assign(socket, current_time: DateTime.utc_now())
}
end)
end
def render(assigns) do
~H"""
<div class="container">
<h1>Welcome to my LiveView App</h1>
<p>Current time: <%= @current_time %></p>
</div>
"""
end
end
When sending metrics to AppSignal, you can use a gauge, a counter, or a distribution.
In the code above, we define a counter measurement called "timer instrumentation" to send current time measurements to the AppSignal dashboard continuously.
As you can see below, by switching the dashboard view from "web" to "live_view", "timer instrumentation" is now available on the dashboard as a sample (with all the details you need to dig further):
Finally, I'll highlight a nifty feature that makes AppSignal really stand out in the application performance monitoring space: automated dashboards.
AppSignal's Automated Dashboards for Elixir
Whenever you add AppSignal to an app built using Elixir, it automatically creates a dashboard.
When we add the AppSignal package to the Phoenix app, we get an automated dashboard and notification — in this case, an Erlang Virtual Machine dashboard:
Check out the AppSignal for Elixir documentation for more information.
Wrapping Up
In this article, we've seen how to track Ecto queries and Phoenix LiveViews using AppSignal for Elixir. Consider this an introduction to what is possible when it comes to error tracking in Elixir with AppSignal.
Next time, we'll deep dive into custom instrumentation using Phoenix and Ecto's in-built telemetry features, learning how you can craft and send custom metrics to AppSignal for monitoring even more powerful use cases.
Happy coding!
P.S. If you'd like to read Elixir Alchemy posts as soon as they get off the press, subscribe to our Elixir Alchemy newsletter and never miss a single post!
Top comments (0)