How to Monitor Custom Metrics with AppSignal
Tags: node, elixir, ruby, apm
Published: 2023-05-04 15:01:13

Setting up custom metrics is an easy way to gain instant insights into the information you need (without sifting through log lines or struggling with complicated reporting tools). Supplement your application's critical monitoring data by tracking meaningful metrics to quickly identify and resolve potential issues.

In this blog post, we'll show you how to set up and use custom metrics to remove your monitoring blind spots. We'll demonstrate how you can use custom metrics alongside our suite of monitoring tools to better understand the performance of your application.

## What Are Custom Metrics?

When it comes to metrics, AppSignal by default tracks critical data such as error rates, response times, and throughput. We use these metrics to monitor your application and notify you when your application is experiencing performance issues.

Custom metrics allow you to visualize and track any application data you want, providing deeper insights into your application's performance by relating additional contexts - such as active user counts or job-specific processing times. You can create dashboards in AppSignal to track custom metrics alongside critical metrics such as throughput or database size.

![Magic Dashboard hover-over, with links to Time Detective](https://blog.appsignal.com/images/blog/2023-04/custom-metrics-graph-hover.png)

## Measuring Your Metrics

When sending your metrics to AppSignal, it's important to consider how you wish to measure them. AppSignal offers three measurement methods:

| Measure      | Description                                                                                                                                                                                                                                                                            |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Gauge        | A number that represents a particular value at a specific point in time that can frequently be overwritten, such as the count of an application's active users.                                                                                                                        |
| Counter      | A number you can increment by any given value, such as the count of times a process has run.                                                                                                                                                                                           |
| Distribution | A collection of numbers from which we store an average, count, or percentile. You can use this to track a spread of values in a dataset - for example, the average user cart value of an e-commerce application, or the percentage of background jobs completed within a desired time. |

AppSignal provides methods and functions to help you easily track your custom metrics using the appropriate form of measurement.

Let's imagine we're monitoring a webshop. We'll show how you can use gauge, counter, and distribution measurements to track specific data points.

### Gauge

For context into _why_ our application may be more or less performant than usual, let's see how many active shoppers are currently using our application. We'll use the gauge measure to report an active user count every time a new user session is created in our application.

To do this, we can create a minutely probe, a mechanism that sends custom metrics to AppSignal periodically. We can use this probe to record how many shopping carts have been updated within the last minute and send this information to AppSignal under the label `active_shoppers` using the `set_gauge` method. For example:

#### Ruby

```ruby
Appsignal::Minutely.probes.register :active_shoppers_probe, lambda do
  active_carts_count = Carts.where(updated_at: 1.minute.ago..).count
  Appsignal.set_gauge("active_shoppers", active_carts_count)
end
```

_You can read our Ruby documentation for more information on [minutely probes](https://docs.appsignal.com/ruby/instrumentation/minutely-probes.html)._

#### Elixir

```elixir
Appsignal.Probes.register(:active_shoppers_probe, fn ->
  query = from(c in Carts,
    where: c.updated_at ^DateTime.utc_now() - (60 * :second),
    select: count(c.id)
  )

  active_carts_count = Repo.one(query)
  Appsignal.set_gauge("active_shoppers", active_carts_count)
end)
```

_You can read our Elixir documentation for more information on [minutely probes](https://docs.appsignal.com/elixir/instrumentation/minutely-probes.html)._

#### Node.js

```js
const meter = Appsignal.client.metrics();
const probes = meter.probes();

probes.register("activeShoppersProbe", () => {
  const oneMinuteAgo = new Date(Date.now() - 60000);

  // use MongoDB to query carts table
  const activeCartsCount = await Cart.countDocuments({
    updated_at: { $gte: oneMinuteAgo, $lte: Date.now() },
  });

  meter.setGauge("active_shoppers", activeCartsCount);
});
```

_You can read our Node.js documentation for more information on [minutely probes](https://docs.appsignal.com/nodejs/3.x/instrumentation/minutely-probes.html)._

Once configured, we can create a chart in AppSignal to track how many active shoppers are using our application:

![Graph showing active shoppers metric](https://blog.appsignal.com/images/blog/2023-04/custom-metrics-active-shoppers.png)

With this information, we are able to quickly infer how our webshop is performing based on the approximate number of people actively using the site. If we notice a particularly high count and anticipate performance issues, we can take measures to ensure our application remains available.

### Counter

With counters, we can track how often something happens in our application. This feature is handy in scenarios where you need to monitor the frequency of certain events or actions over time - for example, how many times a user completes an action, like adding an item to their cart.

Let's say we'd like to understand how often our application is invoicing users. To do this, we need to increment our counter each time an invoice is created.

Use the `increment_counter` method in Ruby and Elixir:

```ruby
Appsignal.increment_counter("invoice_count", 1)
```

And the `incrementCounter` function in Node.js:

```js
const meter = Appsignal.client.metrics();

meter.incrementCounter("invoice_count", 1);
```

Once set up, we can track how many invoices our application is generating in AppSignal:

![Graph showing invoices and order metrics](https://blog.appsignal.com/images/blog/2023-04/custom-metrics-orders-invoices.png)

What if we track additional related data points, such as orders placed, and notice that our metrics aren't tracking against each other as expected? Then we can investigate our invoicing and ordering logic, and potentially locate and fix critical issues before they impact many of our customers.

### Distribution

You can use custom metrics to record data measurements, such as response time or background job duration. Keeping track of such metrics can help you identify poorly performing background jobs or API endpoints, which can negatively impact user experience.

We want to see the average time it takes for our application to run its order confirmation job, as it's vital customers receive this email within minutes of making a purchase.

To do this, we use the `add_distribution_value` method:

#### Ruby

```ruby
start_time = Time.now
Ordering::Confirm.new.run
duration = (Time.now - start_time) * 1000

Appsignal.add_distribution_value("order_confirmation_duration", duration)
```

#### Elixir

```elixir
start_time = :os.system_time(:millisecond)
Ordering.Confirm.run()
duration = :os.system_time(:millisecond) - start_time

Appsignal.add_distribution_value("order_confirmation_duration", duration)
```

#### Node.js

```js
const meter = Appsignal.client.metrics();

let confirmOrderStartTime = Date.now();
confirmOrder();
let confirmOrderDuration = Date.now() - confirmOrderStartTime;

meter.addDistributionValue("order_confirmation_duration", confirmOrderDuration);
```

Once that's done, we can track the average time our confirm order job is taking to complete in AppSignal. We'll notice if it is performing slower than expected before our users do, allowing us to proactively keep our application available and scalable.

![Graph showing order confirmation metric](https://blog.appsignal.com/images/blog/2023-04/custom-metrics-order-confirmation.png)

## Custom Dashboards for Custom Metrics

Thanks to our intuitive UI, you can start tracking your custom metrics in minutes.

You can use the "Add dashboard" button in the Dashboard navigation to create a new dashboard. Click the "Add graph" button to start building your graphs with our Graph Builder.

![Creating a graph with custom metrics](https://blog.appsignal.com/images/blog/2023-04/custom-metrics-create-graph.png)

When creating a graph, you can select which metrics and tags you want to chart and configure your graph's legends and labels. Once that's done, you'll immediately see your graph display current metric data for the specified period of time.

## Why Metrics Matter

While logging is a fantastic solution to help you debug and troubleshoot application performance issues _after_ they've occurred, metrics can help you to prevent future issues _before_ your customers notice anything. With custom metrics, you can:

- **Concentrate on what matters:** Track specific data points in your application accurately and get focused insights without filtering through large amounts of logging metadata or incident lists.
- **Get down to business:** Understand your application's performance from a business perspective and quickly track critical data such as active user counts, KPIs, or daily sales.
- **Streamline your logging:** Logging 'everything everywhere all at once' is unsustainable. With custom metrics, you can track essential data efficiently and use your logs to investigate the cause of incidents, only logging data that's necessary for troubleshooting and debugging.
- **Work proactively, not reactively:** Set custom triggers to warn you if your application takes too long to send invoices to users, for example, or is experiencing a higher volume of active users than usual. These warnings allow you to proactively investigate and resolve an issue before it impacts your customers.

## Dive Deeper Into Custom Metrics

Ready to get the most out of your application's metrics? This blog post has covered just a small slice of what is possible with custom metrics in AppSignal. Our [documentation on custom metrics](https://docs.appsignal.com/metrics/custom.html) outlines everything you need to know.

If you need help, have questions about metrics or anything else AppSignal or monitoring related, you can always [contact us](mailto:support@appsignal.com).

## AppSignal: More Than Just an APM Tool

AppSignal's custom metrics are just one of our many developer-driven features that help you to monitor your application. Developers also enjoy using our monitoring because we have:

- An intuitive interface that is easy to navigate.
- Simple and predictable pricing.
- Developer-to-developer support.

If you're new to AppSignal, remember to [ask us](mailto:support@appsignal.com) for some free stroopwafels! They taste almost as good as it feels to have all of your application's metrics at your fingertips 😉🍪