Skip to content

Commit

Permalink
Merge pull request Feuerlabs#75 from Feuerlabs/uw-rewritten-reporter
Browse files Browse the repository at this point in the history
exometer_report keeps state in ets
  • Loading branch information
uwiger committed Aug 20, 2014
2 parents 1f5eb8c + 9223abc commit 8d73c3a
Show file tree
Hide file tree
Showing 9 changed files with 780 additions and 340 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

__Version:__ Aug 5 2014 16:25:27
__Version:__ Aug 18 2014 16:34:44

__Authors:__ Ulf Wiger ([`[email protected]`](mailto:[email protected])), Magnus Feuer ([`[email protected]`](mailto:[email protected])).

Expand Down
2 changes: 1 addition & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

__Version:__ Aug 5 2014 16:25:27
__Version:__ Aug 18 2014 16:34:44

__Authors:__ Ulf Wiger ([`[email protected]`](mailto:[email protected])), Magnus Feuer ([`[email protected]`](mailto:[email protected])).

Expand Down
131 changes: 123 additions & 8 deletions doc/exometer_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,14 @@ as a list of atoms.



+ `DataPoint`<br />Specifies the data point within the subscribed-to metric as an atom, or a list of atoms.
+ `DataPoint`<br />Specifies the data point within the subscribed-to metric
as an atom, or a list of atoms.



+ `Interval`<br />Specifies the interval, in milliseconds, that the subscribed-to
value will be reported at.
+ `Interval`<br />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.



Expand Down Expand Up @@ -240,6 +242,30 @@ datapoint() = atom()



### <a name="type-delay">delay()</a> ###



<pre><code>
delay() = <a href="#type-time_ms">time_ms()</a>
</code></pre>





### <a name="type-error">error()</a> ###



<pre><code>
error() = {error, any()}
</code></pre>





### <a name="type-extra">extra()</a> ###


Expand All @@ -257,7 +283,7 @@ extra() = any()


<pre><code>
interval() = pos_integer()
interval() = pos_integer() | atom()
</code></pre>


Expand Down Expand Up @@ -299,12 +325,24 @@ reporter_name() = atom()


Restart specification



### <a name="type-time_ms">time_ms()</a> ###



<pre><code>
time_ms() = pos_integer()
</code></pre>


<a name="index"></a>

