|
|
@ -1,5 +1,7 @@ |
|
|
|
-module(eTpf). |
|
|
|
|
|
|
|
-include("eTpf.hrl"). |
|
|
|
|
|
|
|
-export([ |
|
|
|
trace/1 |
|
|
|
, trace/2 |
|
|
@ -10,42 +12,31 @@ |
|
|
|
|
|
|
|
]). |
|
|
|
|
|
|
|
-type pattern() :: module() | {app, atom()} | {callback, module(), atom()}. |
|
|
|
-type scope() :: {scope, [pid() | port() | all | processes | ports |existing | existing_processes | existing_ports |new | new_processes | new_ports]}. |
|
|
|
-type input() :: [pattern() | scope()]. |
|
|
|
|
|
|
|
-export_type([input/0]). |
|
|
|
|
|
|
|
%% The trace functions input is not as strict for user convenience. |
|
|
|
-type user_input() :: pattern() | input(). |
|
|
|
|
|
|
|
-type opts() :: #{mode => trace | profile, pool_id => any(), pool_size => pos_integer(), send => boolean(), running => boolean()}. |
|
|
|
|
|
|
|
-spec trace(user_input()) -> ok. |
|
|
|
-spec trace(userInput()) -> ok. |
|
|
|
trace(Input) -> |
|
|
|
trace(Input, tpTracerConsole). |
|
|
|
|
|
|
|
-spec trace(user_input(), module()) -> ok. |
|
|
|
-spec trace(userInput(), module()) -> ok. |
|
|
|
trace(Input, TracerMod) -> |
|
|
|
trace(Input, TracerMod, undefined, #{}). |
|
|
|
|
|
|
|
-spec trace(user_input(), module(), any()) -> ok. |
|
|
|
-spec trace(userInput(), module(), tracerOpts()) -> ok. |
|
|
|
trace(Input, TracerMod, TracerOpts) -> |
|
|
|
trace(Input, TracerMod, TracerOpts, #{}). |
|
|
|
|
|
|
|
-spec trace(user_input(), module(), any(), opts()) -> ok. |
|
|
|
trace(Input, TracerMod, TracerOpts, Opts) when is_list(Input) -> |
|
|
|
do_trace(Input, TracerMod, TracerOpts, Opts); |
|
|
|
trace(Input, TracerMod, TracerOpts, Opts) -> |
|
|
|
trace([Input], TracerMod, TracerOpts, Opts). |
|
|
|
-spec trace(userInput(), module(), tracerOpts(), traceOpts()) -> ok. |
|
|
|
trace(Input, TracerMod, TracerOpts, TraceOpts) when is_list(Input) -> |
|
|
|
do_trace(Input, TracerMod, TracerOpts, TraceOpts); |
|
|
|
trace(Input, TracerMod, TracerOpts, TraceOpts) -> |
|
|
|
trace([Input], TracerMod, TracerOpts, TraceOpts). |
|
|
|
|
|
|
|
do_trace(Input0, TracerMod, TracerOpts, Opts) -> |
|
|
|
%% @todo Remove eventually? |
|
|
|
do_trace(Input0, TracerMod, TracerOpts, TraceOpts) -> |
|
|
|
_ = application:ensure_all_started(eTpf), |
|
|
|
|
|
|
|
%% Start the pool of tracer processes. |
|
|
|
PoolID = maps:get(pool_id, Opts, default), |
|
|
|
PoolSize = maps:get(pool_size, Opts, erlang:system_info(schedulers)), |
|
|
|
PoolID = maps:get(poolId, TraceOpts, default), |
|
|
|
PoolSize = maps:get(poolSize, TraceOpts, erlang:system_info(schedulers)), |
|
|
|
true = PoolSize > 0, |
|
|
|
{ok, PoolPid} = supervisor:start_child(eTpf_sup, #{ |
|
|
|
id => PoolID, |
|
|
@ -55,11 +46,11 @@ do_trace(Input0, TracerMod, TracerOpts, Opts) -> |
|
|
|
}), |
|
|
|
Tracers = tpTracerPool:tracers(PoolPid), |
|
|
|
TracersMap = maps:from_list(lists:zip(lists:seq(0, length(Tracers) - 1), Tracers)), |
|
|
|
Mode = maps:get(mode, Opts, trace), |
|
|
|
Mode = maps:get(mode, TraceOpts, trace), |
|
|
|
Input1 = flatten(Input0, []), |
|
|
|
Input2 = ensure_pattern(Input1), |
|
|
|
Input = ensure_scope(Input2), |
|
|
|
trace_input(Input, #{mode => Mode, tracers => TracersMap}, Opts), |
|
|
|
trace_input(Input, #{mode => Mode, tracers => TracersMap}, TraceOpts), |
|
|
|
ok. |
|
|
|
|
|
|
|
flatten([], Acc) -> |
|
|
|