Browse files

json backend: first step

  • Loading branch information...
1 parent 0dfefc2 commit c72696ffb6c6405d28a95e49bc8237835f53498e @nniclausse nniclausse committed Sep 23, 2011
Showing with 97 additions and 49 deletions.
  1. +43 −17 src/tsung_controller/ts_mon.erl
  2. +53 −31 src/tsung_controller/ts_stats_mon.erl
  3. +1 −1 tsung-1.0.dtd
View
60 src/tsung_controller/ts_mon.erl
@@ -140,7 +140,7 @@ rcvmes({_Type, Who, What}) ->
gen_server:cast({global, ?MODULE}, {rcvmsg, Who, now(), What}).
dump({none, _, _})-> skip;
-dump({Type, Who, What}) ->
+dump({_Type, Who, What}) ->
gen_server:cast({global, ?MODULE}, {dump, Who, now(), What}).
launcher_is_alive() ->
@@ -365,7 +365,12 @@ terminate(Reason, State) ->
export_stats(State),
ts_stats_mon:status(ts_stats_mon), % blocking call to ts_stats_mon; this way, we are
% sure the last call to dumpstats is finished
- io:format(State#state.log,"EndMonitor:~w~n",[now()]),
+ case State#state.backend of
+ json ->
+ io:format(State#state.log,"}~n",[]);
+ _ ->
+ io:format(State#state.log,"EndMonitor:~w~n",[now()])
+ end,
case State#state.log of
standard_io -> ok;
Dev -> file:close(Dev)
@@ -415,12 +420,12 @@ start_logger({Machines, DumpType, Backend}, _From, State) ->
?LOGF("Activate clients with ~p backend~n",[Backend],?NOTICE),
timer:apply_interval(State#state.dump_interval, ?MODULE, dumpstats, [] ),
start_launchers(Machines),
- ts_stats_mon:set_output(text,{State#state.log,[]}),
- ts_stats_mon:set_output(text,{State#state.log,[]}, transaction),
- ts_stats_mon:set_output(text,{State#state.log,[]}, request),
- ts_stats_mon:set_output(text,{State#state.log,[]}, connect),
- ts_stats_mon:set_output(text,{State#state.log,[]}, page),
- start_dump(State#state{type=DumpType, backend=text}).
+ ts_stats_mon:set_output(Backend,{State#state.log,[]}),
+ ts_stats_mon:set_output(Backend,{State#state.log,[]}, transaction),
+ ts_stats_mon:set_output(Backend,{State#state.log,[]}, request),
+ ts_stats_mon:set_output(Backend,{State#state.log,[]}, connect),
+ ts_stats_mon:set_output(Backend,{State#state.log,[]}, page),
+ start_dump(State#state{type=DumpType, backend=Backend}).
%% @spec start_dump(State::record(state)) -> {reply, Reply, State}
%% @doc open file for dumping traffic
@@ -446,20 +451,41 @@ start_dump(State=#state{type=Type}) ->
%%----------------------------------------------------------------------
%% Func: export_stats/1
%%----------------------------------------------------------------------
-export_stats(State=#state{log=Log,stats=Stats,laststats=LastStats}) ->
+export_stats(State=#state{log=Log,stats=Stats,laststats=LastStats, backend=json}) ->
+ DateStr = ts_utils:now_sec(),
+ io:format(Log,"{\"timestamp\": ~w, ~n",[DateStr]),
+ %% print number of simultaneous users
+ io:format(Log," \"users\": ~p,~n \"users_max\": ~p,~n",[State#state.client,State#state.maxclient]),
+ Param = {json,(State#state.laststats)#stats.os_mon,State#state.log},
+ dict:fold(fun ts_stats_mon:print_stats/3, Param, (State#state.stats)#stats.os_mon),
+ ts_stats_mon:print_stats({session, sample}, Stats#stats.session,{json,[],Log}),
+ ts_stats_mon:print_stats({users_count, count},
+ Stats#stats.users_count,
+ {json,LastStats#stats.users_count,Log}),
+ ts_stats_mon:print_stats({finish_users_count, count},
+ Stats#stats.finish_users_count,
+ {json,LastStats#stats.finish_users_count,Log}),
+ ts_stats_mon:dumpstats(request),
+ ts_stats_mon:dumpstats(page),
+ ts_stats_mon:dumpstats(connect),
+ ts_stats_mon:dumpstats(transaction),
+ ts_stats_mon:dumpstats(),
+ io:format(Log,"}~n",[]);
+
+export_stats(State=#state{log=Log,stats=Stats,laststats=LastStats, backend=BackEnd}) ->
DateStr = ts_utils:now_sec(),
io:format(Log,"# stats: dump at ~w~n",[DateStr]),
%% print number of simultaneous users
io:format(Log,"stats: ~p ~p ~p~n",[users,State#state.client,State#state.maxclient]),
- Param = {(State#state.laststats)#stats.os_mon,State#state.log},
- dict:fold(fun ts_stats_mon:print_stats_txt/3, Param, (State#state.stats)#stats.os_mon),
- ts_stats_mon:print_stats_txt({session, sample}, Stats#stats.session,{[],Log}),
- ts_stats_mon:print_stats_txt({users_count, count},
+ Param = {BackEnd,(State#state.laststats)#stats.os_mon,State#state.log},
+ dict:fold(fun ts_stats_mon:print_stats/3, Param, (State#state.stats)#stats.os_mon),
+ ts_stats_mon:print_stats({session, sample}, Stats#stats.session,{BackEnd,[],Log}),
+ ts_stats_mon:print_stats({users_count, count},
Stats#stats.users_count,
- {LastStats#stats.users_count,Log}),
- ts_stats_mon:print_stats_txt({finish_users_count, count},
- Stats#stats.finish_users_count,
- {LastStats#stats.finish_users_count,Log}),
+ {BackEnd,LastStats#stats.users_count,Log}),
+ ts_stats_mon:print_stats({finish_users_count, count},
+ Stats#stats.finish_users_count,
+ {BackEnd,LastStats#stats.finish_users_count,Log}),
ts_stats_mon:dumpstats(request),
ts_stats_mon:dumpstats(page),
ts_stats_mon:dumpstats(connect),
View
84 src/tsung_controller/ts_stats_mon.erl
@@ -45,7 +45,8 @@
status/1, status/2 ]).
%% More external exports for ts_mon
--export([print_stats_txt/3, update_stats/3, add_stats_data/2, reset_all_stats/1]).
+-export([update_stats/3, add_stats_data/2, reset_all_stats/1]).
+-export([print_stats/3]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
@@ -258,46 +259,67 @@ add_stats_data({sum, Name, Val}, Stats) ->
%%----------------------------------------------------------------------
%% Func: export_stats/2
%%----------------------------------------------------------------------
-export_stats(State=#state{type=Type}) when Type == 'connect'; Type == 'page'; Type == 'request' ->
- Param = {State#state.laststats,State#state.log},
- print_stats_txt({Type,sample}, State#state.stats, Param);
-export_stats(State=#state{backend=_Backend}) ->
- Param = {State#state.laststats,State#state.log},
- dict:fold(fun print_stats_txt/3, Param, State#state.stats).
+export_stats(State=#state{type=Type,backend=Backend}) when Type == 'connect'; Type == 'page'; Type == 'request' ->
+ Param = {Backend,State#state.laststats,State#state.log},
+ print_stats({Type,sample}, State#state.stats, Param);
+export_stats(State=#state{backend=Backend}) ->
+ Param = {Backend,State#state.laststats,State#state.log},
+ dict:fold(fun print_stats/3, Param, State#state.stats).
%%----------------------------------------------------------------------
-%% Func: print_dist_list/3
-%% @spec (Key::tuple(), Value::List, {Last, Logfile}) -> {Last, Logfile}
-%% @doc print statistics in text format in Logfile
+%% @spec print_stats({Backend::tuple(),Name::tuple(),
+%% Type::sample|count|sum|sample_counter}, Value::list(),
+%% {Last, Logfile} ) -> {Last, Logfile}
+%% @doc print statistics in text format in Logfile @end
%%----------------------------------------------------------------------
-print_stats_txt({_Name,_Type}, [], {LastRes,Logfile})->
- {LastRes, Logfile};
-print_stats_txt({_Name,_Type}, [0,0,0,0,0,0,0|_], {LastRes,Logfile})->
- {LastRes,Logfile};
-print_stats_txt({Name,_Type}, [Mean,0,Max,Min,Count,MeanFB,CountFB|_], {LastRes,Logfile})->
- io:format(Logfile, "stats: ~p ~p ~p ~p ~p ~p ~p ~p~n",
+print_stats({_,_}, [], {Backend,LastRes,Logfile})->
+ {Backend,LastRes, Logfile};
+print_stats({_,_}, [0,0,0,0,0,0,0|_], {Backend,LastRes,Logfile})->
+ {Backend,LastRes, Logfile};
+print_stats({_,_,_}, 0, {Backend,0, Logfile})-> % no data yet
+ {Backend,0, Logfile};
+%% print_stats({Backend,Name,Type}, Value , Other) when Backend == text orelse Backend == fullstats ->
+%% print_stats_txt({Name,Type}, Value , Other);
+% sample
+print_stats({{Name,Node},Type},Value,{json,Res,Log}) when (Type =:= sample) orelse (Type =:= sample_counter) ->
+ [_,Host] = string:tokens(Node,"@"),
+ print_stats_txt({Name,Type," {\"name\": \"~s\", \"hostname\": \"" ++ Host
+ ++"\", \"value\": ~p, \"mean\": ~p,\"stdvar\": ~p,\"max\": ~p,\"min\": ~p ,\"global_mean\": ~p ,\"global_count\": ~p},~n"},Value,{json,Res,Log});
+
+print_stats({Name,Type},Value,{json,Res,Log}) when (Type =:= sample) orelse (Type =:= sample_counter) ->
+ print_stats_txt({Name,Type," {\"name\": \"~s\", \"value\": ~p, \"mean\": ~p,\"stdvar\": ~p,\"max\": ~p,\"min\": ~p ,\"global_mean\": ~p ,\"global_count\": ~p},~n"},Value,{json,Res,Log});
+
+print_stats({Name,Type},Value,Other) when (Type =:= sample) orelse (Type =:= sample_counter) ->
+ print_stats_txt({Name,Type,"stats: ~p ~p ~p ~p ~p ~p ~p ~p~n"},Value,Other);
+print_stats({Name,Type},Value,{json,Res,Log}) ->
+ print_stats_txt({Name,Type," {\"name\": \"~s\", \"value\": ~p, \"total\": ~p},~n"},Value,{json,Res,Log});
+print_stats({Name,Type},Value,Other) ->
+ print_stats_txt({Name,Type,"stats: ~p ~p ~p~n"},Value,Other).
+
+
+%% @spec print_stats_txt
+print_stats_txt({Name,_,Format}, [Mean,0,Max,Min,Count,MeanFB,CountFB|_], {Backend,LastRes,Logfile})->
+ io:format(Logfile, Format,
[Name, Count, Mean, 0, Max, Min,MeanFB,CountFB ]),
- {LastRes, Logfile};
-print_stats_txt({Name,_Type},[Mean,Var,Max,Min,Count,MeanFB,CountFB|_],{LastRes,Logfile})->
+ {Backend,LastRes, Logfile};
+print_stats_txt({Name,_,Format},[Mean,Var,Max,Min,Count,MeanFB,CountFB|_],{Backend,LastRes,Logfile})->
StdVar = math:sqrt(Var/Count),
- io:format(Logfile, "stats: ~p ~p ~p ~p ~p ~p ~p ~p~n",
+ io:format(Logfile, Format,
[Name, Count, Mean, StdVar, Max, Min, MeanFB,CountFB]),
- {LastRes, Logfile};
-print_stats_txt({Name, _Type}, [Value,Last], {LastRes, Logfile}) ->
- io:format(Logfile, "stats: ~p ~p ~p~n", [Name, Value, Last ]),
- {LastRes, Logfile};
-print_stats_txt({_Name, _Type}, 0, {0, Logfile})-> % no data yet
- {0, Logfile};
-print_stats_txt({Name, _Type}, Value, {LastRes, Logfile}) when is_number(LastRes)->
- io:format(Logfile, "stats: ~p ~p ~p~n", [Name, Value-LastRes, Value]),
- {LastRes, Logfile};
-print_stats_txt({Name, Type}, Value, {LastRes, Logfile}) ->
+ {Backend,LastRes, Logfile};
+print_stats_txt({Name, _,Format}, [Value,Last], {Backend,LastRes, Logfile}) ->
+ io:format(Logfile, Format, [Name, Value, Last ]),
+ {Backend,LastRes, Logfile};
+print_stats_txt({Name, _,Format}, Value, {Backend,LastRes, Logfile}) when is_number(LastRes)->
+ io:format(Logfile, Format, [Name, Value-LastRes, Value]),
+ {Backend,LastRes, Logfile};
+print_stats_txt({Name, Type, Format}, Value, {Backend,LastRes, Logfile}) when is_number(Value)->
PrevVal = case dict:find({Name, Type}, LastRes) of
{ok, OldVal} -> OldVal;
error -> 0
end,
- io:format(Logfile, "stats: ~p ~p ~p~n", [Name, Value-PrevVal, Value]),
- {LastRes, Logfile}.
+ io:format(Logfile, Format, [Name, Value-PrevVal, Value]),
+ {Backend,LastRes, Logfile}.
%%----------------------------------------------------------------------
View
2 tsung-1.0.dtd
@@ -11,7 +11,7 @@
<!ATTLIST tsung
dumptraffic (true | false | light | protocol) "false"
- backend (text | rrdtool | fullstats) "text"
+ backend (text | json| rrdtool | fullstats) "text"
loglevel (emergency|critical|error|warning|notice|info|debug) "notice"
version NMTOKEN #IMPLIED>

0 comments on commit c72696f

Please sign in to comment.