Skip to content

Commit

Permalink
Added grouped/tagged metrics feature
Browse files Browse the repository at this point in the history
  • Loading branch information
viveshok committed Jan 25, 2013
1 parent ec3c29c commit 81f523a
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 2 deletions.
17 changes: 17 additions & 0 deletions README.md
Expand Up @@ -141,6 +141,23 @@ Meter readers are like a meter except that the values passed to it are monotonic
> folsom_metrics:new_meter_reader(Name).
> folsom_metrics:notify({Name, Value}).

##### Metrics groups/tags

Certain users might want to group and query metrics monitoring a common task. In order to do so, they can
tag metrics:

> folsom_metrics:tag_metric(Name, Tag).

and query a list of tuples `[{Name, Value}]` of all metrics with a given tag:

> folsom_metrics:get_metrics_value(Tag).

If only a certain type of metrics from a given group is desired, one can specify so:

> folsom_metrics:get_metrics_value(Tag, Type).

where Type is one of `counter`, `gauge`, `histogram`, `history`, `meter`, `meter_reader`, `duration` or `spiral`.

##### Erlang VM

folsom also produces Erlang VM statistics.
Expand Down
37 changes: 35 additions & 2 deletions src/folsom_ets.erl
Expand Up @@ -29,6 +29,7 @@
add_handler/3,
add_handler/4,
add_handler/5,
tag_handler/2,
delete_handler/1,
handler_exists/1,
notify/1,
Expand All @@ -39,11 +40,13 @@
get_handlers_info/0,
get_info/1,
get_values/1,
get_history_values/2
get_history_values/2,
get_group_values/1,
get_group_values/2
]).

-record(metric, {
tags = [],
tags = sets:new(),
type,
history_size
}).
Expand All @@ -66,6 +69,14 @@ add_handler(Type, Name, SampleType, SampleSize) ->
add_handler(Type, Name, SampleType, SampleSize, Alpha) ->
maybe_add_handler(Type, Name, SampleType, SampleSize, Alpha, handler_exists(Name)).

tag_handler(Name, Tag) ->
case handler_exists(Name) of
true ->
add_tag(Name, Tag);
false ->
{error, Name, nonexistent_metric}
end.

delete_handler(Name) ->
{_, Info} = get_info(Name),
ok = delete_metric(Name, proplists:get_value(type, Info)).
Expand Down Expand Up @@ -148,6 +159,12 @@ get_values(_, Type) ->
get_history_values(Name, Count) ->
folsom_metrics_history:get_events(Name, Count).

get_group_values(Tag) ->
[{Name, get_values(Name)} || Name <- get_handlers(), has_tag(Name, Tag)].

get_group_values(Tag, Type) ->
[{Name, get_values(Name)} || Name <- get_handlers(), has_tag(Name, Tag), has_type(Name, Type)].

%%%===================================================================
%%% Internal functions
%%%===================================================================
Expand Down Expand Up @@ -228,6 +245,22 @@ maybe_add_handler(Type, _, _, _, _, false) ->
maybe_add_handler(_, Name, _, _, _, true) ->
{error, Name, metric_already_exists}.

add_tag(Name, Tag) ->
OldMetric = ets:lookup_element(?FOLSOM_TABLE, Name, 2),
NewMetric = OldMetric#metric{tags=sets:add_element(Tag, get_tags(Name))},
true = ets:update_element(?FOLSOM_TABLE, Name, {2, NewMetric}),
ok.

get_tags(Name) ->
Metric = ets:lookup_element(?FOLSOM_TABLE, Name, 2),
Metric#metric.tags.

has_tag(Name, Tag) ->
sets:is_element(Tag, get_tags(Name)).

has_type(Name, Type) ->
{Name, [{type, Type}]} =:= get_info(Name).

delete_metric(Name, history) ->
History = folsom_metrics_history:get_value(Name),
ok = delete_history(Name, History),
Expand Down
12 changes: 12 additions & 0 deletions src/folsom_metrics.erl
Expand Up @@ -41,6 +41,7 @@
new_duration/4,
new_spiral/1,
delete_metric/1,
tag_metric/2,
notify/1,
notify/2,
notify/3,
Expand All @@ -51,6 +52,8 @@
get_metrics/0,
metric_exists/1,
get_metrics_info/0,
get_metrics_value/1,
get_metrics_value/2,
get_metric_info/1,
get_metric_value/1,
get_histogram_statistics/1,
Expand Down Expand Up @@ -112,6 +115,9 @@ new_duration(Name, SampleType, SampleSize, Alpha) ->
new_spiral(Name) ->
folsom_ets:add_handler(spiral, Name).