## 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>Add a reporter.</td></tr><tr><td valign="top"><a href="#call_reporter-2">call_reporter/2</a></td><td>Send a custom (synchronous) call to <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#cast_reporter-2">cast_reporter/2</a></td><td>Send a custom (asynchronous) cast to <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#disable_me-2">disable_me/2</a></td><td>Used by a reporter to disable itself.</td></tr><tr><td valign="top"><a href="#disable_reporter-1">disable_reporter/1</a></td><td>Disable <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#enable_reporter-1">enable_reporter/1</a></td><td>Enable <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#list_metrics-0">list_metrics/0</a></td><td>Equivalent to <a href="#list_metrics-1"><tt>list_metrics([])</tt></a>.</td></tr><tr><td valign="top"><a href="#list_metrics-1">list_metrics/1</a></td><td>List all metrics matching <code>Path</code>, together with subscription status.</td></tr><tr><td valign="top"><a href="#list_reporters-0">list_reporters/0</a></td><td>List the name and pid of each known reporter.</td></tr><tr><td valign="top"><a href="#list_subscriptions-1">list_subscriptions/1</a></td><td>List all subscriptions for <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#new_entry-1">new_entry/1</a></td><td>Called by exometer whenever a new entry is created.</td></tr><tr><td valign="top"><a href="#remove_reporter-1">remove_reporter/1</a></td><td>Remove reporter and all its subscriptions.</td></tr><tr><td valign="top"><a href="#remove_reporter-2">remove_reporter/2</a></td><td>Remove <code>Reporter</code> (non-blocking call).</td></tr><tr><td valign="top"><a href="#setopts-3">setopts/3</a></td><td>Called by exometer when options of a metric entry are changed.</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>Add a reporter.</td></tr><tr><td valign="top"><a href="#call_reporter-2">call_reporter/2</a></td><td>Send a custom (synchronous) call to <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#cast_reporter-2">cast_reporter/2</a></td><td>Send a custom (asynchronous) cast to <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#delete_interval-2">delete_interval/2</a></td><td>Delete a named interval.</td></tr><tr><td valign="top"><a href="#disable_me-2">disable_me/2</a></td><td>Used by a reporter to disable itself.</td></tr><tr><td valign="top"><a href="#disable_reporter-1">disable_reporter/1</a></td><td>Disable <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#enable_reporter-1">enable_reporter/1</a></td><td>Enable <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#get_intervals-1">get_intervals/1</a></td><td>List the named intervals for <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#list_metrics-0">list_metrics/0</a></td><td>Equivalent to <a href="#list_metrics-1"><tt>list_metrics([])</tt></a>.</td></tr><tr><td valign="top"><a href="#list_metrics-1">list_metrics/1</a></td><td>List all metrics matching <code>Path</code>, together with subscription status.</td></tr><tr><td valign="top"><a href="#list_reporters-0">list_reporters/0</a></td><td>List the name and pid of each known reporter.</td></tr><tr><td valign="top"><a href="#list_subscriptions-1">list_subscriptions/1</a></td><td>List all subscriptions for <code>Reporter</code>.</td></tr><tr><td valign="top"><a href="#new_entry-1">new_entry/1</a></td><td>Called by exometer whenever a new entry is created.</td></tr><tr><td valign="top"><a href="#remove_reporter-1">remove_reporter/1</a></td><td>Remove reporter and all its subscriptions.</td></tr><tr><td valign="top"><a href="#remove_reporter-2">remove_reporter/2</a></td><td>Remove <code>Reporter</code> (non-blocking call).</td></tr><tr><td valign="top"><a href="#restart_intervals-1">restart_intervals/1</a></td><td>Restart all named intervals, respecting specified delays.</td></tr><tr><td valign="top"><a href="#set_interval-3">set_interval/3</a></td><td>Specify a named interval.</td></tr><tr><td valign="top"><a href="#setopts-3">setopts/3</a></td><td>Called by exometer when options of a metric entry are changed.</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="#start_reporters-0">start_reporters/0</a></td><td></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 @@ -337,11 +375,23 @@ additional options.
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()}
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.
<a name="call_reporter-2"></a>

### call_reporter/2 ###
Expand Down Expand Up @@ -374,6 +424,18 @@ 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.
<a name="delete_interval-2"></a>

### delete_interval/2 ###


<pre><code>
delete_interval(Reporter::<a href="#type-reporter_name">reporter_name()</a>, Name::atom()) -&gt; ok | <a href="#type-error">error()</a>
</code></pre>
<br />

Delete a named interval.

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

### disable_me/2 ###
Expand Down Expand Up @@ -429,6 +491,17 @@ a restart.


If the reporter was already enabled, nothing is changed.
<a name="get_intervals-1"></a>

### get_intervals/1 ###


<pre><code>
get_intervals(Reporter::<a href="#type-reporter_name">reporter_name()</a>) -&gt; [{atom(), [{time, pos_integer()} | {delay, pos_integer()} | {timer_ref, reference()}]}]
</code></pre>
<br />

List the named intervals for `Reporter`.
<a name="list_metrics-0"></a>

### list_metrics/0 ###
Expand Down Expand Up @@ -527,6 +600,45 @@ 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.
<a name="restart_intervals-1"></a>

### restart_intervals/1 ###


<pre><code>
restart_intervals(Reporter::<a href="#type-reporter_name">reporter_name()</a>) -&gt; ok
</code></pre>
<br />


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.
<a name="set_interval-3"></a>

### set_interval/3 ###


<pre><code>
set_interval(Reporter::<a href="#type-reporter_name">reporter_name()</a>, Name::atom(), Time::<a href="#type-time_ms">time_ms()</a> | {<a href="#type-time_ms">time_ms()</a>, <a href="#type-delay">delay()</a>}) -&gt; ok | <a href="#type-error">error()</a>
</code></pre>
<br />


Specify a named interval.



