简体   繁体   English

如何从任何链接的进程中获得任何崩溃的通知?

[英]How to get notified for any crash from any linked process?

I start multiple (genserver) process in my app though Supervisor, Dynamic supervisor, and sometime simply a direct start_link.我在我的应用程序中启动了多个(genserver)进程,虽然主管、动态主管,有时只是一个直接的 start_link。 Some of them can crash without letting me know when I start the app with iex -S mix .当我使用iex -S mix启动应用程序时,其中一些可能会崩溃而不让我知道。 How to make sure I receive all the notification of any crash from any process, if I do not catch it myself?如果我自己没有发现,如何确保我收到来自任何进程的任何崩溃的所有通知? What are the good practice around "letting process crash" while keeping a trace of all the event?在跟踪所有事件的同时,“让进程崩溃”的好做法是什么?

XXX.start_link(ws_uri, __MODULE__, state, [{:name, MyModule}])

From the GenServer docs :GenServer 文档

terminate/2 is called if a callback (except init/1) does one of the following:如果回调(init/1 除外)执行以下操作之一,则调用terminate/2

-returns a :stop tuple - 返回一个 :stop 元组
-raises -加注
-calls Kernel.exit/1 - 调用 Kernel.exit/1
-returns an invalid value - 返回无效值
-the GenServer traps exits (using Process.flag/2) and the parent process sends an exit signal - GenServer 陷阱退出(使用 Process.flag/2)并且父进程发送退出信号

If part of a supervision tree, a GenServer will receive an exit signal when the tree is shutting down.如果是监督树的一部分,当树关闭时,GenServer 将收到退出信号。 The exit signal is based on the shutdown strategy in the child's specification,退出信号基于子规范中的关闭策略,
... ...
... ...
If the GenServer receives an exit signal (that is not :normal) from any process when it is not trapping exits it will exit abruptly with the same reason and so not call terminate/2.如果 GenServer 在没有捕获退出时从任何进程接收到退出信号(不是 :normal),它将以相同的原因突然退出,因此不会调用 terminate/2。 Note that a process does NOT trap exits by default and an exit signal is sent when a linked process exits or its node is disconnected.请注意,默认情况下,进程不会捕获退出,并且当链接进程退出或其节点断开连接时会发送退出信号。

Therefore it is not guaranteed that terminate/2 is called when a GenServer exits.因此,不能保证在 GenServer 退出时调用 terminate/2。 For such reasons, we usually recommend important clean-up rules to happen in separated processes either by use of monitoring or by links themselves.出于这些原因,我们通常建议通过使用监控或链接本身在分离的进程中发生重要的清理规则。 There is no cleanup needed when the GenServer controls a port (for example, :gen_tcp.socket) or File.io_device/0, because these will be closed on receiving a GenServer's exit signal and do not need to be closed manually in terminate/2.当 GenServer 控制端口(例如:gen_tcp.socket)或 File.io_device/0 时不需要清理,因为这些将在接收到 GenServer 的退出信号时关闭,并且不需要在 terminate/2 中手动关闭.

The solution I ended up using, thanks to @7stud, is to activate SASL and OTP loggin in the Elixir logger.感谢@7stud,我最终使用的解决方案是在 Elixir 记录器中激活 SASL 和 OTP 登录。

If you use mix, you can add to your config/config.exs the lines:如果你使用 mix,你可以在你的config/config.exs添加以下config/config.exs行:

config :logger,
  handle_otp_reports: true,
  handle_sasl_reports: true

For more information, see the elixir logger documentation .有关更多信息,请参阅elixir 记录器文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM