MST
星途 面试题库

面试题:Bash脚本日志分析的性能优化与自动化

在一个高并发的生产环境中,应用程序每秒会产生大量日志写入到`prod.log`文件中。日志格式为'时间戳 进程ID 线程ID 日志级别 日志信息'。请设计并实现一个Bash脚本解决方案,能够实时分析日志,当发现某个进程在1分钟内产生超过100条错误日志时,自动发送邮件通知管理员(假设邮件发送可通过`sendmail`命令实现),并且要保证脚本在高负载下的性能和稳定性,尽可能减少资源占用。描述你的设计思路以及具体实现的脚本代码。
25.7万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 实时读取日志:使用 tail -f 命令实时读取 prod.log 文件的新增内容。
  2. 日志解析:对每一行日志进行解析,提取进程ID和日志级别。
  3. 错误日志计数:维护一个进程ID与错误日志计数的映射关系,每出现一条错误日志,对应进程ID的计数加1。
  4. 定时检查:每隔1分钟检查一次每个进程的错误日志计数,若超过100条,则发送邮件通知管理员。
  5. 性能优化:使用数组存储进程ID和计数,避免频繁文件I/O操作,减少资源占用。

脚本代码

#!/bin/bash

# 初始化进程错误日志计数数组
declare -A error_count
# 存储进程ID的数组
pids=()
# 上一次检查时间
last_check_time=$(date +%s)

# 实时读取日志
tail -f prod.log | while read line; do
    # 提取时间戳、进程ID、日志级别
    timestamp=$(echo $line | awk '{print $1}')
    pid=$(echo $line | awk '{print $2}')
    log_level=$(echo $line | awk '{print $4}')

    # 检查是否为错误日志
    if [ "$log_level" = "ERROR" ]; then
        if [ -z "${error_count[$pid]}" ]; then
            error_count[$pid]=1
            pids+=($pid)
        else
            error_count[$pid]=$((error_count[$pid]+1))
        fi
    fi

    # 每隔1分钟检查一次
    current_time=$(date +%s)
    if [ $((current_time - last_check_time)) -ge 60 ]; then
        for pid in "${pids[@]}"; do
            if [ ${error_count[$pid]} -gt 100 ]; then
                echo "进程 $pid 在1分钟内产生超过100条错误日志" | sendmail -v 管理员邮箱地址
            fi
            # 重置计数
            error_count[$pid]=0
        done
        last_check_time=$current_time
    fi
done

注意事项

  1. 替换邮箱地址:脚本中的 管理员邮箱地址 需要替换为实际的管理员邮箱。
  2. 权限问题:确保脚本运行的用户有执行 sendmail 命令的权限,并且 prod.log 文件可读取。
  3. 稳定性:在高负载环境下,tail -fsendmail 命令本身的性能和稳定性需要关注,必要时可以考虑使用更高效的日志读取和邮件发送方式。