See [`add_reporter/2`](#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.


If the named interval exists, it will be replaced with the new definition.
Otherwise, it will be added. Use [`restart_intervals/1`](#restart_intervals-1) if you want
all intervals to be restarted/resynched with corresponding relative delays.
<a name="setopts-3"></a>

### setopts/3 ###
Expand Down Expand Up @@ -594,7 +706,10 @@ is either a single data point (an atom) or a list of data points (a list).



`Interval` is the sampling/reporting interval in milliseconds.
`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: `[]`).
Expand Down Expand Up @@ -634,8 +749,8 @@ 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`](#list_subscriptions-1).
`{Reporter, Metric, DataPoint, Extra}`. The exact information can be
extracted using [`list_subscriptions/1`](#list_subscriptions-1).
<a name="unsubscribe_all-2"></a>

### unsubscribe_all/2 ###
Expand Down
2 changes: 2 additions & 0 deletions include/exometer.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

-define(EXOMETER_SHARED, exometer_shared).
-define(EXOMETER_ENTRIES, exometer_entries).
-define(EXOMETER_SUBS, exometer_subscriptions).
-define(EXOMETER_REPORTERS, exometer_reporters).

-record(exometer_event, {
time = exometer_util:timestamp(),
Expand Down
17 changes: 16 additions & 1 deletion src/exometer_admin.erl
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,19 @@ terminate(_, _) ->
ok.

code_change(_, S, _) ->
case ets:info(?EXOMETER_REPORTERS, name) of
undefined -> create_reporter_tabs();
_ -> ok
end,
{ok, S}.

create_reporter_tabs() ->
Heir = {heir, whereis(exometer_sup), []},
ets:new(?EXOMETER_REPORTERS, [public, named_table, set,
{keypos, 2}, Heir]),
ets:new(?EXOMETER_SUBS, [public, named_table, ordered_set,
{keypos, 2}, Heir]).


create_ets_tabs() ->
case ets:info(?EXOMETER_SHARED, name) of
Expand All @@ -344,7 +355,11 @@ create_ets_tabs() ->
ets:new(?EXOMETER_SHARED, [public, named_table, ordered_set,
{keypos, 2}]),
ets:new(?EXOMETER_ENTRIES, [public, named_table, ordered_set,
{keypos, 2}]);
{keypos, 2}]),
ets:new(?EXOMETER_REPORTERS, [public, named_table, set,
{keypos, 2}]),
ets:new(?EXOMETER_SUBS, [public, named_table, ordered_set,
{keypos, 2}]);
_ ->
true
end.
Expand Down
14 changes: 14 additions & 0 deletions src/exometer_function.erl
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,8 @@ e(A, _) when is_atom(A) -> A;
e({T,I}, _) when T==i; T==integer -> I;
e({T,A}, _) when T==a; T==atom -> A;
e({cons,Eh,Et}, Bs) -> [e(Eh, Bs)|e(Et, Bs)];
e({hd,E}, Bs) -> hd(e(E, Bs));
e({tl,E}, Bs) -> tl(e(E, Bs));
e({l, Es}, Bs) -> [e(E, Bs) || E <- Es];
e({T,S}, _) when T==s; T==string -> S;
e({T,Es}, Bs) when T==t; T==tuple -> list_to_tuple([e(E,Bs) || E <- Es]);
Expand Down Expand Up @@ -651,6 +653,18 @@ call1(length , [L]) -> length(L);
call1(size , [T]) -> size(T);
call1(byte_size, [B]) -> byte_size(B);
call1(bit_size , [B]) -> bit_size(B);
call1(tuple_to_list , [T]) -> tuple_to_list(T);
call1(list_to_tuple , [L]) -> list_to_tuple(L);
call1(atom_to_list , [A]) -> atom_to_list(A);
call1(list_to_atom , [L]) -> list_to_atom(L);
call1(list_to_binary, [L]) -> list_to_binary(L);
call1(binary_to_list, [B]) -> binary_to_list(B);
call1(t2l, [T]) -> tuple_to_list(T);
call1(l2t, [L]) -> list_to_tuple(L);
call1(a2l, [A]) -> atom_to_list(A);
call1(l2a, [L]) -> list_to_atom(L);
call1(l2b, [L]) -> list_to_binary(L);
call1(b2l, [B]) -> binary_to_list(B);
call1({M,F}, As) when is_atom(M), is_atom(F) ->
apply(M, F, As).

Expand Down
Loading

0 comments on commit 8d73c3a

Please sign in to comment.