erlang tracer 没有输出

No output from erlang tracer

我有一个模块 my_api,它有一个回调 cowboy 请求的函数 handle/2, 所以当我像这样发出一些 http 请求时:

curl http://localhost/test

我的应用程序调用了这个函数并且它工作正常,因为我在终端中得到了响应。

但在另一个终端中,我使用 remsh 附加到我的应用程序,并尝试使用 dbg 模块跟踪对该函数的调用,如下所示:

dbg:tracer().
dbg:tp(my_api, handle, 2, []).
dbg:p(all, c).

我预计在另一个终端向我的 api 发出 http 请求后,函数 my_api:handle/2 被调用并且我获得了有关此调用的一些信息(在最少的函数参数)附加到节点终端,但我在那里什么也得不到。我错过了什么?

当您调用 dbg:tracer/0 时,process 类型的跟踪器会启动一个消息处理程序,将所有跟踪消息发送到 user I/O 设备。您的远程 shell 的组长独立于 user I/O 设备,因此您的 shell 不会收到发送到 user 的输出。

允许您查看跟踪输出的一种方法是在服务器上设置跟踪端口,在单独的节点中设置跟踪客户端。如果你想要来自节点 foo 的痕迹,首先 remsh 到它:

$ erl -sname bar -remsh foo

然后设置一个跟踪端口。在这里,我们在主机端口 50000 上设置了一个 TCP/IP 跟踪端口(使用任何您喜欢的端口,只要它对您可用):

1> dbg:tracer(port, dbg:trace_port(ip, 50000)).

接下来,像之前一样设置跟踪参数:

2> dbg:tp(my_api, handle, 2, []).
{ok, ...}
3> dbg:p(all, c).
{ok, ...}

然后退出remsh,启动一个没有remsh的节点:

$ erl -sname bar

在此节点上,启动连接到主机端口 50000 的 TCP/IP 跟踪客户端:

1> dbg:trace_client(ip, {"localhost", 50000}).

此 shell 现在将收到来自 foodbg 条跟踪消息。在这里,我们使用 "localhost" 作为主机名,因为此节点与服务器节点位于同一主机上 运行,但如果您的客户端位于 运行 上,则需要使用不同的主机名一个单独的主机。

另一种方法更简单但依赖于未记录的函数,因此将来可能会中断,它是像您最初所做的那样 remsh 到要跟踪的节点,然后使用 dbg:tracer/2 发送 dbg 输出到你的遥控器 shell 的组长:

1> dbg:tracer(process, {fun dbg:dhandler/2, group_leader()}).
{ok, ...}
2> dbg:tp(my_api, handle, 2, []).
{ok, ...}
3> dbg:p(all, c).
{ok, ...}

由于这依赖于 dbg:dhandler/2 函数,该函数已导出但未记录,因此无法保证它始终有效。

最后,由于您正在跟踪所有进程,请注意dbg man page中描述的潜在问题,并务必在完成跟踪后调用dbg:stop_clear().