如何使用bash统计日志中字符串出现次数并在阈值达标时执行对应命令
Bash日志匹配触发执行脚本实现方案
定时统计版本(适合定期巡检场景)
#!/bin/bash # 替换为实际日志文件路径 LOG_FILE="/var/log/your_service.log" # 触发阈值 TRIGGER_THRESHOLD=5 # 规则配置 格式:待匹配字符串|触发执行的命令 MONITOR_RULES=( "is already connected on srv 21|telnet 192.168.1.6" "is already connected on srv 7|telnet 192.168.1.39" # 可按格式新增更多规则 ) for rule_item in "${MONITOR_RULES[@]}"; do match_content="${rule_item%%|*}" exec_command="${rule_item##*|}" # 统计匹配次数 -F 指定固定字符串匹配,避免特殊字符转义问题 hit_count=$(grep -F -c -- "$match_content" "$LOG_FILE") if [ "$hit_count" -ge "$TRIGGER_THRESHOLD" ]; then echo "匹配内容「${match_content}」出现次数:${hit_count},达到阈值触发执行:${exec_command}" # 执行目标命令 ${exec_command} fi done
使用说明
- 将脚本保存为
log_monitor.sh,执行chmod +x log_monitor.sh赋予执行权限 - 可配合crontab实现定时执行,例如每分钟巡检一次,crontab配置如下:
* * * * * /bin/bash /path/to/log_monitor.sh >> /var/log/monitor_run.log 2>&1 - 如果仅需要统计最近一段时间的日志避免历史数据干扰,可将统计行替换为以下写法(示例为统计最近1000行日志):
hit_count=$(tail -n 1000 "$LOG_FILE" | grep -F -c -- "$match_content")
实时监控版本(适合低延迟响应场景)
可实现日志新增内容实时检测:
#!/bin/bash LOG_FILE="/var/log/your_service.log" TRIGGER_THRESHOLD=5 # 定义规则映射 待匹配字符串为key,触发命令为value declare -A RULE_MAP RULE_MAP["is already connected on srv 21"]="telnet 192.168.1.6" RULE_MAP["is already connected on srv 7"]="telnet 192.168.1.39" # 初始化计数关联数组 declare -A COUNT_MAP for match_str in "${!RULE_MAP[@]}"; do COUNT_MAP[$match_str]=0 done # 监听日志新增内容 tail -f "$LOG_FILE" | while read new_log_line; do for match_str in "${!RULE_MAP[@]}"; do if [[ "$new_log_line" == *"$match_str"* ]]; then COUNT_MAP[$match_str]=$((COUNT_MAP[$match_str]+1)) if [ "${COUNT_MAP[$match_str]}" -ge "$TRIGGER_THRESHOLD" ]; then echo "匹配内容「${match_str}」累计出现${COUNT_MAP[$match_str]}次,触发执行:${RULE_MAP[$match_str]}" ${RULE_MAP[$match_str]} # 可选:执行后重置计数,避免重复触发 # COUNT_MAP[$match_str]=0 fi fi done done
使用说明
- 可配合systemd配置为后台服务常驻运行,实现7*24小时实时监控
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

