我正在监视一个 Erlang 应用程序,我目前正在尝试确定特定 PID 已经运行了多长时间。绝对时间戳或持续时间对我有用,但我在 process_info 或通过 sys 模块看不到这些数据位中的任何一个。有没有办法从 Erlang VM 中获取这些信息?
我可以从 ps 命令获取整个 VM 的启动时间,但这对单个 Erlang 进程没有任何可见性。
编辑:
我注意到当虚拟机崩溃时,erl_crash.dump 包含每个进程的启动时间戳,所以我知道它就在那里!
我正在监视一个 Erlang 应用程序,我目前正在尝试确定特定 PID 已经运行了多长时间。绝对时间戳或持续时间对我有用,但我在 process_info 或通过 sys 模块看不到这些数据位中的任何一个。有没有办法从 Erlang VM 中获取这些信息?
我可以从 ps 命令获取整个 VM 的启动时间,但这对单个 Erlang 进程没有任何可见性。
编辑:
我注意到当虚拟机崩溃时,erl_crash.dump 包含每个进程的启动时间戳,所以我知道它就在那里!
编写一个管理这个的过程。由于您可以找到给定进程的PID,因此您还可以monitor
在进程上设置a。然后,如果过程出错,您将在邮箱中收到一条消息。
我想这可以为您提供解决方案的基础。
tl; dr:是的,但你无法做到。
如果您深入了解https://github.com/erlang/otp上的 OTP 源代码,您会发现(通过搜索“erl_crash”)负责编写故障转储的文件称为erts/emulator/beam/break.c
.
在该文件中搜索“started”(这是一个很好的猜测,并且它出现在故障转储中)将带您到第 248-249 行(所有行号基于 OTP-18.3.1 标签),看起来像这样:
approx_started = (time_t) p->approx_started;
erts_print(to, to_arg, "Started: %s", ctime(&approx_started));
搜索源代码的其余部分approx_started
显示它被声明erts/emulator/beam/erl_process.h
为struct process
. 它写在erts/emulator/beam/erl_process.c
. 在写入故障转储时,它被读取的唯一位置是 in 。break.c
所以,是的,Erlang确实记录了进程启动的(大约)时间。但是,不,你不能得到它。
我不知道为什么它是“近似的”。
我正在查看工具栏:start()。进程监视器,不看时间活着或时间初始化,但它很容易制作。在进程字典中,您可以在初始化时保存一个值,并且该进程可以对该值响应其他进程。
对于字典过程中的读取值,您可以使用 get/1 和保存使用 put/2 (第一个键和第二个值)。
对该值的其他过程的响应与其他响应等相同。