Skip to content

Commit

Permalink
Allow {apply, {M, F, A}} in static subscribers list
Browse files Browse the repository at this point in the history
The result of apply(M,F,A) must be a list of legal subscriber
tuples (including possibly {apply, {M,F,A}}.
  • Loading branch information
uwiger authored and Tino Breddin committed Apr 7, 2014
1 parent 5bd65d1 commit 5fc9ec6
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 27 deletions.
45 changes: 31 additions & 14 deletions README.md
Expand Up @@ -4,7 +4,7 @@

Copyright (c) 2014 Basho Technologies, Inc. All Rights Reserved.

__Version:__ Mar 5 2014 11:56:38
__Version:__ Mar 19 2014 23:14:26

__Authors:__ Ulf Wiger ([`ulf.wiger@feuerlabs.com`](mailto:ulf.wiger@feuerlabs.com)), Magnus Feuer ([`magnus.feuer@feuerlabs.com`](mailto:magnus.feuer@feuerlabs.com)).

Expand Down Expand Up @@ -659,8 +659,8 @@ Below is an example, from `exometer/priv/app.config`:
```erlang

{exometer, [
{report, [
{subscribers, [
{report, [
{subscribers, [
{exometer_report_collectd, [db, cache, hits], mean, 2000, true},
{exometer_report_collectd, [db, cache, hits], max, 5000, false}
]}
Expand All @@ -674,36 +674,53 @@ how to configure individual plugins.

The `subscribers` sub-section contains all static subscriptions to be
setup att exometer applications start. Each tuple in the prop list
contains five elements:
should be of one of the following formats:

`{Reporter, Metric, DataPoint, Interval}`
`{Reporter, Metric, DataPoint, Interval, RetryFailedMetrics}`
`{Reporter, Metric, DataPoint, Interval, RetryFailedMetrics, Extra}`
`{apply, {M, F, A}}`

In the case of `{apply, M, F, A}`, the result of `apply(M, F, A)` must
be a list of `subscribers` tuples.

The meaning of the above tuple elements is:

+ `receiver` (module name atom)
+ `Reporter :: module()`
<br></br>
Specifies the reporter plugin module, such as`exometer_report_collectd` that is to receive updated metric's data
points.

+ `name` (list of atoms)
+ `Metric :: [atoms()]`
<br></br>
Specifies the path to a metric previously created with an`exometer:new()` call.

+ `datapoint` (atom)
+ `DataPoint` :: atom() | [atom()]'
<br></br>
Specifies the data point within the given metric to send to the
receiver. The data point must match one of the data points returned by`exometer:info(Name, datapoints)` for the given metrics name.

+ `interval` (milliseconds)
+ `Interval` :: integer()' (milliseconds)
<br></br>
Specifies the interval, in milliseconds, between each update of the
given metric's data point. At the given interval, the data point will
be samples, and the result will be sent to the receiver.

+ `retry_failed_metrics (true | false)`
+ `RetryFailedMetrics :: boolean()`
<br></br>
Specifies if the metric should be continued to be reported
even if it is not found during a reporting cycle. This would be
the case if a metric is not created by the time it is reported for
the first time. If the metric will be created at a later time,
this value should be set to true. Set this value to false if all
attempts to report the metric should stop if when is not found.
even if it is not found during a reporting cycle. This would be
the case if a metric is not created by the time it is reported for
the first time. If the metric will be created at a later time,
this value should be set to true. Set this value to false if all
attempts to report the metric should stop if when is not found.
The default value is `true`.

+ `Extra :: any()`
<br></br>
Provides a means to pass along extra information for a given
subscription. An example is the `syntax` option for the SNMP reporter,
in which case `Extra` needs to be a property list.


#### <a name="Configuring_reporter_plugins">Configuring reporter plugins</a> ####
Expand Down
1 change: 0 additions & 1 deletion doc/edoc-info
@@ -1,4 +1,3 @@
%% encoding: UTF-8
{application,exometer}.
{packages,[]}.
{modules,[exometer,exometer_admin,exometer_cache,exometer_cpu,
Expand Down
11 changes: 9 additions & 2 deletions doc/exometer_function.md
Expand Up @@ -148,7 +148,7 @@ simple_fun() = {function, <a href="#type-mod_name">mod_name()</a>, <a href="#typ
## Function Index ##


<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#behaviour-0">behaviour/0</a></td><td></td></tr><tr><td valign="top"><a href="#delete-3">delete/3</a></td><td></td></tr><tr><td valign="top"><a href="#empty-0">empty/0</a></td><td></td></tr><tr><td valign="top"><a href="#get_datapoints-3">get_datapoints/3</a></td><td></td></tr><tr><td valign="top"><a href="#get_value-4">get_value/4</a></td><td></td></tr><tr><td valign="top"><a href="#new-3">new/3</a></td><td>Callback for creating an exometer <code>function</code> entry.</td></tr><tr><td valign="top"><a href="#reset-3">reset/3</a></td><td></td></tr><tr><td valign="top"><a href="#sample-3">sample/3</a></td><td></td></tr><tr><td valign="top"><a href="#setopts-4">setopts/4</a></td><td></td></tr><tr><td valign="top"><a href="#test_mem_info-1">test_mem_info/1</a></td><td></td></tr><tr><td valign="top"><a href="#update-4">update/4</a></td><td></td></tr></table>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#behaviour-0">behaviour/0</a></td><td></td></tr><tr><td valign="top"><a href="#delete-3">delete/3</a></td><td></td></tr><tr><td valign="top"><a href="#empty-0">empty/0</a></td><td></td></tr><tr><td valign="top"><a href="#get_datapoints-3">get_datapoints/3</a></td><td></td></tr><tr><td valign="top"><a href="#get_value-4">get_value/4</a></td><td></td></tr><tr><td valign="top"><a href="#new-3">new/3</a></td><td>Callback for creating an exometer <code>function</code> entry.</td></tr><tr><td valign="top"><a href="#preprocess_setopts-5">preprocess_setopts/5</a></td><td></td></tr><tr><td valign="top"><a href="#reset-3">reset/3</a></td><td></td></tr><tr><td valign="top"><a href="#sample-3">sample/3</a></td><td></td></tr><tr><td valign="top"><a href="#setopts-4">setopts/4</a></td><td></td></tr><tr><td valign="top"><a href="#test_mem_info-1">test_mem_info/1</a></td><td></td></tr><tr><td valign="top"><a href="#update-4">update/4</a></td><td></td></tr></table>


<a name="functions"></a>
Expand Down Expand Up @@ -193,7 +193,7 @@ behaviour() -&gt; atom()

### get_value/4 ###

`get_value(X1, X2, X3, DataPoints) -> any()`
`get_value(X1, X2, X3, DataPoints0) -> any()`


<a name="new-3"></a>
Expand Down Expand Up @@ -338,6 +338,13 @@ An entry that does pattern-matching on the return value
match, {gcs,reclaimed,'_'} }, []).
```

<a name="preprocess_setopts-5"></a>

### preprocess_setopts/5 ###

`preprocess_setopts(Name, Opts, Type, Ref, OldOpts) -> any()`


<a name="reset-3"></a>

### reset/3 ###
Expand Down
11 changes: 10 additions & 1 deletion doc/exometer_report.md
Expand Up @@ -282,6 +282,8 @@ extra() = any()



Restart specification



### <a name="type-interval">interval()</a> ###
Expand Down Expand Up @@ -310,7 +312,7 @@ metric() = [atom(), ...]
## Function Index ##


<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#add_reporter-2">add_reporter/2</a></td><td></td></tr><tr><td valign="top"><a href="#call_reporter-2">call_reporter/2</a></td><td></td></tr><tr><td valign="top"><a href="#cast_reporter-2">cast_reporter/2</a></td><td></td></tr><tr><td valign="top"><a href="#list_metrics-0">list_metrics/0</a></td><td></td></tr><tr><td valign="top"><a href="#list_metrics-1">list_metrics/1</a></td><td></td></tr><tr><td valign="top"><a href="#list_reporters-0">list_reporters/0</a></td><td></td></tr><tr><td valign="top"><a href="#list_subscriptions-1">list_subscriptions/1</a></td><td></td></tr><tr><td valign="top"><a href="#new_entry-1">new_entry/1</a></td><td></td></tr><tr><td valign="top"><a href="#remove_reporter-1">remove_reporter/1</a></td><td></td></tr><tr><td valign="top"><a href="#setopts-3">setopts/3</a></td><td></td></tr><tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td>Starts the server
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#add_reporter-2">add_reporter/2</a></td><td></td></tr><tr><td valign="top"><a href="#call_reporter-2">call_reporter/2</a></td><td></td></tr><tr><td valign="top"><a href="#cast_reporter-2">cast_reporter/2</a></td><td></td></tr><tr><td valign="top"><a href="#list_metrics-0">list_metrics/0</a></td><td></td></tr><tr><td valign="top"><a href="#list_metrics-1">list_metrics/1</a></td><td></td></tr><tr><td valign="top"><a href="#list_reporters-0">list_reporters/0</a></td><td></td></tr><tr><td valign="top"><a href="#list_subscriptions-1">list_subscriptions/1</a></td><td></td></tr><tr><td valign="top"><a href="#new_entry-1">new_entry/1</a></td><td></td></tr><tr><td valign="top"><a href="#remove_reporter-1">remove_reporter/1</a></td><td></td></tr><tr><td valign="top"><a href="#remove_reporter-2">remove_reporter/2</a></td><td></td></tr><tr><td valign="top"><a href="#setopts-3">setopts/3</a></td><td></td></tr><tr><td valign="top"><a href="#start_link-0">start_link/0</a></td><td>Starts the server
--------------------------------------------------------------------.</td></tr><tr><td valign="top"><a href="#subscribe-4">subscribe/4</a></td><td>Equivalent to <a href="#subscribe-5"><tt>subscribe(Reporter, Metric, DataPoint, Interval, [])</tt></a>.</td></tr><tr><td valign="top"><a href="#subscribe-5">subscribe/5</a></td><td>Add a subscription to an existing reporter.</td></tr><tr><td valign="top"><a href="#terminate_reporter-1">terminate_reporter/1</a></td><td></td></tr><tr><td valign="top"><a href="#unsubscribe-3">unsubscribe/3</a></td><td>Equivalent to <a href="#unsubscribe-4"><tt>unsubscribe(Reporter, Metric, DataPoint, [])</tt></a>.</td></tr><tr><td valign="top"><a href="#unsubscribe-4">unsubscribe/4</a></td><td>Removes a subscription.</td></tr><tr><td valign="top"><a href="#unsubscribe_all-2">unsubscribe_all/2</a></td><td>Removes all subscriptions related to Metric in Reporter.</td></tr></table>


Expand Down Expand Up @@ -405,6 +407,13 @@ list_subscriptions(Reporter::module()) -&gt; [{<a href="#type-metric">metric()</
`remove_reporter(Reporter) -> any()`


<a name="remove_reporter-2"></a>

### remove_reporter/2 ###

`remove_reporter(Reporter, Reason) -> any()`


<a name="setopts-3"></a>

### setopts/3 ###
Expand Down
2 changes: 1 addition & 1 deletion doc/exometer_report_snmp.md
Expand Up @@ -100,7 +100,7 @@ Callback function used by the SNMP master agent upon operations performed by a m

### exometer_setopts/4 ###

`exometer_setopts(Metric, Options, X3, St0) -> any()`
`exometer_setopts(Exometer_entry, Options, X3, St0) -> any()`


<a name="exometer_subscribe-5"></a>
Expand Down
31 changes: 23 additions & 8 deletions doc/overview.edoc
Expand Up @@ -571,8 +571,8 @@ Below is an example, from `exometer/priv/app.config':

<pre lang="erlang">
{exometer, [
{report, [
{subscribers, [
{report, [
{subscribers, [
{exometer_report_collectd, [db, cache, hits], mean, 2000, true},
{exometer_report_collectd, [db, cache, hits], max, 5000, false}
]}
Expand All @@ -585,35 +585,50 @@ how to configure individual plugins.

The `subscribers' sub-section contains all static subscriptions to be
setup att exometer applications start. Each tuple in the prop list
contains five elements:
should be of one of the following formats:

`{Reporter, Metric, DataPoint, Interval}'
`{Reporter, Metric, DataPoint, Interval, RetryFailedMetrics}'
`{Reporter, Metric, DataPoint, Interval, RetryFailedMetrics, Extra}'
`{apply, {M, F, A}}'

In the case of `{apply, M, F, A}', the result of `apply(M, F, A)' must
be a list of `subscribers' tuples.

The meaning of the above tuple elements is:

+ `receiver' (module name atom)
+ `Reporter :: module()'
<br/>Specifies the reporter plugin module, such as
`exometer_report_collectd' that is to receive updated metric's data
points.

+ `name' (list of atoms)
+ `Metric :: [atoms()]'
<br/>Specifies the path to a metric previously created with an
`exometer:new()' call.

+ `datapoint' (atom)
+ `DataPoint' :: atom() | [atom()]'
<br/>Specifies the data point within the given metric to send to the
receiver. The data point must match one of the data points returned by
`exometer:info(Name, datapoints)' for the given metrics name.

+ `interval' (milliseconds)
+ `Interval' :: integer()' (milliseconds)
<br/>Specifies the interval, in milliseconds, between each update of the
given metric's data point. At the given interval, the data point will
be samples, and the result will be sent to the receiver.

+ `retry_failed_metrics (true | false)'
+ `RetryFailedMetrics :: boolean()'
<br/>Specifies if the metric should be continued to be reported
even if it is not found during a reporting cycle. This would be
the case if a metric is not created by the time it is reported for
the first time. If the metric will be created at a later time,
this value should be set to true. Set this value to false if all
attempts to report the metric should stop if when is not found.
The default value is `true'.

+ `Extra :: any()'
<br/>Provides a means to pass along extra information for a given
subscription. An example is the `syntax' option for the SNMP reporter,
in which case `Extra' needs to be a property list.


=== Configuring reporter plugins ===
Expand Down
4 changes: 4 additions & 0 deletions src/exometer_report.erl
Expand Up @@ -918,6 +918,10 @@ init_subscriber({Reporter, Metric, DataPoint, Interval, RetryFailedMetrics, Extr

init_subscriber({Reporter, Metric, DataPoint, Interval}, Acc) ->
[subscribe_(Reporter, Metric, DataPoint, Interval, true, undefined) | Acc];

init_subscriber({apply, {M, F, A}}, Acc) ->
lists:foldr(fun init_subscriber/2, Acc, apply(M, F, A));

init_subscriber(Other, Acc) ->
?warning("Incorrect static subscriber spec ~p. "
"Use { Reporter, Metric, DataPoint, Interval [, Extra ]}~n", [ Other ]),
Expand Down

0 comments on commit 5fc9ec6

Please sign in to comment.