Skip to content

Latest commit

 

History

History
747 lines (469 loc) · 25.9 KB

exometer_report.md

File metadata and controls

747 lines (469 loc) · 25.9 KB

Module exometer_report

.

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.

Description

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
    When exometer_report:subscribe() is called, targeting the custom report plugin, the gen_server's exometer_subscribe() function will be invoked to notify the plugin of the new metrics subscription.

  • Report Metrics
    Updated metrics are sent by exometer to the exometer_report/4. All reported metrics will have been notified to the recipient through a previous exometer_report() function.

  • Tear down subscription
    When exometer_report:unsubscribe() is called, addressing the custom report plugin, the recipient's Mod: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.

Data Types


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()

Function Index

add_reporter/2Add a reporter.
call_reporter/2Send a custom (synchronous) call to Reporter.
cast_reporter/2Send a custom (asynchronous) cast to Reporter.
delete_interval/2Delete a named interval.
disable_me/2Used by a reporter to disable itself.
disable_reporter/1Disable Reporter.
enable_reporter/1Enable Reporter.
get_intervals/1List the named intervals for Reporter.
list_metrics/0Equivalent to list_metrics([]).
list_metrics/1List all metrics matching Path, together with subscription status.
list_reporters/0List the name and pid of each known reporter.
list_subscriptions/1List all subscriptions for Reporter.
new_entry/1Called by exometer whenever a new entry is created.
remove_reporter/1Remove reporter and all its subscriptions.
remove_reporter/2Remove Reporter (non-blocking call).
restart_intervals/1Restart all named intervals, respecting specified delays.
set_interval/3Specify a named interval.
setopts/3Called by exometer when options of a metric entry are changed.
start_link/0Starts the server --------------------------------------------------------------------.
start_reporters/0
subscribe/4Equivalent to subscribe(Reporter, Metric, DataPoint, Interval, [], true).
subscribe/5Equivalent to subscribe(Reporter, Metric, DataPoint, Interval, Extra, false).
subscribe/6Add a subscription to an existing reporter.
terminate_reporter/1
trigger_interval/2Trigger a named interval.
unsubscribe/3Equivalent to unsubscribe(Reporter, Metric, DataPoint, []).
unsubscribe/4Removes a subscription.
unsubscribe_all/2Removes all subscriptions related to Metric in Reporter.

Function Details

add_reporter/2


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/2


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/2


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/2


delete_interval(Reporter::reporter_name(), Name::atom()) -> ok | error()

Delete a named interval.

disable_me/2


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/1


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/1


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/1


get_intervals(Reporter::reporter_name()) -> [{atom(), [{time, pos_integer()} | {delay, pos_integer()} | {timer_ref, reference()}]}]

List the named intervals for Reporter.

list_metrics/0


list_metrics() -> {ok, [{exometer:name(), [datapoint()], [{reporter_name(), datapoint()}], exometer:status()}]} | {error, any()}

Equivalent to list_metrics([]).

list_metrics/1


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/0


list_reporters() -> [{reporter_name(), pid()}]

List the name and pid of each known reporter.

list_subscriptions/1


list_subscriptions(Reporter::reporter_name()) -> [{metric(), datapoint(), interval(), extra()}]

List all subscriptions for Reporter.

new_entry/1


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/1


remove_reporter(Reporter::reporter_name()) -> ok | {error, any()}

Remove reporter and all its subscriptions.

remove_reporter/2


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/1


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/3


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/3


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/0


start_link() -> {ok, pid()} | ignore | {error, any()}

Starts the server

start_reporters/0

start_reporters() -> any()

subscribe/4


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/5


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/6


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/1

terminate_reporter(Reporter) -> any()

trigger_interval/2


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/3


unsubscribe(Reporter::module(), Metric::metric(), DataPoint::datapoint()) -> ok | not_found

Equivalent to unsubscribe(Reporter, Metric, DataPoint, []).

unsubscribe/4


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/2


unsubscribe_all(Reporter::module(), Metric::metric()) -> ok

Removes all subscriptions related to Metric in Reporter.