.
Behaviours: gen_server
.
This module defines the exometer_report
behaviour.
Required callback functions: exometer_init/1
, exometer_report/5
, exometer_subscribe/5
, exometer_unsubscribe/4
, exometer_info/2
, exometer_call/3
, exometer_cast/2
, exometer_terminate/2
, exometer_setopts/4
, exometer_newentry/2
.
A custom reporter plugin, executing in its own process, can receive
updated metric values by having its module referenced in an
exometer_report:subscribe()
call.
The reporter, once it is setup as a subscription destination, will receive periodic calls with updated metrics and data points to be reported.
Each custom plugin implements the exometer_report behavior.
The life cycle of a a custom reporter consists of the following steps.
-
Reporter creation
exometer_init/1
is invoked by exometer when the reporter is configured in the reporter application environment. See Configuring reporter plugins for details. -
Setup subscription
Whenexometer_report:subscribe()
is called, targeting the custom report plugin, the gen_server'sexometer_subscribe()
function will be invoked to notify the plugin of the new metrics subscription. -
Report Metrics
Updated metrics are sent by exometer to theexometer_report/4
. All reported metrics will have been notified to the recipient through a previousexometer_report()
function. -
Tear down subscription
Whenexometer_report:unsubscribe()
is called, addressing the custom report plugin, the recipient'sMod:exometer_unsubscribe/4
function will be invoked to notify the plugin of the deleted subscription.
The following chapters details each of the callbacks to be implemented in the exometer_report behavior.
The exometer_init()
function is invoked as follows:
exometer_init(Options)
The custom reporter plugin should create the necessary state for the new plugin and return a state to be used in future plugin calls.
Options
Provides the prop list with attributes from the application environment for the cusom recipient. See Configuring reporter plugins for
The Mod:exometer_init/1
function should return {ok, State}
where
State is a tuple that will be provided as a reference argument to
future calls made into the plugin. Any other return formats will
cancel the creation of the custom reporting plugin.
The Mod:exometer_subscribe/5
function is invoked as follows:
exometer_subscribe(Metric, DataPoint, Interval, Extra, State)
The custom plugin can use this notification to modify and return its
state in order to prepare for future calls to exometer_report()
with
the given meteric and data point.
-
Metric
Specifies the metric that is now subscribed to by the plugin as a list of atoms. -
DataPoint
Specifies the data point within the subscribed-to metric as an atom, or a list of atoms. -
Interval
Specifies the interval, in milliseconds, that the subscribed-to value will be reported at, or an atom, referring to a named interval configured in the reporter. -
Extra
Specifies the extra data, which can be anything the reporter can understand. -
State
Contains the state returned by the last called plugin function.
The exomoeter_subscribe()
function should return {ok, State}
where
State is a tuple that will be provided as a reference argument to
future calls made into the plugin. Any other return formats will
generate an error log message by exometer.
The Mod:exometer_report/5
function is invoked as follows:
exometer_report(Metric, DataPoint, Extra, Value, State)
The custom plugin will receive this call when a periodic subscription triggers and wants to report its current value through the plugin. The plugin should export the value to the external system it interfaces and return its possibly modified state.
-
Metric
Specifies the metric that is to be reported. -
DataPoint
Specifies the data point or data points within the metric to be reported. -
Extra
Specifies the extra data, which can be anything the reporter can understand. -
State
Contains the state returned by the last called plugin function.
The exometer_report()
function should return {ok, State}
where
State is a tuple that will be provided as a reference argument to
future calls made into the plugin. Any other return formats will
generate an error log message by exometer.
The Mod:exometer_unsubscribe/4
function is invoked as follows:
exometer_unsubscribe(Metric, DataPoint, Extra, State)
The custom plugin can use this notification to modify and return its
state in order to free resources used to maintain the now de-activated
subscription. When this call returns, the given metric / data point
will not be present in future calls to exometer_report/5
.
-
Metric
Specifies the metric that is now subscribed to by the plugin as a list of atoms. -
DataPoint
Specifies the data point or data points within the subscribed-to metric as an atom or a list of atoms. -
Extra
Specifies the extra data, which can be anything the reporter can understand. -
Value
Specifies the value for the datapoint, which is reported. -
State
Contains the state returned by the last called plugin function.
The Mod:exometer_unsubscribe/4
function should return {ok, State}
where
State is a tuple that will be provided as a reference argument to
future calls made into the plugin. Any other return formats will
generate an error log message by exometer.
If the option {report_bulk, true}
has been given when starting the
reporter, and this function is exported, it will be called as:
exometer_report_bulk(Found, Extra, State)
where Found
has the format [{Metric, [{DataPoint, Value}|_]}|_]
That is, e.g. when a select
pattern is used, all found values are passed
to the reporter in one message. If bulk reporting is not enabled, each
datapoint/value pair will be passed separately to the
exometer_report/5
function. If report_bulk
was enabled, the
reporter callback will get all values at once. Note that this happens
also for single values, which are then passed as a list of one metric,
with a list of one datapoint/value pair.
datapoint() = exometer:datapoint()
datapoints() = datapoint() | [datapoint()]
delay() = time_ms()
error() = {error, any()}
extra() = any()
interval() = pos_integer() | atom()
metric() = exometer:name() | {find, exometer:name()} | {select, ets:match_spec()}
options() = [{atom(), any()}]
reporter_name() = atom()
Restart specification
retry() = boolean()
time_ms() = pos_integer()
add_reporter/2 | Add a reporter. |
call_reporter/2 | Send a custom (synchronous) call to Reporter . |
cast_reporter/2 | Send a custom (asynchronous) cast to Reporter . |
delete_interval/2 | Delete a named interval. |
disable_me/2 | Used by a reporter to disable itself. |
disable_reporter/1 | Disable Reporter . |
enable_reporter/1 | Enable Reporter . |
get_intervals/1 | List the named intervals for Reporter . |
list_metrics/0 | Equivalent to list_metrics([]). |
list_metrics/1 | List all metrics matching Path , together with subscription status. |
list_reporters/0 | List the name and pid of each known reporter. |
list_subscriptions/1 | List all subscriptions for Reporter . |
new_entry/1 | Called by exometer whenever a new entry is created. |
remove_reporter/1 | Remove reporter and all its subscriptions. |
remove_reporter/2 | Remove Reporter (non-blocking call). |
restart_intervals/1 | Restart all named intervals, respecting specified delays. |
set_interval/3 | Specify a named interval. |
setopts/3 | Called by exometer when options of a metric entry are changed. |
start_link/0 | Starts the server --------------------------------------------------------------------. |
start_reporters/0 | |
subscribe/4 | Equivalent to subscribe(Reporter, Metric, DataPoint, Interval, [], true). |
subscribe/5 | Equivalent to subscribe(Reporter, Metric, DataPoint, Interval, Extra, false). |
subscribe/6 | Add a subscription to an existing reporter. |
terminate_reporter/1 | |
trigger_interval/2 | Trigger a named interval. |
unsubscribe/3 | Equivalent to unsubscribe(Reporter, Metric, DataPoint, []). |
unsubscribe/4 | Removes a subscription. |
unsubscribe_all/2 | Removes all subscriptions related to Metric in Reporter. |
add_reporter(Reporter::reporter_name(), Options::options()) -> ok | {error, any()}
Add a reporter.
The reporter can be configured using the following options. Note that all options are also passed to the reporter callback module, which may support additional options.
{module, atom()}
- The name of the reporter callback module. If no module
is given, the module name defaults to the given reporter name.
{status, enabled | disabled}
- The operational status of the reporter
if enabled, the reporter will report values to its target. If disabled, the
reporter process will be terminated and subscription timers canceled, but
the subscriptions will remain, and it will also be possible to add new
subscriptions to the reporter.
{intervals, [named_interval()]}
named_interval() :: {Name::atom(), Interval::pos_integer()}
| {Name::atom(), Interval::time_ms(), delay()::time_ms()}
| {Name::atom(), 'manual'}
Define named intervals. The name can be used by subscribers, so that all
subsriptions for a given named interval will be reported when the interval
triggers. An optional delay (in ms) can be given: this will cause the first
interval to start in Delay
milliseconds. When all intervals are named
at the same time, the delay parameter can be used to achieve staggered
reporting. If the interval is specified as
'manual
', it will have
to be triggered manually using trigger_interval/2
.
{report_bulk, true | false}
Pass all found datapoint/value pairs for a given subscription at once to
the exometer_report_bulk/3
function, if it is exported, otherwise use
exometer_report/4
as usual.
call_reporter(Reporter::reporter_name(), Msg::any()) -> any() | {error, any()}
Send a custom (synchronous) call to Reporter
.
This function is used to make a client-server call to a given reporter instance. Note that the reporter type must recognize the request.
cast_reporter(Reporter::reporter_name(), Msg::any()) -> ok | {error, any()}
Send a custom (asynchronous) cast to Reporter
.
This function is used to make an asynchronous cast to a given reporter instance. Note that the reporter type must recognize the message.
delete_interval(Reporter::reporter_name(), Name::atom()) -> ok | error()
Delete a named interval.
disable_me(Mod::module(), St::any()) -> no_return()
Used by a reporter to disable itself.
This function can be called from a reporter instance if it wants to be
disabled, e.g. after exhausting a configured number of connection attempts.
The arguments passed are the name of the reporter callback module and the
module state, and are used to call the Mod:terminate/2
function.
disable_reporter(Reporter::reporter_name()) -> ok | {error, any()}
Disable Reporter
.
The reporter will be terminated, and all subscription timers will be canceled, but the subscriptions themselves and reporter metadata are kept.
enable_reporter(Reporter::reporter_name()) -> ok | {error, any()}
Enable Reporter
.
The reporter will be 'restarted' in the same way as if it had crashed and was restarted by the supervision logic, but without counting it as a restart.
If the reporter was already enabled, nothing is changed.
get_intervals(Reporter::reporter_name()) -> [{atom(), [{time, pos_integer()} | {delay, pos_integer()} | {timer_ref, reference()}]}]
List the named intervals for Reporter
.
list_metrics() -> {ok, [{exometer:name(), [datapoint()], [{reporter_name(), datapoint()}], exometer:status()}]} | {error, any()}
Equivalent to list_metrics([])
.
list_metrics(Path::metric()) -> {ok, [{exometer:name(), [datapoint()], [{reporter_name(), datapoint()}], exometer:status()}]} | {error, any()}
List all metrics matching Path
, together with subscription status.
This function performs a metrics search using exometer:find_entries/1
,
then matches the result against known subscriptions. It reports, for each
metric, the available data points, as well as which reporters subscribe to
which data points.
list_reporters() -> [{reporter_name(), pid()}]
List the name and pid of each known reporter.
list_subscriptions(Reporter::reporter_name()) -> [{metric(), datapoint(), interval(), extra()}]
List all subscriptions for Reporter
.
new_entry(Entry::exometer:entry()) -> ok
Called by exometer whenever a new entry is created.
This function is called whenever a new metric is created, giving each
reporter the chance to enable a subscription for it. Note that each
reporter is free to call the subscription management functions, as there
is no risk of deadlock. The callback function triggered by this call is
Mod:exometer_newentry(Entry, St)
.
remove_reporter(Reporter::reporter_name()) -> ok | {error, any()}
Remove reporter and all its subscriptions.
remove_reporter(Reporter::reporter_name(), _Reason::any()) -> ok | {error, any()}
Remove Reporter
(non-blocking call).
This function can be used to order removal of a reporter with a custom reason. Note that the function is asynchronous, making it suitable e.g. for calling from within the reporter itself.
restart_intervals(Reporter::reporter_name()) -> ok
Restart all named intervals, respecting specified delays.
This function can be used if named intervals are added incrementally, and it is important that all intervals trigger separated by the given delays.
set_interval(Reporter::reporter_name(), Name::atom(), Time::time_ms() | {time_ms(), delay()} | manual) -> ok | error()
Specify a named interval.
See add_reporter/2
for a description of named intervals.
The named interval is here specified as either Time
(milliseconds) or
{Time, Delay}
, where a delay in milliseconds is provided. It is also
specify an interval as
'manual
', indicating that the interval can
only be triggered manually via trigger_interval/2
.
If the named interval exists, it will be replaced with the new definition.
Otherwise, it will be added. Use restart_intervals/1
if you want
all intervals to be restarted/resynched with corresponding relative delays.
setopts(Metric::exometer:entry(), Options::options(), Status::exometer:status()) -> ok
Called by exometer when options of a metric entry are changed.
Reporters subscribing to the metric get a chance to process the options
change in the function Mod:exometer_setopts(Metric,Options,Status,St)
.
start_link() -> {ok, pid()} | ignore | {error, any()}
start_reporters() -> any()
subscribe(Reporter::reporter_name(), Metric::metric(), DataPoint::datapoints(), Interval::interval()) -> ok | not_found | unknown_reporter | error
Equivalent to subscribe(Reporter,Metric,DataPoint,Interval,[],true)
.
subscribe(Reporter::reporter_name(), Metric::metric(), DataPoint::datapoints(), Interval::interval(), Extra::extra()) -> ok | not_found | unknown_reporter | error
Equivalent to subscribe(Reporter,Metric,DataPoint,Interval,Extra,false)
.
subscribe(Reporter::reporter_name(), Metric::metric(), DataPoint::datapoints(), Interval::interval(), Extra::extra(), Retry::retry()) -> ok | not_found | unknown_reporter | error
Add a subscription to an existing reporter.
The reporter must first be started using add_reporter/2
, or through
a static configuration. Metric
is the name of an exometer entry. DataPoint
is either a single data point (an atom) or a list of data points (a list).
Interval
is the sampling/reporting interval in milliseconds, or an atom,
referring to a named interval configured in the reporter. The named
interval need not be defined yet in the reporter (the subscription will
not trigger until it is defined.)
Extra
can be anything that the chosen reporter understands (default: []
).
If the reporter uses exometer_util:report_type/3
, Extra
should be
a proplist, and the option {report_type, T}
can control which type (e.g.
for collectd or statsd) that the value corresponds to.
Retry
: boolean(). If true, retry the subscription at the next interval,
even if the metric cannot be read.
terminate_reporter(Reporter) -> any()
trigger_interval(Reporter::reporter_name(), Name::atom()) -> ok
Trigger a named interval.
This function is mainly used to trigger intervals defined as
'manual
', but can be used to trigger any named interval. If a named interval with a specified time in milliseconds is triggered this way, it will effectively be restarted, and will repeat as usual from that point on.
unsubscribe(Reporter::module(), Metric::metric(), DataPoint::datapoint()) -> ok | not_found
Equivalent to unsubscribe(Reporter, Metric, DataPoint, [])
.
unsubscribe(Reporter::module(), Metric::metric(), DataPoint::datapoint() | [datapoint()], Extra::extra()) -> ok | not_found
Removes a subscription.
Note that the subscription is identified by the combination
{Reporter, Metric, DataPoint, Extra}
. The exact information can be
extracted using list_subscriptions/1
.
unsubscribe_all(Reporter::module(), Metric::metric()) -> ok
Removes all subscriptions related to Metric in Reporter.