Minutely probes
Minutely probes are a mechanism to periodically send custom metrics to AppSignal. This is a system that is included in the AppSignal Elixir package by default. At the start of every minute the minutely probes are triggered to collect metrics and then snoozed until the next minute.
By default the AppSignal Elixir package enables a probe for the ErlangVM.
Usage
The minutely probes allow the AppSignal Elixir package to collect custom metrics by default for the ErlangVM and app-specific metrics by creating your own probe.
Multiple instances
Once activated, the minutely probes system runs on every instance of an app. This means that if a probe report metrics without some kind of differentiating tag, global metrics may be overwritten by instance-level metrics.
To remedy this, we suggest tagging your metrics with the hostname or something else unique for each instance. For example, the ErlangVM Probe tags metrics with the hostname by default.
Alternatively you can disable minutely probes for all but one instance, on which the minutely probes process is run. We suggest using the APPSIGNAL_ENABLE_MINUTELY_PROBES
environment variable to only enable it on the instance of your choosing.
Configuration
The minutely probes are configured using the enable_minutely_probes
config option. The default value is true
.
Creating probes
If you want to track more custom metrics from your app than our default probes do, you can add your own probe(s).
An AppSignal minutely probe can be an Anonymous function, or a Module based function.
Anonymous function
The simplest probe type to register. If you have no dependencies for your probe this is the preferred method.
Appsignal.Probes.register(:my_probe, fn -> Appsignal.set_gauge("database_size", 10) end)
Module based function
A module based function can be useful if you have a more complex probe, or a probe that has dependencies.
# lib/my_app/probes/my_probe.ex defmodule MyApp.MyProbe do def call do Appsignal.set_gauge("database_size", 10) end end
Now you can register this probe in the start function of your OTP app.
Appsignal.Probes.register(:my_probe, &MyApp.MyProbe.call/0)
Stateful probes
As of version 2.2.8
of the AppSignal Elixir package, probes can pass state between runs. If your probe takes an argument, the return value of the last run will be passed as the value for that argument in the following run.
An initial state to be used for the probe's first run can be provided as the third argument to Appsignal.Probes.register
. If it is not provided, the initial state will be nil
.
Appsignal.Probes.register(:stateful_probe, fn minutes -> Appsignal.set_gauge("uptime_minutes", minutes) minutes + 1 end, 0)
Or, as a module based function:
# lib/my_app/probes/my_probe.ex defmodule MyApp.MyProbe do def call(minutes) do Appsignal.set_gauge("uptime_minutes", minutes) minutes + 1 end end
Which you can then register as:
Appsignal.Probes.register(:stateful_probe, &MyApp.MyProbe.call/1, 0)
Registering probes
Probes can be registered with the register
method on the Appsignal.Probes
module.
This method accepts three arguments.
key
- This is the key/name of the probe. This will be used to identify the probe in case an error occurs while executing the probe (which will be logged to the appsignal.log file) and to override an existing probe.probe
- This is one of the supported probe types that should be called every minute to collect metrics.state
- This is the initial state that will be passed to your probe. If your probe does not take state as an argument, then this argument has no effect. It is an optional argument, and its default value isnil
.
To add a probe, register it in your application's start/2
function, just before the supervisor is started.
In a Phoenix app this will look like this:
# lib/my_app/application.ex def start(_type, _args) do children = [ MyApp.Repo, MyAppWeb.Endpoint, ] Appsignal.Probes.register(:my_probe, &MyProbe.call/0) opts = [strategy: :one_for_one, name: Weekmenu.Supervisor] Supervisor.start_link(children, opts) end
Overriding default probes
AppSignal ships with default probes for certain integrations. If for any reason this probe does not function properly or requires some additional configuration for your use case, you can override the default probe by registering a new probe with the same key.
# lib/my_app/application.ex Appsignal.Probes.register(:erlang, fn() -> # Do things end)
Overriding probes will log a debug message in the appsignal.log file which can help to detect if a probe is correctly overridden.