tag_metric(Name, Tag) ->
folsom_ets:tag_handler(Name, Tag).

delete_metric(Name) ->
folsom_ets:delete_handler(Name).

Expand Down Expand Up @@ -145,6 +151,12 @@ metric_exists(Name) ->
get_metrics_info() ->
folsom_ets:get_handlers_info().

get_metrics_value(Tag) ->
folsom_ets:get_group_values(Tag).

get_metrics_value(Tag, Type) ->
folsom_ets:get_group_values(Tag, Type).

get_metric_info(Name) ->
[folsom_ets:get_info(Name)].

Expand Down
37 changes: 37 additions & 0 deletions test/folsom_erlang_checks.erl
Expand Up @@ -29,7 +29,9 @@
-export([
create_metrics/0,
populate_metrics/0,
tag_metrics/0,
check_metrics/0,
check_group_metrics/0,
delete_metrics/0,
vm_metrics/0,
counter_metric/2,
Expand Down Expand Up @@ -87,6 +89,15 @@ create_metrics() ->

?debugFmt("~n~nmetrics: ~p~n", [folsom_metrics:get_metrics()]).

tag_metrics() ->
Group = "mygroup",
ok = folsom_metrics:tag_metric(counter, Group),
ok = folsom_metrics:tag_metric(counter2, Group),
ok = folsom_metrics:tag_metric(<<"gauge">>, Group),
ok = folsom_metrics:tag_metric(meter, Group),
ok = folsom_metrics:tag_metric(spiral, Group),
?debugFmt("~n~ntagged metrics: ~p, ~p, ~p, ~p and ~p in group ~p~n", [counter,counter2,<<"gauge">>,meter,spiral,Group]).

populate_metrics() ->
ok = folsom_metrics:notify({counter, {inc, 1}}),
ok = folsom_metrics:notify({counter, {dec, 1}}),
Expand Down Expand Up @@ -229,6 +240,32 @@ check_metrics() ->
%% check spiral
[{count, 100}, {one, 100}] = folsom_metrics:get_metric_value(spiral).

check_group_metrics() ->
Metrics = get_metrics_value("mygroup"),
5 = length(Metrics),
{counter, 0} = lists:keyfind(counter,1,Metrics),
{counter2, 0} = lists:keyfind(counter2,1,Metrics),
{<<"gauge">>, 2} = lists:keyfind(<<"gauge">>,1,Metrics),

{meter, Meter} = lists:keyfind(meter,1,Metrics),
ok = case proplists:get_value(one, Meter) of
Value when Value > 1 ->
ok;
_ ->
error
end,
ok = case proplists:get_value(day, Meter) of
Value1 when Value1 > 0.005 ->
ok;
_ ->
error
end,

{spiral, [{count, 100}, {one, 100}]} = lists:keyfind(spiral,1,Metrics),

Counters = get_metrics_value("mygroup",counter),
{counter, 0} = lists:keyfind(counter,1,Counters),
{counter2, 0} = lists:keyfind(counter2,1,Counters).

delete_metrics() ->
17 = length(ets:tab2list(?FOLSOM_TABLE)),
Expand Down
4 changes: 4 additions & 0 deletions test/folsom_tests.erl
Expand Up @@ -32,6 +32,8 @@ run_test_() ->
fun (_) -> folsom:stop() end,
[{"creating metrics",
fun folsom_erlang_checks:create_metrics/0},
{"tagging metrics",
fun folsom_erlang_checks:tag_metrics/0},
{"populating metrics",
{timeout, 30, fun folsom_erlang_checks:populate_metrics/0}},
{"checking metrics",
Expand All @@ -40,6 +42,8 @@ run_test_() ->
fun () ->
folsom_erlang_checks:counter_metric(10000, testcounter)
end},
{"checking group metrics",
fun folsom_erlang_checks:check_group_metrics/0},
{"checking erlang vm metrics",
fun folsom_erlang_checks:vm_metrics/0},
{"deleting metrics",
Expand Down

0 comments on commit 81f523a

Please sign in to comment.