Skip to content
Permalink
Browse files
Merge branch 'djnym-master'
  • Loading branch information
ferd committed Aug 10, 2015
2 parents e209456 + ddb5fc7 commit 7bd836bdfc9656f8233ad84f62353823bdda9ce1
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
@@ -14,3 +14,5 @@ erl_crash.dump
/doc/stylesheet.css
/site/*.html
.rebar/
_build/

@@ -32,6 +32,8 @@ all stable changes of the first version of Recon.
`recon:proc_window`.
- Fix doc typos
- Fix potential race condition on waiting for death of tracing process
- Add an option which allows sending tracing output somewhere other than
group_leader().
- 2.2.1
- Fixing type specs for `recon:port_types/0` and `recon_lib:count/1`,
thanks to @lucafavatella
@@ -0,0 +1 @@
[].
@@ -152,6 +152,21 @@
%%% In case the operator is tracing from a remote shell which gets
%%% disconnected, the links between the shell and the tracer should make it
%%% so tracing is automatically turned off once you disconnect.
%%%
%%% If sending output to the Group Leader is not desired, you may specify
%%% a different pid() via the option `io_server' in the {@link calls/3} function.
%%% For instance to write the traces to a file you can do something like
%%%
%%% 1> {ok, Dev} = file:open("/tmp/trace",[write]).
%%% 2> recon_trace:calls({queue, in, fun(_) -> return_trace() end}, 3, [{io_server, Dev}]).
%%% 1
%%% 3>
%%% Recon tracer rate limit tripped.
%%% 4> file:close(Dev).
%%%
%%% The only output still sent to the Group Leader is the rate limit being
%%% tripped, and any errors. The rest will be sent to the other IO
%%% server (see [http://erlang.org/doc/apps/stdlib/io_protocol.html]).
%%% @end
-module(recon_trace).

@@ -161,7 +176,7 @@
-export([format/1]).

%% Internal exports
-export([count_tracer/1, rate_tracer/2, formatter/4]).
-export([count_tracer/1, rate_tracer/2, formatter/5]).

-type matchspec() :: [{[term()], [term()], [term()]}].
-type shellfun() :: fun((_) -> term()).
@@ -177,6 +192,7 @@
| {args, args | arity} % default: args
%% match pattern options
| {scope, global | local} % default: global
| {io_server, pid()} % default: group_leader()
].

-type mod() :: '_' | module().
@@ -305,10 +321,10 @@ calls(Spec, Max, Opts) ->
calls({Mod, Fun, Args}, Max, Opts, FormatterFun) ->
calls([{Mod,Fun,Args}], Max, Opts, FormatterFun);
calls(TSpecs = [_|_], {Max, Time}, Opts, FormatterFun) ->
Pid = setup(rate_tracer, [Max, Time], FormatterFun),
Pid = setup(rate_tracer, [Max, Time], FormatterFun, validate_io_server(Opts)),
trace_calls(TSpecs, Pid, Opts);
calls(TSpecs = [_|_], Max, Opts, FormatterFun) ->
Pid = setup(count_tracer, [Max], FormatterFun),
Pid = setup(count_tracer, [Max], FormatterFun, validate_io_server(Opts)),
trace_calls(TSpecs, Pid, Opts).

%%%%%%%%%%%%%%%%%%%%%%%
@@ -345,22 +361,22 @@ rate_tracer(Max, Time, Count, Start) ->
end.

%% @private Formats traces to be output
formatter(Tracer, Parent, Ref, FormatterFun) ->
formatter(Tracer, Parent, Ref, FormatterFun, IOServer) ->
process_flag(trap_exit, true),
link(Tracer),
Parent ! {Ref, linked},
formatter(Tracer, group_leader(), FormatterFun).
formatter(Tracer, IOServer, FormatterFun).

formatter(Tracer, Leader, FormatterFun) ->
formatter(Tracer, IOServer, FormatterFun) ->
receive
{'EXIT', Tracer, normal} ->
io:format("Recon tracer rate limit tripped.~n"),
exit(normal);
{'EXIT', Tracer, Reason} ->
exit(Reason);
TraceMsg ->
io:format(Leader, FormatterFun(TraceMsg), []),
formatter(Tracer, Leader, FormatterFun)
io:format(IOServer, FormatterFun(TraceMsg), []),
formatter(Tracer, IOServer, FormatterFun)
end.


@@ -370,12 +386,12 @@ formatter(Tracer, Leader, FormatterFun) ->

%% starts the tracer and formatter processes, and
%% cleans them up before each call.
setup(TracerFun, TracerArgs, FormatterFun) ->
setup(TracerFun, TracerArgs, FormatterFun, IOServer) ->
clear(),
Ref = make_ref(),
Tracer = spawn_link(?MODULE, TracerFun, TracerArgs),
register(recon_trace_tracer, Tracer),
Format = spawn(?MODULE, formatter, [Tracer, self(), Ref, FormatterFun]),
Format = spawn(?MODULE, formatter, [Tracer, self(), Ref, FormatterFun, IOServer]),
register(recon_trace_formatter, Format),
receive
{Ref, linked} -> Tracer
@@ -449,6 +465,9 @@ validate_tspec(Mod, Fun, Args) ->
_ when Args >= 0, Args =< 255 -> {Args, true}
end.

validate_io_server(Opts) ->
proplists:get_value(io_server, Opts, group_leader()).

%%%%%%%%%%%%%%%%%%%%%%%%
%%% TRACE FORMATTING %%%
%%%%%%%%%%%%%%%%%%%%%%%%

0 comments on commit 7bd836b

Please sign in to comment.