如何监控通过 cron 执行的脚本并在经过的时间执行操作?

如何监控通过 cron 执行的脚本并在经过的时间执行操作?

我全天通过 CRON 运行大量脚本,由于它们依赖于第三方提供商,而第三方提供商有时会很慢,因此我目前以这种方式运行它们,timeout 60m bash /script.sh这对我来说效果很好。60 分钟后终止脚本,因为它只需要 5 分钟即可运行,等等。

当脚本的某些部分执行时,我确实会记录作业并将输出到日志文件,但我希望更详细地了解脚本和作业的运行情况。我正在寻找一种方法来通知我,例如,每执行 10 分钟一次(当然需要一个运行计时器)。我不需要知道如何通知我或我可以处理的任何内容,但我正在寻找有关“如何”监控各种脚本的输入,这些脚本每隔 X 分钟通知我一次(不同脚本的通知时间不同),以及在脚本被终止时通知我。

我确实尝试了各种各样的方法ps,但除非我的工作非常奇怪,否则我会得到每个执行脚本的 3 个结果。

CRON 条目示例:

42 01 * * * mkdir -p '/tmp-data/logs/specific-script/' && timeout 60m bash /script.sh > /tmp-data/logs/specific-script-$(date ...)

使用类似ps -e -o pid,etime,etimes,cmd | grep '[b]ash'

看来每个 CRON 作业都会有三个条目,当然所有这三个条目都不需要被终止,所以我甚至不知道如何找到需要终止的“那个”...

/bin/sh -c timeout 60m bash /script.sh ...
timeout 60m bash /script.sh ...
bash /script.sh ...

并不是真的在寻找代码,甚至不是在寻找任何方向,比如其他人如何“监控”他们的工作并密切关注他们的运行时间,如果运行缓慢/运行时间长则执行命令,并杀死运行时间过长的命令并收到通知它已被杀死。

答案1

我已将大部分 cron 作业移至 systemd 计时器单元。这使得管理它们的过程变得更容易;我不需要ps查找进程来查看要杀死的 PID。

例如,而不是:

42 01 * * *  mkdir -p '/tmp-data/logs/specific-script/' && timeout 60m bash /script.sh > /tmp-data/logs/specific-script-$(date ...)

我会创建一个服务~/.config/systemd/user/myservice.service

[Service]
RuntimeMaxSec=60m
ExecStart=/bin/bash /script.sh

然后计时器~/.config/systemd/user/myservice.timer

[Timer]
OnCalendar=01:42:00

[Install]
WantedBy=default.target

进而:

$ systemctl --user enable myservice.timer

现在:

  • 我可以依靠 systemd 来收集日志,通过运行可以看到这些日志journalctl --user -u myservice。我可以传递各种附加标志来journalctl按时间、内容等过滤消息。

  • 我没有使用,而是timeout让 systemd 管理最大服务运行时间。

  • 如果我需要提前停止某项服务,我只需运行systemctl --user stop myservice;无需使用 来查找ps

  • 如果我想定期停止服务运行,我可以systemctl --user stop myservice.timer(停止计时器直到下次重启),或者systemctl --user disable --now myservice.timer(停止计时器并防止它在下次重启后再次启动)。

  • 如果我想按需运行该服务,我可以systemctl --user start myservice


关于监控您的服务,您可能可以使用ExecStopPost服务单元中的脚本来处理。这些脚本可以访问环境变量的数量, 包括$SERVICE_RESULT

如果您的服务由于超出而被终止RuntimeMaxSec$SERVICE_RESULT则会是timeout,因此您可以检查这一点并执行一些监控操作(发送电子邮件、播放声音等等)。

[Service]
RuntimeMaxSec=60m
ExecStart=/bin/bash /script.sh
ExecStopPost=/bin/bash /script-to-check-and-notify-me.sh

超时也将成为服务日志的一部分,例如:

$ journalctl --user -u exampleservice
Aug 28 07:59:44 madhatter systemd[5559]: Started exampleservice.service.
Aug 28 07:59:54 madhatter systemd[5559]: exampleservice.service: Service reached runtime time limit. Sto>
Aug 28 07:59:54 madhatter systemd[5559]: exampleservice.service: Failed with result 'timeout'.

相关内容