DEV Community

Cover image for Track Errors in Phoenix for Elixir with AppSignal
Aestimo K. for AppSignal

Posted on • Originally published at blog.appsignal.com

Track Errors in Phoenix for Elixir with AppSignal

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
...
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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:

Phoenix app added to AppSignal

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
Enter fullscreen mode Exit fullscreen mode

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"
    }
}'
Enter fullscreen mode Exit fullscreen mode

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):

Requesting the games list

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now when we make a request to the games list, this custom exception is raised:

Custom exception

And the same is shown on the AppSignal dashboard:

Custom exception on AppSignal

If you click on the displayed error link, AppSignal gives you more context on the error, which should help you resolve it:

Error details

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,
...
Enter fullscreen mode Exit fullscreen mode
# config/appsignal.exs

import Config

config :appsignal, :config,
  otp_app: :game_reviews_app,
  ...
Enter fullscreen mode Exit fullscreen mode

With our configuration done, AppSignal's instrumentation will now automatically pick up Ecto queries and display them on this dashboard:

Default Ecto instrumentation

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
Enter fullscreen mode Exit fullscreen mode

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
...
Enter fullscreen mode Exit fullscreen mode

And with that, you're able to view LiveView mount, handle_event, and handle_param events in the AppSignal dashboard, like so:

Liveview instrumentation - 1

Liveview instrumentation - 2

Liveview instrumentation - 3

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
Enter fullscreen mode Exit fullscreen mode

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):

Instrumenting an AppSignal counter in Elixir

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:

Automated dashboard creation notification

Automated dashboard link

Automated 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)