我全天通过 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'.