Permalink
Browse files

Adding Scheduler wall time ratios to metrics

- upgrading docs
- changing the default delay to 1 second rather than 5
- bumping version to 0.2
- forcing a restart of the server in case of hot code loading;
  no ill effect otherwise

The new scheduler wall time metric will add keys to StatsD, of the
form 'BaseKey.scheduler_wall_time.<SchedulerId>'.
  • Loading branch information...
1 parent 9f26aa3 commit 03c896937389e84334261ca8d32eeca5f4e20805 @ferd committed Jul 17, 2012
Showing with 43 additions and 5 deletions.
  1. +5 −1 README.markdown
  2. +2 −2 src/vmstats.app.src
  3. +36 −2 src/vmstats_server.erl
View
@@ -3,11 +3,12 @@
vmstats is a tiny Erlang app that works in conjunction with [statsderl](https://github.com/ferd/statsderl) in order to generate information on the Erlang VM for graphite logs.
The different fields include:
- - the error\_logger queue lenght
+ - the error\_logger queue length
- the number of modules loaded
- the number of processes
- the process limit
- the length of the run queue
+ - the scheduler usage as a percentage
- memory used for ETS tables, atoms, processes, binaries and the total memory
## How to build ##
@@ -18,3 +19,6 @@ The different fields include:
It is recommended to leave the interval at 1000ms (1 second) as graphite seems to dampen missing data points on intervals larger than that, or to accumulate them when they're smaller. At roughly 1 second, the values seem to represent what the Erlang VM outputs the best.
+## I was basing myself on 'master' and stuff started breaking!
+
+You are likely using vmstats with an Erlang release prior to R15B. Switch away from master and use the tag "0.1.0" to get back to the functionning version you knew.
View
@@ -1,6 +1,6 @@
{application, vmstats, [
{description, "Tiny application to gather VM statistics for StatsD client"},
- {vsn, "0.1"},
+ {vsn, "0.2.0"},
{registered, [vmstats_sup, vmstats_server]},
{applications, [
kernel,
@@ -11,6 +11,6 @@
{applications, [statsderl]},
{modules, [vmstats, vmstats_sup, vmstats_server]},
{env, [
- {delay, 5000} % in milliseconds
+ {delay, 1000} % in milliseconds
]}
]}.
View
@@ -12,6 +12,8 @@
-define(TIMER_MSG, '#delay').
-record(state, {key :: string(),
+ sched_time :: enabled | disabled,
+ prev_sched :: [{integer(), integer(), integer()}],
timer_ref :: reference(),
delay :: integer()}). % milliseconds
@@ -25,7 +27,20 @@ start_link(BaseKey) ->
init(BaseKey) ->
{ok, Delay} = application:get_env(vmstats, delay),
Ref = erlang:start_timer(Delay, self(), ?TIMER_MSG),
- {ok, #state{key=[BaseKey,$.], timer_ref=Ref, delay=Delay}}.
+ try erlang:system_flag(scheduler_wall_time, true) of
+ _ ->
+ {ok, #state{key = [BaseKey,$.],
+ timer_ref = Ref,
+ delay = Delay,
+ sched_time = enabled,
+ prev_sched = lists:sort(erlang:statistics(scheduler_wall_time))}}
+ catch
+ error:badarg ->
+ {ok, #state{key = [BaseKey,$.],
+ timer_ref = Ref,
+ delay = Delay,
+ sched_time = disabled}}
+ end.
handle_call(_Msg, _From, State) ->
{noreply, State}.
@@ -58,7 +73,20 @@ handle_info({timeout, R, ?TIMER_MSG}, S = #state{key=K, delay=D, timer_ref=R}) -
statsderl:increment([K2,"binary"], proplists:get_value(binary, Mem), 1.00),
statsderl:increment([K2,"ets"], proplists:get_value(ets, Mem), 1.00),
- {noreply, S#state{timer_ref=erlang:start_timer(D, self(), ?TIMER_MSG)}};
+ %% Scheduler wall time
+ #state{sched_time=Sched, prev_sched=PrevSched} = S,
+ case Sched of
+ enabled ->
+ NewSched = lists:sort(erlang:statistics(scheduler_wall_time)),
+ [statsderl:increment([K,"scheduler_wall_time.",integer_to_list(Sid)], T, 1.00)
+ || {Sid, T} <- wall_time_diff(PrevSched, NewSched)],
+ {noreply, S#state{timer_ref=erlang:start_timer(D, self(), ?TIMER_MSG),
+ prev_sched=NewSched}};
+ disabled ->
+ {noreply, S#state{timer_ref=erlang:start_timer(D, self(), ?TIMER_MSG)}}
+ end;
+handle_info(_Msg, {state, _Key, _TimerRef, _Delay}) ->
+ exit(forced_upgrade_restart);
handle_info(_Msg, State) ->
{noreply, State}.
@@ -67,3 +95,9 @@ code_change(_OldVsn, State, _Extra) ->
terminate(_Reason, _State) ->
ok.
+
+%% Returns the two timeslices as a ratio of each other,
+%% as a percentage so that StatsD gets to print something > 1
+wall_time_diff(T1, T2) ->
+ [{I, round(((Active2-Active1)/(Total2-Total1))*100)}
+ || {{I, Active1, Total1}, {I, Active2, Total2}} <- lists:zip(T1,T2)].

0 comments on commit 03c8969

Please sign in to comment.