Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gauge support and remove Sampling section from README #1

Merged
merged 2 commits into from
Apr 10, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ application environment vars. See estatsd_sup for details.

The following calls to estatsd are all gen_server:cast, ie non-blocking.

Gauges
--------

estatsd:gauge(temperature, 45). %% set temperature to 45

Counters
--------

Expand All @@ -48,13 +53,6 @@ Or for your convenience:
do_sometask(),
estatsd:timing(sometast, Start). %% uses now() and now_diff for you

Sampling
--------

Only report 10% of some_frequent_task measurements:

estatsd:timing(some_frequent_task, 12, 0.1)



NOTES
Expand Down
4 changes: 4 additions & 0 deletions src/estatsd.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-module(estatsd).

-export([
gauge/2,
increment/1, increment/2, increment/3,
decrement/1, decrement/2, decrement/3,
timing/2
Expand Down Expand Up @@ -34,3 +35,6 @@ decrement(Key, Amount) -> decrement(Key, Amount, 1).
decrement(Key, Amount, Sample) ->
increment(Key, 0 - Amount, Sample).

% Sets a gauge value
gauge(Key, Value) when is_number(Value) ->
gen_server:cast(?SERVER, {gauge, Key, Value}).
41 changes: 38 additions & 3 deletions src/estatsd_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ init([FlushIntervalMs, GraphiteHost, GraphitePort]) ->
error_logger:info_msg("estatsd will flush stats to ~p:~w every ~wms\n",
[ GraphiteHost, GraphitePort, FlushIntervalMs ]),
ets:new(statsd, [named_table, set]),
ets:new(statsdgauge, [named_table, set]),
%% Flush out stats to graphite periodically
{ok, Tref} = timer:apply_interval(FlushIntervalMs, gen_server, cast,
[?MODULE, flush]),
Expand All @@ -48,6 +49,16 @@ init([FlushIntervalMs, GraphiteHost, GraphitePort]) ->
},
{ok, State}.

handle_cast({gauge, Key, Value0}, State) ->
Value = {Value0, num2str(unixtime())},
case ets:lookup(statsdgauge, Key) of
[] ->
ets:insert(statsdgauge, {Key, [Value]});
[{Key, Values}] ->
ets:insert(statsdgauge, {Key, [Value | Values]})
end,
{noreply, State};

handle_cast({increment, Key, Delta0, Sample}, State) when Sample >= 0, Sample =< 1 ->
Delta = Delta0 * ( 1 / Sample ), %% account for sample rates < 1.0
case ets:lookup(statsd, Key) of
Expand All @@ -69,9 +80,11 @@ handle_cast({timing, Key, Duration}, State) ->

handle_cast(flush, State) ->
All = ets:tab2list(statsd),
spawn( fun() -> do_report(All, State) end ),
Gauges = ets:tab2list(statsdgauge),
spawn( fun() -> do_report(All, Gauges, State) end ),
%% WIPE ALL
ets:delete_all_objects(statsd),
ets:delete_all_objects(statsdgauge),
NewState = State#state{timers = gb_trees:empty()},
{noreply, NewState}.

Expand Down Expand Up @@ -119,17 +132,19 @@ num2str(NN) -> lists:flatten(io_lib:format("~w",[NN])).
unixtime() -> {Meg,S,_Mic} = erlang:now(), Meg*1000000 + S.

%% Aggregate the stats and generate a report to send to graphite
do_report(All, State) ->
do_report(All, Gauges, State) ->
% One time stamp string used in all stats lines:
TsStr = num2str(unixtime()),
{MsgCounters, NumCounters} = do_report_counters(All, TsStr, State),
{MsgTimers, NumTimers} = do_report_timers(TsStr, State),
{MsgGauges, NumGauges} = do_report_gauges(Gauges),
%% REPORT TO GRAPHITE
case NumTimers + NumCounters of
case NumTimers + NumCounters + NumGauges of
0 -> nothing_to_report;
NumStats ->
FinalMsg = [ MsgCounters,
MsgTimers,
MsgGauges,
%% Also graph the number of graphs we're graphing:
"statsd.numStats ", num2str(NumStats), " ", TsStr, "\n"
],
Expand Down Expand Up @@ -182,3 +197,23 @@ do_report_timers(TsStr, State) ->
[ Fragment | Acc ]
end, [], Timings),
{Msg, length(Msg)}.

do_report_gauges(Gauges) ->
Msg = lists:foldl(
fun({Key, Vals}, Acc) ->
KeyS = key2str(Key),
Fragments = lists:foldl(
fun ({Val, TsStr}, KeyAcc) ->
%% Build stats string for graphite
Fragment = [
"gauge.", KeyS, " ",
io_lib:format("~w", [Val]), " ",
TsStr, "\n"
],
[ Fragment | KeyAcc ]
end, [], Vals
),
[ Fragments | Acc ]
end, [], Gauges
),
{Msg, length(Gauges)}.