【问题标题】:How to get notified for any crash from any linked process?如何从任何链接进程获得任何崩溃通知?
【发布时间】:2021-02-05 15:43:30
【问题描述】:

我在我的应用程序中启动了多个(genserver)进程,虽然是 Supervisor、Dynamic supervisor,有时只是一个直接的 start_link。当我使用iex -S mix 启动应用程序时,其中一些可能会在不通知我的情况下崩溃。如果我自己没有收到它,如何确保我收到来自任何进程的任何崩溃通知?在跟踪所有事件的同时“让进程崩溃”的良好做法是什么?

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

【问题讨论】:

    标签: elixir erlang-otp


    【解决方案1】:

    感谢@7stud,我最终使用的解决方案是在 Elixir 记录器中激活 SASL 和 OTP 登录。

    如果你使用 mix,你可以添加到你的 config/config.exs 行:

    config :logger,
      handle_otp_reports: true,
      handle_sasl_reports: true
    

    有关详细信息,请参阅elixir logger documentation

    【讨论】:

    • :handle_otp_reports默认为true,无需自行设置。
    【解决方案2】:

    来自GenServer docs

    terminate/2 如果回调(init/1 除外)执行以下操作之一,则调用:

    -返回一个 :stop 元组
    -提高
    -调用 Kernel.exit/1
    - 返回一个无效值
    - GenServer 捕获退出(使用 Process.flag/2)并且父进程发送退出信号

    如果是监督树的一部分,GenServer 将收到退出信号 当树关闭时。退出信号是基于 子规范中的关闭策略,
    ...
    ...
    如果 GenServer 收到退出信号(不是:正常) 从任何没有捕获退出的进程中,它将突然退出 出于同样的原因,所以不要调用 terminate/2。注意一个过程 默认情况下不会捕获退出,并且当出现退出信号时会发送退出信号 链接进程退出或其节点断开连接。

    因此,不能保证 terminate/2 在 a GenServer 退出。出于这些原因,我们通常建议重要的 通过使用在分离的进程中发生的清理规则 监控或通过链接本身。不需要清理时 GenServer 控制一个端口(例如:gen_tcp.socket)或 File.io_device/0,因为这些将在收到 GenServer的退出信号,不需要在里面手动关闭 终止/2.

    【讨论】:

    • 您是否建议我在所有使用 GenServer 的模块中实现终止并手动输出收到的异常?
    • @JeremyCochoy,这不是你想做的吗?
    • @JeremyCochoy,有关其他选项,请参见此处:stackoverflow.com/questions/43372045/…
    • 一千谢谢。我查看了您的链接,然后找到了 SASL logger,然后查看了 elixir 记录器文档,它允许通过设置一个简单的标志来记录所有内容。如果没有你的帮助,我不会找到它!
    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 2019-05-15
    相关资源
    最近更新 更多