Linux Java日志自动化分析实战方案
一 架构与工具选型
二 快速落地方案 Shell脚本与cron
#!/usr/bin/env bash
set -Eeuo pipefail
LOG_DIR="/opt/app/logs"
APP_NAME="myapp"
ALERT_EMAIL="ops@example.com"
THRESHOLD=10
TMP_DIR="/tmp/java_logs_$(date +%F)"
mkdir -p "$TMP_DIR"
# 1) 当日新错误按应用聚合
for f in "$LOG_DIR"/*.log; do
[ -f "$f" ] || continue
base=$(basename "$f")
# 仅统计今天新增行(避免重复计数)
grep -a "$(date +%Y-%m-%d)" "$f" 2>/dev/null \
| grep -Ei "ERROR|Exception" \
| sed 's/.*ERROR/ERROR/' \
| sort \
| uniq -c \
| sort -nr \
| tee "$TMP_DIR/${APP_NAME}_${base}_$(date +%H%M).txt"
done
# 2) 汇总并告警
total=$(find "$TMP_DIR" -type f -exec cat {} + | awk '{sum+=$1} END {print sum+0}')
echo "【$APP_NAME】今日新增异常总数:$total(阈值:$THRESHOLD)" > "$TMP_DIR/summary.txt"
cat "$TMP_DIR"/*.txt >> "$TMP_DIR/summary.txt"
if [ "$total" -ge "$THRESHOLD" ]; then
mail -s "[ALERT] $APP_NAME Java日志异常激增 $total" "$ALERT_EMAIL" < "$TMP_DIR/summary.txt"
fi
# 3) 归档与清理(示例:保留近7天)
tar czf "$LOG_DIR/archive/${APP_NAME}_logs_$(date +%F).tgz" -C "$LOG_DIR" ./*.log 2>/dev/null || true
> "$LOG_DIR/application.log" # 轮转后清空当前日志(确保应用支持重新打开日志)
find "$LOG_DIR/archive" -mtime +7 -delete 2>/dev/null || true
# 每日分析
0 2 * * * /usr/bin/bash /opt/scripts/analyze_java_logs.sh >> /var/log/log_analysis.log 2>&1
# 实时增量扫描(每10分钟)
*/10 * * * * /usr/bin/bash -lc 'tail -n0 -F /opt/app/logs/*.log 2>/dev/null | grep -Ei "ERROR|Exception" | tail -n 50 >> /var/log/java_error_realtime.log'
三 集中化方案 ELK或EFK
input {
file {
path => "/opt/app/logs/*.log"
start_position => "beginning"
sincedb_path => "/var/lib/logstash/sincedb-java"
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:msg}" }
}
date {
match => [ "timestamp", "ISO8601", "yyyy-MM-dd HH:mm:ss.SSS" ]
target => "@timestamp"
}
if [level] =~ /ERROR|Exception/i {
mutate { add_tag => ["alert_candidate"] }
}
}
output {
elasticsearch {
hosts => ["http://localhost:9200"]
index => "java-logs-%{+YYYY.MM.dd}"
}
stdout { codec => rubydebug }
}
四 云原生与轻量方案 Grafana Loki Promtail
五 关键实践与优化
/opt/app/logs/*.log {
daily
rotate 7
compress
missingok
notifempty
create 0640 appuser appgroup
copytruncate
}