Тем временем я понял, как это сделать, на самом деле это не так уж сложно. Чтобы иметь процесс, обрабатывающий вывод сообщения трассировки, вам просто нужно использовать dbg:trace/2,3
и написать одну функцию, которая выполняет форматирование.
Мы пишем небольшой модуль, содержащий функцию для передачи на dbg:trace
:
-module(trtool).
-export([nested/2]).
nested({trace, _Pid, call, {Mod, Fun, Param}}, Level) ->
io:format("~s~p:~p ~p\n",
[lists:duplicate(Level, "| "), Mod, Fun, Param]),
Level + 1;
nested({trace, _Pid, return_from, {Mod, Fun, Arity}, Rval}, Level) ->
L = Level - 1,
io:format("~s~p:~p/~b -> ~p\n",
[lists:duplicate(L, "| "), Mod, Fun, Arity, Rval]),
L;
nested(Any, Level) ->
io:format("trace_msg: ~p\n", [Any]),
Level.
Функция принимает два аргумента, в первом случае ей передается сообщение трассировки, представляющее собой кортеж с удобными полями. Чтобы выяснить, как структурируются сообщения, которые вы хотите отформатировать, просто начните с простой функции, которая печатает все, как в последнем предложении примера функции.
Второй формат - это состояние, которое может содержать любые данные. Мы передаем начальное значение при вызове dbg:trace
и возвращаем следующее значение из нашей функции.
В примере nested
мы просто пропускаем уровень отступа, который будет увеличиваться и уменьшаться в предложениях call
и return_from
.
Теперь давайте попробуем это, сначала вызвав dbg:tracer/2
, первый параметр должен быть атомом process
, второй параметр - кортеж, содержащий наше вновь написанное веселье и начальное значение для параметра состояния.
1> dbg:tracer(process, {fun trtool:nested/2, 0}).
{ok,<0.70.0>}
Затем мы настраиваем трассировку, как и раньше:
2> dbg:p(all, c), dbg:tpl(user_default,hop,x),dbg:tpl(user_default,rec,x).
{ok,[{matched,nonode@nohost,2},{saved,x}]}
Затем мы запускаем наш вызов функции для трассировки, и за вложением можно легко следовать:
3> rec(3).
user_default:rec [3]
| user_default:rec [3,1,3]
| | user_default:rec [3,1,2]
| | | user_default:rec [3,1,1]
| | | | user_default:rec [3,1,0]
| | | | | user_default:hop [3,1,0]
| | | | | user_default:hop/3 -> {3,21}
| | | | user_default:rec/3 -> {3,21,1}
| | | | user_default:rec [6,2,-1]
| | | | | user_default:hop [6,2,1]
| | | | | user_default:hop/3 -> {2,46}
| | | | user_default:rec/3 -> {2,46,1}
| | | user_default:rec/3 -> {5,67,2}
| | | user_default:rec [8,3,0]
| | | | user_default:hop [8,3,0]
| | | | user_default:hop/3 -> {3,144}
| | | user_default:rec/3 -> {3,144,1}
| | user_default:rec/3 -> {8,211,3}
| | user_default:rec [11,4,1]
| | | user_default:rec [11,4,0]
| | | | user_default:hop [11,4,0]
| | | | user_default:hop/3 -> {3,258}
| | | user_default:rec/3 -> {3,258,1}
| | | user_default:rec [14,5,-1]
| | | | user_default:hop [14,5,1]
| | | | user_default:hop/3 -> {2,260}
| | | user_default:rec/3 -> {2,260,1}
| | user_default:rec/3 -> {5,518,2}
| user_default:rec/3 -> {13,729,5}
user_default:rec/1 -> {15,729}
{15,729}
4>