Skip to content

Commit

Permalink
Merge pull request #3 from blinkov/master
Browse files Browse the repository at this point in the history
Support for Erlang VM stats reporting
  • Loading branch information
RJ committed May 28, 2012
2 parents c9e1b99 + 14eb2a3 commit 2643d30
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 18 deletions.
75 changes: 62 additions & 13 deletions src/estatsd_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
-module(estatsd_server).
-behaviour(gen_server).

-export([start_link/3]).
-export([start_link/4]).

%-export([key2str/1,flush/0]). %% export for debugging

Expand All @@ -22,18 +22,19 @@
flush_interval, % ms interval between stats flushing
flush_timer, % TRef of interval timer
graphite_host, % graphite server host
graphite_port % graphite server port
graphite_port, % graphite server port
vm_metrics % flag to enable sending VM metrics on flush
}).

start_link(FlushIntervalMs, GraphiteHost, GraphitePort) ->
start_link(FlushIntervalMs, GraphiteHost, GraphitePort, VmMetrics) ->
gen_server:start_link({local, ?MODULE},
?MODULE,
[FlushIntervalMs, GraphiteHost, GraphitePort],
[FlushIntervalMs, GraphiteHost, GraphitePort, VmMetrics],
[]).

%%

init([FlushIntervalMs, GraphiteHost, GraphitePort]) ->
init([FlushIntervalMs, GraphiteHost, GraphitePort, VmMetrics]) ->
error_logger:info_msg("estatsd will flush stats to ~p:~w every ~wms\n",
[ GraphiteHost, GraphitePort, FlushIntervalMs ]),
ets:new(statsd, [named_table, set]),
Expand All @@ -45,7 +46,8 @@ init([FlushIntervalMs, GraphiteHost, GraphitePort]) ->
flush_interval = FlushIntervalMs,
flush_timer = Tref,
graphite_host = GraphiteHost,
graphite_port = GraphitePort
graphite_port = GraphitePort,
vm_metrics = VmMetrics
},
{ok, State}.

Expand Down Expand Up @@ -135,18 +137,20 @@ unixtime() -> {Meg,S,_Mic} = erlang:now(), Meg*1000000 + S.
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),
{MsgCounters, NumCounters} = do_report_counters(All, TsStr, State),
{MsgTimers, NumTimers} = do_report_timers(TsStr, State),
{MsgGauges, NumGauges} = do_report_gauges(Gauges),
{MsgVmMetrics, NumVmMetrics} = do_report_vm_metrics(TsStr, State),
%% REPORT TO GRAPHITE
case NumTimers + NumCounters + NumGauges of
case NumTimers + NumCounters + NumGauges + NumVmMetrics of
0 -> nothing_to_report;
NumStats ->
FinalMsg = [ MsgCounters,
MsgTimers,
MsgGauges,
MsgVmMetrics,
%% Also graph the number of graphs we're graphing:
"statsd.numStats ", num2str(NumStats), " ", TsStr, "\n"
"stats.num_stats ", num2str(NumStats), " ", TsStr, "\n"
],
send_to_graphite(FinalMsg, State)
end.
Expand All @@ -157,11 +161,11 @@ do_report_counters(All, TsStr, State) ->
KeyS = key2str(Key),
Val = Val0 / (State#state.flush_interval/1000),
%% Build stats string for graphite
Fragment = [ "stats.", KeyS, " ",
Fragment = [ "stats.counters.", KeyS, " ",
io_lib:format("~w", [Val]), " ",
TsStr, "\n",

"stats_counts.", KeyS, " ",
"stats.counters.counts.", KeyS, " ",
io_lib:format("~w",[NumVals]), " ",
TsStr, "\n"
],
Expand Down Expand Up @@ -217,3 +221,48 @@ do_report_gauges(Gauges) ->
end, [], Gauges
),
{Msg, length(Gauges)}.

do_report_vm_metrics(TsStr, State) ->
case State#state.vm_metrics of
true ->
NodeKey = node_key(),
{TotalReductions, Reductions} = erlang:statistics(reductions),
{NumberOfGCs, WordsReclaimed, _} = erlang:statistics(garbage_collection),
{{input, Input}, {output, Output}} = erlang:statistics(io),
RunQueue = erlang:statistics(run_queue),
StatsData = [
{process_count, erlang:system_info(process_count)},
{reductions, Reductions},
{total_reductions, TotalReductions},
{number_of_gcs, NumberOfGCs},
{words_reclaimed, WordsReclaimed},
{input, Input},
{output, Output},
{run_queue, RunQueue}
],
StatsMsg = lists:map(fun({Key, Val}) ->
[
"stats.vm.", NodeKey, ".stats.", key2str(Key), " ",
io_lib:format("~w", [Val]), " ",
TsStr, "\n"
]
end, StatsData),
MemoryMsg = lists:map(fun({Key, Val}) ->
[
"stats.vm.", NodeKey, ".memory.", key2str(Key), " ",
io_lib:format("~w", [Val]), " ",
TsStr, "\n"
]
end, erlang:memory()),
Msg = StatsMsg ++ MemoryMsg;
false ->
Msg = []
end,
{Msg, length(Msg)}.

node_key() ->
NodeList = atom_to_list(node()),
{ok, R} = re:compile("[\@\.]"),
Opts = [global, {return, list}],
S = re:replace(NodeList, R, "_", Opts),
key2str(S).
14 changes: 9 additions & 5 deletions src/estatsd_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,36 @@
-define(FLUSH_INTERVAL, appvar(flush_interval, 10000)).
-define(GRAPHITE_HOST, appvar(graphite_host, "127.0.0.1")).
-define(GRAPHITE_PORT, appvar(graphite_port, 2003)).
-define(VM_METRICS, appvar(vm_metrics, true)).

%% ===================================================================
%% API functions
%% ===================================================================


start_link() ->
start_link( ?FLUSH_INTERVAL, ?GRAPHITE_HOST, ?GRAPHITE_PORT).
start_link( ?FLUSH_INTERVAL, ?GRAPHITE_HOST, ?GRAPHITE_PORT, ?VM_METRICS).

start_link(FlushIntervalMs) ->
start_link( FlushIntervalMs, ?GRAPHITE_HOST, ?GRAPHITE_PORT).
start_link( FlushIntervalMs, ?GRAPHITE_HOST, ?GRAPHITE_PORT, ?VM_METRICS).

start_link(FlushIntervalMs, GraphiteHost, GraphitePort) ->
start_link( FlushIntervalMs, GraphiteHost, GraphitePort, ?VM_METRICS).

start_link(FlushIntervalMs, GraphiteHost, GraphitePort, VmMetrics) ->
supervisor:start_link({local, ?MODULE},
?MODULE,
[FlushIntervalMs, GraphiteHost, GraphitePort]).
[FlushIntervalMs, GraphiteHost, GraphitePort, VmMetrics]).

%% ===================================================================
%% Supervisor callbacks
%% ===================================================================

init([FlushIntervalMs, GraphiteHost, GraphitePort]) ->
init([FlushIntervalMs, GraphiteHost, GraphitePort, VmMetrics]) ->
Children = [
{estatsd_server,
{estatsd_server, start_link,
[FlushIntervalMs, GraphiteHost, GraphitePort]},
[FlushIntervalMs, GraphiteHost, GraphitePort, VmMetrics]},
permanent, 5000, worker, [estatsd_server]}
],
{ok, { {one_for_one, 10000, 10}, Children} }.
Expand Down

0 comments on commit 2643d30

Please sign in to comment.