【Linux】shell脚本+cron定时任务实现“当程序报错时,发送邮件”

背景

在做项目的时候,有时会有一些程序在服务器上运行很久,或者一直运行,并且可能出现报错的情况,比如对Spring Boot项目的服务接口进行测试的时候,调用接口的时候报错。这种情况下,由于不知道程序什么时候会报错,所以就要时不时看一下日志信息,很麻烦。

解决方案

一般这种程序都是通过命令nohup xxx &后台运行的,程序的日志信息会默认保存到nohup.out。所以我就想能不能用一个程序代替我定时监控程序是否报了错。当程序报错的时候,发邮件给我。

代码实现

这个需求主要要实现以下两个功能:

  1. 监控日志是否报了错
  2. 发送邮件

对于第二点,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="[email protected]"

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":将文件通过邮件发送出去

你可能感兴趣的:(Linux,linux,运维,服务器)