Probes
A probe is a persistent system metric that's updated at a consistent rate.
Probes can be either functions, or a module that implements the
Instruments.Probe
behaviour. If it's a module, its state is controlled by
another process, all implementers need to worry about is the
state transitions.
defining-probes
Defining probes
First of all, probes must have unique names so their stats won't conflict with one another. This is enforced at runtime, since it's possible to define probes progammatically.
functions
Functions
The simplest way to define a probe is to specify a function:
Probe.define("erlang.process_count", :gauge,
function: fn -> :erlang.system_info(:process_count) end,
report_interval: 60_000)
Since the above definiton doesn't pass in the sample_interval options, the sample interval is the same as the report interval. The metric will be sampled and reported every 60 seconds.
mfa
MFA
A simplification of the above example uses the :mfa
option to specify
a module, function and arguments to be called.
For example,
Probe.define("erlang.process_count", :gauge, mfa: {:erlang, :system_info, [:process_count]})
You can also have a function that returns a keyword list of stats and select which keys you want to report. The keys are added to the stat name
Probe.define("erlang.memory", :gauge,
function: fn -> :erlang.memory() end,
keys: [:total, :atom, :processes],
report_interval: 60_000)
While the :erlang.memory()
returns a keyword list with 9 entries,
the above call will only produce three metrics, erlang.memory.total
,
erlang.memory.atom
and erlang.memory.processes
.
module-based-probes
Module based Probes
If more control is desired, you can implement a probe module yourself.
defmodule MyProbe do
@behaviour Instruments.Probe
# callback implementations...
end
# and then define the probe:
Probe.define("system.my_probe", :counter, module: MyProbe)
Your module is now a registered probe, and will receive all of the Probe
callbacks.