Debugging, improved logging, etc.
This commit is contained in:
@@ -6,6 +6,18 @@
|
||||
, erase/1
|
||||
]).
|
||||
|
||||
-export([note_flow/1,
|
||||
ct_log/2, %% ct_log(Fmt, Args)
|
||||
ct_log/3, %% ct_log(Flow, Fmt, Args)
|
||||
timestamp/0]).
|
||||
|
||||
-export([ status/0
|
||||
, summarize_flow/1
|
||||
, reset_flow/1
|
||||
, reset/0 ]).
|
||||
|
||||
-include("gm_ctflow.hrl").
|
||||
|
||||
-type flow() :: any().
|
||||
-type key() :: any().
|
||||
-type value() :: any().
|
||||
@@ -28,3 +40,92 @@ get(Key, Default) ->
|
||||
-spec erase(key()) -> 'ok'.
|
||||
erase(Key) ->
|
||||
gm_ctflow_state:erase(Key).
|
||||
|
||||
|
||||
note_flow(Flow) ->
|
||||
erlang:put({?MODULE, flow}, Flow).
|
||||
|
||||
ct_log(Fmt, Args) ->
|
||||
ct_log(erlang:get({?MODULE, flow}), Fmt, Args).
|
||||
|
||||
ct_log(Flow, Fmt, Args) ->
|
||||
TS = timestamp(),
|
||||
case Flow of
|
||||
undefined ->
|
||||
save_log(undefined, TS, Fmt, Args),
|
||||
ct:log(Fmt, Args);
|
||||
Flow ->
|
||||
save_log(Flow, TS, Fmt, Args),
|
||||
ct:log("~p[~w]: " ++ Fmt, [Flow, self()|Args])
|
||||
end.
|
||||
|
||||
|
||||
save_log(Flow, TS, Fmt, Args) ->
|
||||
gm_ctflow_log:log(Flow, TS, Fmt, Args).
|
||||
|
||||
reset_flow(Flow) ->
|
||||
gm_ctflow_log:erase(Flow),
|
||||
try_call(fun gm_ctflow_worker:stop/1, Flow),
|
||||
try_call(fun gm_ctflow_fun:delete/1, Flow),
|
||||
ok.
|
||||
|
||||
reset() ->
|
||||
gm_ctflow_log:erase(),
|
||||
gm_ctflow_state:reset(),
|
||||
gm_ctflow_worker_sup:reset(),
|
||||
gm_ctflow_fun:reset(),
|
||||
ok.
|
||||
|
||||
status() ->
|
||||
WorkerFlows = [F || {F,_} <- gm_ctflow_reg:registered_names()],
|
||||
FunFlows = gm_ctflow_fun:flows(),
|
||||
AllFlows = ordsets:from_list(WorkerFlows ++ FunFlows),
|
||||
[summarize_flow(Flow) || Flow <- AllFlows].
|
||||
|
||||
summarize_flow(Flow) ->
|
||||
LogHistory = gm_ctflow_log:history(Flow),
|
||||
AllState = gm_ctflow_state:all(),
|
||||
FunState = try_call(fun gm_ctflow_fun:maybe_get_state/1, Flow),
|
||||
WorkerState = try_call(fun gm_ctflow_worker:maybe_get_state/1, Flow),
|
||||
S = [ {worker_state, WorkerState}
|
||||
, {fun_state, FunState}
|
||||
, {all_state, AllState}
|
||||
, {log_history, LogHistory} ],
|
||||
ct:log("== Summary for flow ~p~n~s", [Flow , [summary_(S1) || S1 <- S]]).
|
||||
|
||||
summary_({log_history, []}) -> fw("= Log History: - none -~n", []);
|
||||
summary_({log_history, H}) ->
|
||||
[ fw("= Log History:~n", [])
|
||||
, [ fw("~n~s:~n~s~n", [TS, fw(Fmt, Args)])
|
||||
|| {TS, Fmt, Args} <- H], "\n"];
|
||||
summary_({all_state, []}) -> fw("= State: - none -~n", []);
|
||||
summary_({all_state, L}) ->
|
||||
[ fw("= State:~n", []) , [fw("~p = ~p~n", [K, V]) || {K, V} <- L], "\n"];
|
||||
summary_({worker_state, S}) -> fw("= Worker State: ~s~n", [maybe_state_str(S)]);
|
||||
summary_({fun_state, S}) -> fw("= Fun State: ~s~n", [maybe_state_str(S)]).
|
||||
|
||||
maybe_state_str({ok, S}) -> fw("~p", [S]);
|
||||
maybe_state_str({error, E}) -> fw("ERROR: ~p", [E]);
|
||||
maybe_state_str(error) -> "- none -".
|
||||
|
||||
fw(Fmt, Args) -> io_lib:fwrite(Fmt, Args).
|
||||
|
||||
try_call(F, Flow) ->
|
||||
try F(Flow)
|
||||
catch
|
||||
exit:E:ST ->
|
||||
ct:log("Call to ~p(~p) failed: exit:~p:~p", [F, Flow, E, ST]);
|
||||
error:E:ST ->
|
||||
ct:log("Call to ~p(~p) failed: error:~p:~p", [F, Flow, E, ST]),
|
||||
undefined
|
||||
end.
|
||||
|
||||
%% copy-pasted (roughly) from ct_logs.erl
|
||||
timestamp() ->
|
||||
{MS,S,US} = os:timestamp(),
|
||||
{{Year,Month,Day}, {Hour,Min,Sec}} =
|
||||
calendar:now_to_local_time({MS,S,US}),
|
||||
MilliSec = trunc(US/1000),
|
||||
lists:flatten(io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B "
|
||||
"~2.10.0B:~2.10.0B:~2.10.0B.~3.10.0B",
|
||||
[Year,Month,Day,Hour,Min,Sec,MilliSec])).
|
||||
|
||||
Reference in New Issue
Block a user