Skip to content

Instantly share code, notes, and snippets.

@id
Last active March 26, 2024 15:55
Show Gist options
  • Save id/cba5dbf7653d7eab6a03 to your computer and use it in GitHub Desktop.
Save id/cba5dbf7653d7eab6a03 to your computer and use it in GitHub Desktop.
Tracing in erlang
F = fun(F, Fd) -> receive stop -> io:format(Fd, "stop~n", []), file:close(Fd), ok; Msg -> io:format(Fd, "~p~n", [Msg]), F(F, Fd) end end.
{ok, Fd} = file:open("/tmp/trace.out", [write]), Tracer = proc_lib:spawn(fun() -> F(F, Fd) end).
%% trace everything
erlang:trace(Pid, true, [all, {tracer, Tracer}]).
%% stop tracing
erlang:trace(Pid, false, [all, {tracer, Tracer}]).
Tracer ! stop.
%% match pattern
f(Match), Match = [{[foo, '$1', '$2'], [], [{return_trace}]}].
%% Trace all calls to function myfun/3 where first argument is an atom 'foo' in module mymod
Match = [{[foo, '$1', '$2'], [], [{return_trace}]}].
erlang:trace_pattern({mymod, myfun, 3}, Match, [local]).
erlang:trace(all, true, [call, {tracer, Tracer}]).
%% stop tracing
erlang:trace(all, false, [call, {tracer, Tracer}]).
Tracer ! stop.
%% formatting erlang timestamp
FmtNow = fun({_, _, Micro} = Now) ->
{{Y,M,D}, {HH,MM,SS}} = calendar:now_to_local_time(Now),
io_lib:format("~.4.0w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w.~w",[Y, M, D, HH, MM, SS, Micro])
end.
%% function to trace calls into specific file
f(F), f(Fd), F = fun(F, Fd) ->
receive
stop ->
io:format(Fd, "stop~n", []),
file:close(Fd),
ok;
{trace_ts, Pid, call, {__Mod, __Fun, __Args}, Now} ->
Ts = FmtNow(Now),
io:format(Fd, "[~s] ~p called ~p:~p(~180p)~n", [Ts, Pid, __Mod, __Fun, __Args]),
F(F, Fd);
{trace_ts, Pid, return_from, {__Mod, __Fun, __Ar}, Ret, Now} ->
Ts = FmtNow(Now),
io:format(Fd, "[~s] ~p return from ~p:~p/~p: ~180p~n", [Ts, Pid, __Mod, __Fun, __Ar, Ret]),
F(F, Fd);
Msg ->
exit({unexpected_msg, Msg})
end
end.
%% open a file to write trace messages to and spawn a tracer process
f(Fd), {ok, Fd} = file:open("/tmp/trace.out", [write]).
f(Tracer), Tracer = proc_lib:spawn(fun() -> F(F, Fd) end).
%% generic match pattern, matches everything
f(Match), Match = [{'_', [], [{return_trace}]}].
%% trace all calls to all functions in Modules
Modules = [my_mod_1, my_mod_2].
lists:foreach(fun(M) -> erlang:trace_pattern({M, '_', '_'}, Match, [local]) end, Modules).
erlang:trace(all, true, [call, timestamp, {tracer, Tracer}]).
%% stop tracing
erlang:trace(all, false, [call, timestamp, {tracer, Tracer}]).
Tracer ! stop.
@alexandremcosta
Copy link

elixir example

:erlang.trace(:all, true, [:call])
:erlang.trace_pattern({ModuleName, :_, :_}, [{:_, [], [{:return_trace}]}])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment