#!/bin/bash
# curl -sSL https://git.nguoiduathu.eu.org/devops/vps_setup/raw/branch/main/auto_restart_apache.sh -o auto_restart_apache.sh && chmod +x auto_restart_apache.sh
# or
# wget -qO- https://git.nguoiduathu.eu.org/devops/vps_setup/raw/branch/main/auto_restart_apache.sh -O auto_restart_apache.sh && chmod +x auto_restart_apache.sh
# --- HỖ TRỢ TỰ ĐỘNG CẬP NHẬT SCRIPT ---
if [ "$1" = "update" ]; then
echo "Đang cập nhật auto_restart_apache.sh..."
SCRIPT_PATH="${BASH_SOURCE[0]}"
if [ -z "$SCRIPT_PATH" ]; then
SCRIPT_PATH="auto_restart_apache.sh"
fi
curl -sSL https://git.nguoiduathu.eu.org/devops/vps_setup/raw/branch/main/auto_restart_apache.sh -o "$SCRIPT_PATH" && chmod +x "$SCRIPT_PATH"
if [ $? -eq 0 ]; then
echo "Cập nhật thành công!"
exit 0
else
echo "Cập nhật thất bại!"
exit 1
fi
fi
# --- CẤU HÌNH TELEGRAM (Tải từ file .env) ---
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "$SCRIPT_DIR/.env" ]; then
set -a
source "$SCRIPT_DIR/.env"
set +a
elif [ -f "./.env" ]; then
set -a
source "./.env"
set +a
fi
# Dự phòng giá trị mặc định nếu không tìm thấy hoặc chưa cấu hình trong .env
TELEGRAM_TOKEN="${TELEGRAM_TOKEN:-}"
TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-"-1002063999592"}"
# --- CẤU HÌNH ĐƯỜNG DẪN ---
ACCESS_LOGS="${ACCESS_LOGS:-${ACCESS_LOG:-"/www/wwwlogs/access_log"}}"
LOG_OUTPUT="/www/wwwlogs/incident_report.log"
COUNT_FILE="/tmp/apache_error_count.txt"
THRESHOLD=200
# Lấy IP Public của Server
SERVER_IP=$(curl -s https://ifconfig.me/ip || curl -s https://icanhazip.com)
# Định dạng thời gian
CURRENT_TIME=$(date +"%d/%b/%Y:%H:%M")
LOG_TIME=$(date "+%Y-%m-%d %H:%M:%S")
# 1. KIỂM TRA SỨC KHỎE HỆ THỐNG (TỰ ĐỘNG PHÁT HIỆN PROXY NGINX + APACHE)
# Tự động phát hiện cổng của Apache
APACHE_PORT=80
if ss -tuln | grep -q :8288; then
APACHE_PORT=8288
elif netstat -tuln | grep -q :8288 2>/dev/null; then
APACHE_PORT=8288
fi
# Kiểm tra xem Nginx và Apache có đang chạy không
NGINX_ALIVE=$(pgrep -f nginx | wc -l)
PROC_ALIVE=$(pgrep -f httpd | wc -l)
# Kiểm tra HTTP Code cổng công cộng (Port 80)
HTTP_CODE=$(curl --write-out %{http_code} --silent --output /dev/null --connect-timeout 5 127.0.0.1:80)
# Kiểm tra HTTP Code Apache trực tiếp (Port 8288) nếu chạy qua proxy
BACKEND_HTTP_CODE=200
if [ "$APACHE_PORT" -eq 8288 ]; then
BACKEND_HTTP_CODE=$(curl --write-out %{http_code} --silent --output /dev/null --connect-timeout 5 127.0.0.1:8288)
fi
# 2. PHÂN TÍCH DỮ LIỆU SÂU
TMP_LOG=$(mktemp)
> "$TMP_LOG"
for ACCESS_LOG in ${ACCESS_LOGS//,/ }; do
if [ -f "$ACCESS_LOG" ]; then
grep "$CURRENT_TIME" "$ACCESS_LOG" | grep -v "incident_report.log" | grep -v "127.0.0.1" >> "$TMP_LOG"
fi
done
REQ_COUNT=$(wc -l < "$TMP_LOG")
if [ "$REQ_COUNT" -gt 0 ]; then
# Top API kèm Method (GET/POST)
TOP_API=$(awk '{print $6, $7}' "$TMP_LOG" | tr -d '"' | sort | uniq -c | sort -rn | head -n 5)
# Top IP (Đã lọc bỏ local)
TOP_IP=$(awk '{print $1}' "$TMP_LOG" | sort | uniq -c | sort -rn | head -n 5)
# Top User-Agent (Phát hiện bot/crawl)
TOP_AGENTS=$(awk -F'\"' '{print $6}' "$TMP_LOG" | cut -d' ' -f1-3 | sort | uniq -c | sort -rn | head -n 3)
# Thống kê phân bổ Status Code (200, 404, 500...)
STATUS_STATS=$(awk '{print $9}' "$TMP_LOG" | sort | uniq -c | sort -rn)
# Top API phản hồi lâu nhất (Đổi micro giây sang giây)
TOP_SLOW=$(awk '{ printf "%.2fs %s %s\n", $NF/1000000, $6, $7 }' "$TMP_LOG" | tr -d '"' | sort -rn | head -n 5)
else
TOP_API="No requests"
TOP_IP="No requests"
TOP_AGENTS="No requests"
STATUS_STATS="No requests"
TOP_SLOW="No requests"
fi
# 3. LOGIC BIẾN CỐ (Bảo vệ thông minh)
IS_DOWN=false
RESTART_APACHE=false
RESTART_NGINX=false
# Trường hợp 1: Chạy Apache trực tiếp trên Port 80
if [ "$APACHE_PORT" -eq 80 ]; then
if [ "$HTTP_CODE" -ne 200 ]; then
if [ "$PROC_ALIVE" -eq 0 ] || [ "$HTTP_CODE" -eq 000 ] || [ "$HTTP_CODE" -ge 500 ]; then
IS_DOWN=true
RESTART_APACHE=true
fi
fi
# Trường hợp 2: Chạy Nginx (Port 80) + Apache (Port 8288) làm Reverse Proxy
else
# Kiểm tra Nginx
if [ "$NGINX_ALIVE" -eq 0 ] || [ "$HTTP_CODE" -eq 000 ]; then
IS_DOWN=true
RESTART_NGINX=true
fi
# Kiểm tra Apache Backend (Nếu Nginx sống nhưng trả về 502/504 Bad Gateway, hoặc Apache chết hẳn)
if [ "$PROC_ALIVE" -eq 0 ] || [ "$BACKEND_HTTP_CODE" -eq 000 ] || [ "$BACKEND_HTTP_CODE" -ge 500 ] || [ "$HTTP_CODE" -eq 502 ] || [ "$HTTP_CODE" -eq 504 ]; then
IS_DOWN=true
RESTART_APACHE=true
fi
fi
# 4. XỬ LÝ LOG CHI TIẾT VÀ BÁO CÁO
if [ "$IS_DOWN" = true ]; then
VAL=$(cat "$COUNT_FILE" 2>/dev/null || echo 0)
VAL=$((VAL + 1))
echo $VAL > "$COUNT_FILE"
HEADER="🚨 [CRITICAL] APACHE DOWN/ERROR"
# --- ĐẦY ĐỦ NỘI DUNG LOG CHI TIẾT KHI SẬP ---
{
echo "================ [$LOG_TIME] CRITICAL ================"
echo "Server IP: $SERVER_IP"
echo "Summary: $REQ_COUNT req/min - HTTP Status: $HTTP_CODE"
echo "Lần lỗi liên tiếp: $VAL"
echo "--------------------------------------------"
echo "Top API:"
echo "$TOP_API"
echo ""
echo "Status Stats:"
echo "$STATUS_STATS"
echo ""
echo "Slowest Requests:"
echo "$TOP_SLOW"
echo ""
echo "User Agents:"
echo "$TOP_AGENTS"
echo ""
echo "Top IP:"
echo "$TOP_IP"
echo "--------------------------------------------"
echo ""
} >> "$LOG_OUTPUT"
else
# Hoạt động bình thường -> Reset bộ đếm lỗi về 0
echo 0 > "$COUNT_FILE"
echo "Apache hoạt động bình thường."
if [ "$REQ_COUNT" -gt "$THRESHOLD" ]; then
HEADER="⚠️ [WARNING] HIGH REQUEST DETECTED"
else
# Trạng thái lý tưởng: Không lỗi, không vượt ngưỡng -> Thoát im lặng
rm -f "$TMP_LOG"
exit 0
fi
fi
# --- ĐẦY ĐỦ NỘI DUNG GỬI TELEGRAM ---
REPORT="----------------------------------
$HEADER
🖥️ Server: $SERVER_IP
⏰ Time: $LOG_TIME
📊 Requests/min: $REQ_COUNT (Thật)
🌐 HTTP Code: $HTTP_CODE
----------------------------------
🔥 TOP API & METHOD:
$TOP_API
⏳ TOP SLOWEST (s):
$TOP_SLOW
📡 HTTP STATUS DISTRIBUTION:
$STATUS_STATS
👥 TOP AGENTS:
$TOP_AGENTS
📍 TOP IP (Excluding Local):
$TOP_IP"
# --- RESTART NẾU LỖI LIÊN TIẾP 2 LẦN ---
if [ "$IS_DOWN" = true ] && [ "$VAL" -ge 2 ]; then
ACTION_MSG=""
if [ "$RESTART_APACHE" = true ]; then
fuser -k $APACHE_PORT/tcp > /dev/null 2>&1 || true
rm -f /www/server/apache/logs/httpd.pid
/etc/init.d/httpd start > /dev/null 2>&1 || systemctl start httpd > /dev/null 2>&1 || true
ACTION_MSG="Force Restarted Apache (Port $APACHE_PORT)!"
fi
if [ "$RESTART_NGINX" = true ]; then
/etc/init.d/nginx restart > /dev/null 2>&1 || systemctl restart nginx > /dev/null 2>&1 || true
if [ -n "$ACTION_MSG" ]; then
ACTION_MSG="$ACTION_MSG & Restarted Nginx!"
else
ACTION_MSG="Restarted Nginx (Port 80)!"
fi
fi
# Đính kèm thêm hành động sửa lỗi vào tin nhắn Telegram
REPORT="$REPORT 🛠️ ACTION: $ACTION_MSG"
# Ghi lại hành động vào file log hệ thống
echo "[$LOG_TIME] ACTION: $ACTION_MSG due to 2 consecutive failures." >> "$LOG_OUTPUT"
echo 0 > "$COUNT_FILE"
# --- TIẾN HÀNH GỬI TELEGRAM (Cho cả CRITICAL và WARNING) ---
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
--data-urlencode "chat_id=$TELEGRAM_CHAT_ID" \
--data-urlencode "text=$REPORT" \
-d "parse_mode=HTML" > /dev/null
fi
rm -f "$TMP_LOG"