Packages

Statman to the rescue!

Current section

Files

Jump to
statman src statman_gauge.erl
Raw

src/statman_gauge.erl

-module(statman_gauge).
-export([init/0, expire/0, get_all/0]).
-export([set/2, incr/1, incr/2, decr/1, decr/2]).
-include_lib("eunit/include/eunit.hrl").
-define(TABLE, statman_gauges).
init() ->
ets:new(?TABLE, [named_table, public, set, {write_concurrency, true}]),
ok.
set(Key, Value) when is_integer(Value) orelse is_float(Value) ->
set(Key, Value, now_to_seconds()).
set(Key, Value, Timestamp) ->
(catch ets:insert(?TABLE, {Key, Timestamp, Value})),
ok.
incr(Key) -> incr(Key, 1).
decr(Key) -> incr(Key, -1).
decr(Key, Decr) -> incr(Key, -Decr).
incr(Key, Incr) ->
case catch ets:update_counter(?TABLE, Key, {3, Incr}) of
{'EXIT', {badarg, _}} ->
set(Key, Incr),
ok;
_ ->
ets:update_element(?TABLE, Key, {2, now_to_seconds()}),
ok
end.
expire() ->
expire(now_to_seconds() - 60).
%% @doc: Deletes any gauges that has not been updated since the given
%% threshold.
expire(Threshold) ->
ets:select_delete(?TABLE, [{{'_', '$1', '_'}, [{'<', '$1', Threshold}], [true]}]).
get_all() ->
ets:select(?TABLE, [{ {'$1', '_', '$2'}, [], [{{'$1', '$2'}}]}]).
now_to_seconds() ->
{MegaSeconds, Seconds, _} = os:timestamp(),
MegaSeconds * 1000000 + Seconds.
%%
%% TESTS
%%
gauge_test_() ->
{foreach,
fun setup/0, fun teardown/1,
[
?_test(test_expire()),
?_test(test_expire_incr_decr()),
?_test(test_set_incr())
]
}.
setup() ->
init(),
[?TABLE].
teardown(Tables) ->
lists:map(fun ets:delete/1, Tables).
test_expire() ->
?assertEqual([], get_all()),
set(foo, 30, now_to_seconds() - 3),
?assertEqual([{foo, 30}], get_all()),
?assertEqual(0, expire(now_to_seconds() - 5)),
?assertEqual(1, expire(now_to_seconds() - 0)),
?assertEqual([], get_all()).
test_expire_incr_decr() ->
?assertEqual([], get_all()),
ok = set(problems, 100, now_to_seconds() - 3),
ok = decr(problems),
?assertEqual([{problems, 99}], get_all()),
?assertEqual(0, expire(now_to_seconds()-1)),
?assertEqual([{problems, 99}], get_all()).
test_set_incr() ->
incr(foo, 2),
?assertEqual([{foo, 2}], get_all()),
set(foo, 10),
incr(foo),
incr(foo),
?assertEqual([{foo, 12}], get_all()),
decr(foo),
?assertEqual([{foo, 11}], get_all()).