我正在 Ubuntu 上运行 24/7 的 YouTube 流。我的 ffmpeg 命令包含在 systemd 服务中。在某些情况下,ffmpeg 命令会失败,并且 systemd 重新启动的速度不够快,无法保持 YouTube 流的活动。发生这种情况时,我需要守护程序重新加载并重新启动 systemd 服务。
为了解决这个问题,我编写了一个 bash 脚本来检查日志中是否有流结束错误,但是,它似乎不起作用。自从实现这个脚本以来,我就遇到了失败,而且它似乎没有被触发。
两个问题:
#!/bin/bash
RESET=0
while true; do
# Get the current time minus 1 minute
LAST_1_MINUTE=$(date -d '1 minute ago' '+%b %e %H:%M:%S')
# Run the command to check for the error within the last minute
if journalctl --since "$LAST_1_MINUTE" | grep -qi "Error writing trailer"; then
if [ $RESET -lt 1 ]; then
# Perform actions if error is detected
sudo systemctl daemon-reload && \
echo "Restarting master.service by monitor.sh script at $(date)" >> /var/log/monitor.log && \
sudo systemctl restart master.service
RESET=2
fi
else
RESET=$((RESET - 1))
fi
# Wait for 20 seconds before the next iteration
sleep 20
done
有没有更有效的方法来完成我正在做的事情?
是的;在很多方面。最重要的是,日志消息可以作为“连续流”接收,而无需每 X 秒重新检查一次。对于传统的 syslog,您可以 tail -f
日志文件,它将使用 inotify 来输出行;对于 Journald,您可以使用
journalctl -f
执行相同的操作。一旦有了日志流,循环就变成了while read
——读取功能将自动暂停,直到数据可用,空闲时不消耗任何资源,同时提供即时更新。journalctl -f | while IFS= read -r line; do
...
done
(即使没有这个,您也可以通过使用journalctl对相对时间戳的内置支持(即“最后一分钟”的
date
)来避免调用
journalctl -S -1m
,或者使用其对在特定光标处恢复的支持,即
journalctl --cursor-file=/tmp/cursor
)。很可能您不关心all日志,因此将输出限制为仅您服务的日志会更有效 - Journalctl 具有 -u
选项来按服务匹配,
-t
来按“syslog 标记进行匹配” “([xyz]:
之前的名称),您甚至可以执行 journalctl /usr/bin/ffmpeg
按可执行文件进行过滤。(您可能还希望使用 logger
或 systemd-cat
将脚本本身记录到
系统日志。)