在做项目的时候,有时会有一些程序在服务器上运行很久,或者一直运行,并且可能出现报错的情况,比如对Spring Boot项目的服务接口进行测试的时候,调用接口的时候报错。这种情况下,由于不知道程序什么时候会报错,所以就要时不时看一下日志信息,很麻烦。
一般这种程序都是通过命令nohup xxx &
后台运行的,程序的日志信息会默认保存到nohup.out。所以我就想能不能用一个程序代替我定时监控程序是否报了错。当程序报错的时候,发邮件给我。
这个需求主要要实现以下两个功能:
对于第二点,linux可以通过mail命令发送邮件。而第一点,我的分析是这样。一旦程序报错之后,程序就会停止运行了。所以如果nohup.out有报错信息,一定在文件的最后面若干行。我的做法就是取文件最后50行,查找是否有Error,如果有,说明程序报错了,就发送邮件给我。
#!/bin/bash
function monitor_file() {
# 监控文件是否发生了更新
local file_to_monitor="$1"
lines_to_check=50
error_text="Error"
# 使用tail命令获取文件的最后几行,并使用grep检查是否包含错误文本
if tail -n $lines_to_check $file_to_monitor | grep -q $error_text; then
# echo "文件最后 $lines_to_check 行包含错误文本 '$error_text'"
echo 1
else
# echo "文件最后 $lines_to_check 行没有包含错误文本 '$error_text'"
echo 0
fi
}
function send_email() {
local subject="报错啦"
local body="报错具体信息请查看附件日志文件"
local log_file_path="$1"
local recipient="$2"
# 使用 mail 命令的 -A 选项附加文件
mail -s "$subject" -A "$log_file_path" "$recipient" <<EOF
$body
EOF
}
# 使用函数监控文件,并获取返回值
file_to_monitor="/path/to/nohup.out"
recipient="xxx@xxx.com"
result=$(monitor_file "$file_to_monitor")
if [ "$result" -eq 1 ]
then
# echo "Do something because the file has been updated."
send_email "$file_to_monitor" "$recipient"
fi
在写好该程序后,通过cron定时任务就能实现“固定时间检查一次是否报错,如果报错,发送邮件给我”的功能,这样就省去了我主动去查看是否报错的时间和精力。
这个需求中主要学习一到一些shell脚本的语法:
nohup xxx &
:&表示后台运行,nohup是为了防止断开ssh连接时程序终止nohup java -jar xxx.jar > output.log 2> error.log &
:将程序的标准输出和标准错误输出分别重定向到output.log和error.log文件中mail -s "$subject" -A "$log_file_path" "$recipient"
:将文件通过邮件发送出去