elixir

An Introduction to Absinthe for Elixir Monitoring with AppSignal

Sapan Diwakar

Sapan Diwakar on

An Introduction to Absinthe for Elixir Monitoring with AppSignal

Absinthe is a popular GraphQL toolkit for building robust APIs in Elixir. Monitoring such APIs is essential to ensure performance, detect bottlenecks, and handle errors effectively. AppSignal offers a seamless way to monitor and gain insights into your Absinthe-powered GraphQL APIs, enabling you to keep applications performant and reliable.

In this post, we’ll explore how to leverage AppSignal’s automatic instrumentation and custom metrics for Absinthe, along with strategies to monitor errors, track subscriptions, and enhance performance through actionable metrics.

Automatic Absinthe for Elixir Instrumentation with AppSignal

Setting up AppSignal for your Elixir application is straightforward. You can follow the official setup guide to install the AppSignal package and configure it with your application key. Once integrated, AppSignal automatically instruments your Absinthe GraphQL API, giving you insights into the execution time and performance of individual queries and mutations.

Here's an example of how your AppSignal performance report might look, showcasing query performance breakdown:

AppSignal GraphQL Sample Breakdown

The sample breakdown above shows that GraphQL took 45 ms—this duration covers both parsing the query and encoding the results. Ecto took 37 ms, with most of that time spent executing the database query.

Let's check out the Event Timeline now:

AppSignal GraphQL Event Timeline

As you can see, this provides a breakdown of all the Ecto queries performed during the resolution of this query. With this instrumentation, you can identify slow queries, measure throughput, and understand which resolvers might need optimization—all without adding any manual instrumentation.

Handling Errors and Exceptions in Absinthe with AppSignal

In GraphQL APIs, errors can occur at multiple points: within resolvers, due to validation issues, or from an underlying data source. AppSignal helps capture and report these errors along with contextual information, making debugging efficient.

Resolver Exceptions and Validation Errors

When an error occurs in a resolver, AppSignal captures it and provides details about the query that caused the issue, the resolver, and the stack trace.

For example, if a single field on a GraphQL API has an error, it will be reported on the "Errors" page on AppSignal. Here's an example of such an error:

AppSignal Error

Clicking on "Inspect latest sample" takes you to the full sample details, including:

  • A backtrace that can help us pinpoint where the error originated.
  • The full GraphQL query and variables (if any), and a lot of other information that can be useful to reproduce that issue.
AppSignal Sample Backtrace/Parameters/Session

Tracking Custom Metrics

While automatic instrumentation provides valuable insights into the performance of your Absinthe API, tracking custom metrics can offer even deeper visibility into specific areas of your application. Custom metrics allow you to define and collect data points unique to your business logic or performance needs. AppSignal makes it easy to track these metrics in your Absinthe GraphQL API.

Defining Custom Metrics

To start tracking custom metrics, you'll need to define the specific aspects of your API that you want to measure. This could include:

  • Resolver Performance: Measure how long specific resolvers take to execute.
  • Query Complexity: Track the number of fields requested in a query or the depth of the query.
  • Subscription Events: Monitor events related to GraphQL subscriptions, such as connection counts and active subscriptions.

Implementing Custom Metrics

You can implement custom metrics using AppSignal's built-in APIs. Here’s a simple example, tracking the execution time of a resolver:

Elixir
defmodule MyAppWeb.Resolvers.PostResolver do def get_pots(_, %{id: id}, _) do start_time = System.monotonic_time() case Blog.get_post(id) do nil -> Appsignal.increment_counter("post.not_found") {:error, "Post not found"} post -> duration = System.monotonic_time() - start_time Appsignal.set_gauge("post.fetch_time", duration) {:ok, post} end end end

Once you've defined and implemented your custom metrics, you can view them in your AppSignal dashboard, which includes various graphs and charts. These graphs and charts are crucial for identifying trends over time, such as increasing fetch times or spikes in 'post not found' errors.

AppSignal Custom Metrics Dashboard Example

Monitoring Absinthe Subscriptions

Subscriptions in Absinthe allow for real-time updates, typically used in chat or notification systems. Monitoring these subscriptions is crucial to ensure they perform well throughout their lifecycle.

Example: Monitoring Subscription Performance

A typical Absinthe subscription might look like this:

Elixir
subscription :comment_added do arg :post_id, non_null(:id) config fn args, _ -> {:ok, topic: args.post_id} end trigger :comment_added, topic: fn %{post_id: post_id} -> "post:#{post_id}" end resolve fn comment, _, _ -> {:ok, comment} end end

Similar to custom metrics monitoring, we can track subscription activation time, latency during updates, total active subscriptions at any given time, and any errors that occur within these subscriptions, giving you full visibility into their behavior.

Here’s how to add basic instrumentation to measure the time required to set up and resolve the subscription.

Elixir
field :comment_added, :comment do arg(:post_id, non_null(:id)) config(fn %{post_id: id} = _args, %{context: context} -> Appsignal.instrument("subscription.config", "Setting up subscription", fn -> {:ok, topic: "post:#{id}"} end) end) resolve(fn comment, _, _ -> Appsignal.instrument("subscription.resolve", "Resolving subscription", fn -> {:ok, comment} end) end) end

And that's it for our whistle-stop tour of Absinthe monitoring using AppSignal!

Wrapping Up

Monitoring GraphQL APIs with AppSignal enables Elixir developers to maintain high performance, quickly diagnose errors, and leverage custom metrics for business-critical operations. Whether you're tracking query execution, debugging resolver errors, or ensuring efficient subscription handling, AppSignal equips you with the necessary tools to build and maintain robust Absinthe applications.

If you are building complex APIs with Absinthe, ensure you integrate AppSignal to enhance your observability and performance monitoring. For further reading, explore AppSignal's Absinthe documentation and this four-part series on building scalable GraphQL APIs with Absinthe.

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!

Sapan Diwakar

Sapan Diwakar

Our guest author Sapan Diwakar is a full-stack developer. He writes about his interests on his blog and is a big fan of keeping things simple, in life and in code. When he’s not working with technology, he loves to spend time in the garden, hiking around forests, and playing outdoor sports.

All articles by Sapan Diwakar

Become our next author!

Find out more

AppSignal monitors your apps

AppSignal provides insights for Ruby, Rails, Elixir, Phoenix, Node.js, Express and many other frameworks and libraries. We are located in beautiful Amsterdam. We love stroopwafels. If you do too, let us know. We might send you some!

Discover AppSignal
AppSignal monitors your apps