为什么在检查程序返回退出代码 0 时 monit 会记录错误和状态失败

为什么在检查程序返回退出代码 0 时 monit 会记录错误和状态失败

问题 1

我想要使​​用 monit 版本 5.25.1 来监控无头运行的 LibreOffice-Process。

以下是我针对此方法的监控配置:

cat /etc/monit/conf.d/libreoffice


check program lo-check-8101 with path "/bin/bash /opt/libreoffice/chkloproc.sh TestLOPort8101 8101"
        with timeout 10 seconds
        if status != 0 then exec "/bin/bash /opt/libreoffice/loproc_is_down.sh"
        if status = 0 then exec "/bin/bash /opt/libreoffice/loproc_is_up.sh"

此 LibreOffice 实例正在监听端口 8101。

如果一切正常,检查脚本将返回 0,如果 LibreOffice 实例出现错误,则返回 101。我正在通过发送 HTML、请求文本并检查响应来测试正在运行的 LibreOffice 进程的文本转换。

动作脚本(loproc_is_down.sh / loproc_is_up.sh)正在添加 / 删除一个 iptables 规则,以向正在运行的 haproxy 宣告状态,haproxy 正在对该 LibreOffice 实例 / 进程进行端口检查...如果这听起来有点复杂,我很抱歉,但这不是我想在这里讨论的问题。

问题是,我不明白为什么 monit 会记录以下条目:

重启后监控日志

[CET Oct 29 16:58:18] info     : Starting Monit 5.25.1 daemon with http interface at [localhost]:2812
[CET Oct 29 16:58:18] info     : Monit start delay set to 10s
[CET Oct 29 16:58:28] info     : 'host1' Monit 5.25.1 started
[CET Oct 29 16:58:58] error    : 'lo-check-8101' status failed (0) -- no output
[CET Oct 29 16:58:58] info     : 'lo-check-8101' exec: '/bin/bash /opt/libreoffice/loproc_is_up.sh'
[CET Oct 29 16:59:28] error    : 'lo-check-8101' status failed (0) -- no output

...以及来自‘监控状态’的以下状态屏幕:

monit status
Monit 5.25.1 uptime: 0m

Program 'lo-check-8101'
  status                       Status failed
  monitoring status            Monitored
  monitoring mode              active
  on reboot                    start
  last exit value              0
  last output                  -
  data collected               Tue, 29 Oct 2019 16:58:58

System 'host1'
  status                       OK
  monitoring status            Monitored
  monitoring mode              active
  on reboot                    start
  load average                 [0.03] [0.02] [0.01]
  cpu                          0.6%us 0.6%sy 0.0%wa
  memory usage                 543.9 MB [7.8%]
  swap usage                   0 B [0.0%]
  uptime                       20d 1h 11m
  boot time                    Wed, 09 Oct 2019 16:47:51
  data collected               Tue, 29 Oct 2019 16:58:58

在我看来,检查脚本返回退出值 0,但状态被报告/解释为“状态失败”。

我不明白为什么 monit 在其日志文件中报告“错误:...状态失败(0)”。

除了对给定检查脚本程序的最后退出代码的解释之外,状态还有什么含义?


问题 2

monit 还有另一种反应,我无法理解,也许有人可以向我解释一下?

当我尝试通过停止 LibreOffice 进程来伪造它时,monit 在一个周期后识别出这一点,并启动所需/配置的动作脚本“loproc_is_down.sh”,并将最后的退出代码正确报告为 101,但带有日志行

“信息:状态成功(101)”

第一个循环,然后再次

“错误:状态失败(101)”

监控日志伪造失败

[CET Oct 29 17:14:28] info     : 'lo-check-8101' status succeeded (101) -- Error: Existing listener not found. Unable start listener by parameters. Aborting.
[CET Oct 29 17:14:28] error    : 'lo-check-8101' status failed (101) -- Error: Existing listener not found. Unable start listener by parameters. Aborting.
[CET Oct 29 17:14:28] info     : 'lo-check-8101' exec: '/bin/bash /opt/libreoffice/loproc_is_down.sh'
[CET Oct 29 17:14:58] error    : 'lo-check-8101' status failed (101) -- Error: Existing listener not found. Unable start listener by parameters. Aborting.
[CET Oct 29 17:15:28] error    : 'lo-check-8101' status failed (101) -- Error: Existing listener not found. Unable start listener by parameters. Aborting.

再次启动 LibreOffice 进程时则相反:

服务再次运行时监控日志

[CET Oct 29 17:15:58] error    : 'lo-check-8101' status failed (0) -- no output
[CET Oct 29 17:15:58] info     : 'lo-check-8101' exec: '/bin/bash /opt/libreoffice/loproc_is_up.sh'
[CET Oct 29 17:15:58] info     : 'lo-check-8101' status succeeded (0) -- no output
[CET Oct 29 17:16:28] error    : 'lo-check-8101' status failed (0) -- no output
[CET Oct 29 17:16:58] error    : 'lo-check-8101' status failed (0) -- no output

看起来 monit 运行了检查脚本,该脚本返回退出代码 0,并启动动作脚本“loproc_is_up.sh”并报告“状态成功(0)”

...但随后在接下来的周期中再次记录“错误:状态失败(0)”。

我不明白 monit 概念/文档中“状态”的含义...有人可以向我解释一下吗?

