Improve the profiler

This commit is contained in:
Evgeniy Khramtsov 2013-05-15 16:34:02 +10:00
parent 08774b1b5a
commit 1a45637860
1 changed files with 45 additions and 61 deletions

View File

@ -34,56 +34,64 @@
reds/0, reds/1, trace/1, help/0, reds/0, reds/1, trace/1, help/0,
q/0, m/0, r/0, q/1, m/1, r/1]). q/0, m/0, r/0, q/1, m/1, r/1]).
-define(APPS, [ejabberd, mnesia]). -define(TRACE_FILE, "/tmp/fprof.trace").
-define(ANALYSIS_FILE, "/tmp/fprof.analysis").
%%==================================================================== %%====================================================================
%% API %% API
%%==================================================================== %%====================================================================
eprof_start() -> eprof_start() ->
eprof:start(), eprof:start(),
case lists:keyfind(running, 1, application:info()) of case get_procs() of
{_, Apps} -> [] ->
case get_procs(?APPS, Apps) of {error, no_procs_found};
[] -> Procs ->
{error, no_procs_found}; eprof:start_profiling(Procs)
Procs ->
eprof:start_profiling(Procs)
end;
_ ->
{error, no_app_info}
end. end.
fprof_start() -> fprof_start() ->
fprof_start(0). fprof_start(0).
fprof_start(Duration) -> fprof_start(Duration) ->
case lists:keyfind(running, 1, application:info()) of case get_procs() of
{_, Apps} -> [] ->
case get_procs(?APPS, Apps) of {error, no_procs_found};
[] -> Procs ->
{error, no_procs_found}; case fprof:trace([start, {procs, Procs}, {file, ?TRACE_FILE}]) of
Procs -> ok ->
fprof:trace([start, {procs, Procs}]), io:format("Profiling started, writing trace data to ~s~n",
io:format("Profiling started~n"), [?TRACE_FILE]),
if Duration > 0 -> if Duration > 0 ->
timer:sleep(Duration*1000), timer:sleep(Duration*1000),
fprof:trace([stop]), fprof:trace([stop]),
fprof:stop(); fprof:stop();
true-> true->
ok ok
end end;
end; Err ->
_ -> io:format("Couldn't start profiling: ~p~n", [Err]),
{error, no_app_info} Err
end
end. end.
fprof_stop() -> fprof_stop() ->
fprof:trace([stop]), fprof:trace([stop]),
fprof:profile(), case fprof:profile([{file, ?TRACE_FILE}]) of
fprof:analyse([totals, no_details, {sort, own}, ok ->
no_callers, {dest, "fprof.analysis"}]), case fprof:analyse([totals, no_details, {sort, own},
fprof:stop(), no_callers, {dest, ?ANALYSIS_FILE}]) of
format_fprof_analyze(). ok ->
fprof:stop(),
format_fprof_analyze();
Err ->
io:format("Couldn't analyze: ~p~n", [Err]),
Err
end;
Err ->
io:format("Couldn't compile a trace into profile data: ~p~n",
[Err]),
Err
end.
fprof_analyze() -> fprof_analyze() ->
fprof_stop(). fprof_stop().
@ -175,35 +183,11 @@ trace_loop() ->
%%==================================================================== %%====================================================================
%% Internal functions %% Internal functions
%%==================================================================== %%====================================================================
get_procs(Apps, AppList) -> get_procs() ->
io:format("Searching for processes to profile...~n", []), processes().
Procs = lists:flatmap(
fun({App, Leader}) when is_pid(Leader) ->
case lists:member(App, Apps) of
true ->
get_procs(Leader);
false ->
[]
end;
(_) ->
[]
end, AppList),
io:format("Found ~p processes~n", [length(Procs)]),
Procs.
get_procs(Leader) ->
lists:filter(
fun(Pid) ->
case process_info(Pid, group_leader) of
{_, Leader} ->
true;
_ ->
false
end
end, processes()).
format_fprof_analyze() -> format_fprof_analyze() ->
case file:consult("fprof.analysis") of case file:consult(?ANALYSIS_FILE) of
{ok, [_, [{totals, _, _, TotalOWN}] | Rest]} -> {ok, [_, [{totals, _, _, TotalOWN}] | Rest]} ->
OWNs = lists:flatmap( OWNs = lists:flatmap(
fun({MFA, _, _, OWN}) -> fun({MFA, _, _, OWN}) ->