感谢您阅读这篇长文并希望能够帮助我找到答案。

答案1

Monit 的作用是捕捉问题在受监控实体上。

因此,您的配置逐行告诉 Monit:

check program lo-check-8101 with path "/bin/bash /opt/libreoffice/chkloproc.sh TestLOPort8101 8101" with timeout 10 seconds

执行二进制文件。存储退出代码和一些附加信息。

        if status != 0 then exec "/bin/bash /opt/libreoffice/loproc_is_down.sh"

如果状态不是 0,则会出现问题。现在执行二进制文件。

        if status = 0 then exec "/bin/bash /opt/libreoffice/loproc_is_up.sh"

如果状态为 0,则会出现问题。现在执行二进制文件。- 我甚至不知道此调用的结果应该是什么。这里一切都正常,那么为什么要执行某些操作呢?


可以这么说:有了这个配置,就不会出现“成功”的情况(=一切正常)。

为了优化它,你应该只捕捉 Monit 的问题:

check program lo-check-8101 with path "/opt/libreoffice/chkloproc.sh TestLOPort8101 8101"
    with timeout 10 seconds
    if status != 0 then exec "/opt/libreoffice/loproc_is_down.sh"
    if 2 restarts within 3 cycles then unmonitor

这意味着如果状态为 0,Monit 不会执行任何操作。

关于配置还有一些话:

  1. 如果我理解正确的话(看到这个问题),无头服务器将创建一个 PID 文件。因此,您可能还会使用check process一些send/ expectmagic 来验证服务是否正在运行。
  2. 如果你将.sh文件设置为可执行文件(+x;即chmod +x /opt/libreoffice/*.sh),并且你有一个正确的舍邦在这些文件中,您可以省略/bin/bash执行以提高可读性。

我对此的配置(不知道使用什么协议:8101,假设是 http)应该更像这样:

check process libre-local with pidfile "/var/run/libreoffice-server.pid"
    start program = "/usr/bin/systemctl start libreoffice-server" # Unit name is an assumption!
    stop program = "/usr/bin/systemctl stop libreoffice-server" # Unit name is an assumption!

    if failed
        port 8101
        protocol http
        request "/any_valid_entrypoint"
        for 2 cycles
    then restart

    # if loadavg (5min) per core > 1 for 5 cycles then restart
    if loadavg (5min) > 4 for 5 cycles then restart
    if totalmem > 2 GB for 5 cycles then restart
    if 3 restarts within 5 cycles then unmonitor

使用loadavg需要per core最新的 Monit 版本。因此它可能不适用于您的发行版,所以我注释掉了此行 ;)


根据原帖回复进行编辑(我希望您收到通知):

(我们不能评论<50 回复...这真的很痛苦)

如果我理解正确的话,你必须转换某些内容才能获取应用程序的状态,如果转换失败,则应重新启动应用程序。翻译为 Monit:

check program lo-check-8101 with path "CONVERT_HERE"
    with timeout 10 seconds
    if status != 0 then exec "/usr/bin/systemctl restart libreoffice-server"
    if 2 restarts within 3 cycles then unmonitor

...CONVERT_HERE如果转换顺利,则可执行文件以 0 退出,如果转换失败,则以 <>0 退出。我仍然觉得我在这里错过了一些东西。;)

您能否将所有三个可执行文件都放到一个要点或类似的东西中?

答案2

@boppy:谢谢你的回答。

你是对的,我需要处理“无头自由办公室”流程。

LibreOffice 有点讨厌,虽然它已经挂断了,但它仍在接受连接...所以,如果您能够转换某些东西(在检查脚本中发生),您只能知道正在运行的 lo 进程的健康状况。

因此,我不能依赖 PID 或端口检查...如果转换不起作用,则尝试使用我的检查脚本 + monit 来拒绝连接。

这背后的想法是:

如果 monit 正在向 iptables 添加一条规则以拒绝与 lo 进程的连接,则如果 lo 进程恢复/健康并再次转换,它应该删除这些添加的规则。

也许 monit 是错误的工具,或者我只是认为它太复杂了...但 monit 看起来比使用 cron 来执行这些检查和 iptables 更合适...也许我会尝试一下 cron。


我从您的回答中了解到一件重要的事情,即如果我在 monit 配置中使用“IF STATUS = 0 THEN EXEC ...”行,则没有成功状态。

因此,由于这个“IF ... EXEC”行,monit 不会将退出值 0 解释为“成功”。


感谢您的 monit-config ...如果 lo 进程失控,重新启动它们似乎是个好主意。


但是 monit 仍然有些问题...我通过将“-v”作为 /etc/defaults/monit 选项放入打开调试的 monit,然后查看以下日志行:(monit 周期配置为 30 秒)

[CET Oct 31 16:49:00] error    : 'lo-check-8101' status failed (0) -- conversion ok
[CET Oct 31 16:49:00] debug    : 'lo-check-8101' status succeeded (0) -- conversion ok
[CET Oct 31 16:49:00] debug    : 'lo-check-8101' program started
[CET Oct 31 16:49:30] error    : 'lo-check-8101' status failed (0) -- conversion ok
[CET Oct 31 16:49:30] debug    : 'lo-check-8101' status succeeded (0) -- conversion ok
[CET Oct 31 16:49:30] debug    : 'lo-check-8101' program started

这是 monit 错误吗?也许我需要更新版本的 monit。

相关内容