Tự động hóa kiểm tra sức khỏe hệ thống và vệ sinh log bằng Bash và Cron
Trong môi trường quản trị hệ thống (Sysadmin), một trong những thách thức lớn nhất là đảm bảo tính sẵn sàng cao của các máy chủ khi lượng tài nguyên bị tiêu thụ quá mức hoặc khi các file nhật ký (log) chiếm dụng toàn bộ dung lượng ổ cứng. Việc theo dõi thủ công thông qua SSH vào từng máy chủ để kiểm tra không những kém hiệu quả mà còn dễ bỏ sót các sự cố tiềm ẩn. Bài viết này sẽ hướng dẫn bạn xây dựng một giải pháp tự động hóa toàn diện sử dụng Bash scripting để quét tài nguyên hệ thống, kết hợp với Cron để lên lịch chạy định kỳ, và gửi cảnh báo ngay lập tức qua email hoặc Slack khi phát hiện bất thường. Đây là nền tảng vững chắc trước khi bạn mở rộng quy mô sang các công cụ quản lý cấu hình như Ansible.
Chuẩn bị môi trường và khái niệm cơ bản
Trước khi bắt tay vào viết script, chúng ta cần hiểu rõ cơ chế hoạt động của các thành phần chính. Cron là một daemon trong hệ điều hành Linux dùng để lên lịch chạy các tác vụ lặp lại. Khi Cron kích hoạt, nó sẽ gọi script Bash của bạn để thực thi các lệnh. Script này sẽ đóng vai trò là bộ não, thực hiện các phép tính logic, so sánh giá trị ngưỡng (threshold) và quyết định việc cần phải làm gì. Một điểm quan trọng cần lưu ý khi viết script cho Cron là biến môi trường (environment variables) thường bị hạn chế so với khi bạn đăng nhập trực tiếp, do đó bạn cần khai báo rõ ràng các biến hoặc sử dụng đường dẫn tuyệt đối cho các lệnh hệ thống.
Chúng ta sẽ xây dựng một kịch bản cụ thể: Script sẽ kiểm tra tỷ lệ sử dụng CPU, bộ nhớ RAM và dung lượng ổ đĩa. Nếu bất kỳ thông số nào vượt quá ngưỡng an toàn (ví dụ CPU > 80%, RAM > 90%, Disk > 95%), script sẽ tự động thực hiện việc nén và lưu trữ các file log lớn để giải phóng dung lượng, sau đó gửi một báo cáo chi tiết cho quản trị viên. Cách tiếp cận này giúp giảm thiểu thời gian phản ứng (MTTR) và ngăn chặn sự cố tràn đĩa dẫn đến treo hệ thống.
Viết script Bash để thu thập thông tin và cảnh báo
Để bắt đầu, chúng ta tạo một file script có tên là health_check.sh trong thư mục /usr/local/bin/. Nội dung script cần thực hiện tuần tự các bước: thu thập dữ liệu, so sánh với ngưỡng, thực thi hành động xử lý nếu cần và ghi log lại kết quả. Việc sử dụng đường dẫn tuyệt đối cho các lệnh như df, free, top hay date là bắt buộc để script có thể chạy đúng khi được Cron gọi, vì biến PATH của Cron thường rất ngắn và chỉ chứa các thư mục cơ bản như /bin hoặc /usr/bin.
#!/bin/bash
# Khai báo các biến ngưỡng cảnh báo
CPU_THRESHOLD=80
RAM_THRESHOLD=90
DISK_THRESHOLD=95
LOG_FILE="/var/log/health_check.log"
ADMIN_EMAIL="admin@example.com"
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
# Định nghĩa hàm ghi log
log_message() {
local message=$1
local level=$2
echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $message" >> $LOG_FILE
}
# Hàm gửi cảnh báo qua Slack (tùy chọn)
send_slack_alert() {
local title=$1
local message=$2
local json_payload=$(cat < /dev/null 2>&1
}
# Lấy thông tin CPU (sử dụng top -bn1 để lấy thông tin nhanh)
# Lưu ý: top -bn1 | head -1 | awk '{print $8}'
# Tuy nhiên, để chính xác hơn trên các hệ thống mới, chúng ta dùng mpstat hoặc vmstat
# Ở đây dùng top cho đơn giản và phổ biến
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us//g' | sed 's/,$//g')
if [[ -z "$CPU_USAGE" ]]; then
CPU_USAGE=0
fi
# Lấy thông tin RAM
RAM_TOTAL=$(free | grep Mem | awk '{print $2}')
RAM_USED=$(free | grep Mem | awk '{print $3}')
RAM_PERCENTAGE=$((RAM_USED * 100 / RAM_TOTAL))
# Lấy thông tin Disk
DISK_PERCENTAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//g')
# Kiểm tra và so sánh ngưỡng
ALERT_MESSAGE=""
if [ $CPU_USAGE -gt $CPU_THRESHOLD ]; then
ALERT_MESSAGE+="⚠️ CPU Usage is high: ${CPU_USAGE}%\n"
log_message "CRITICAL: CPU Usage ${CPU_USAGE}%" "ERROR"
fi
if [ $RAM_PERCENTAGE -gt $RAM_THRESHOLD ]; then
ALERT_MESSAGE+="⚠️ RAM Usage is high: ${RAM_PERCENTAGE}%\n"
log_message "CRITICAL: RAM Usage ${RAM_PERCENTAGE}%" "ERROR"
fi
if [ $DISK_PERCENTAGE -gt $DISK_THRESHOLD ]; then
ALERT_MESSAGE+="⚠️ Disk Usage is critical: ${DISK_PERCENTAGE}%\n"
log_message "CRITICAL: Disk Usage ${DISK_PERCENTAGE}%" "ERROR"
# Hành động tự động: Nén các file log lớn để giải phóng dung lượng
log_message "Starting automatic cleanup of large log files..." "INFO"
# Tìm các file log lớn hơn 100MB trong /var/log, nén chúng và lưu vào thư mục archive
find /var/log -type f -size +100M -name "*.log" -exec gzip -f {} \; 2>/dev/null
# Xoá file log đã bị nén nếu muốn (hoặc giữ lại để audit)
# find /var/log -type f -name "*.log.gz" -mtime +7 -delete 2>/dev/null
log_message "Cleanup task completed." "INFO"
fi
# Gửi cảnh báo nếu có vấn đề
if [[ -n "$ALERT_MESSAGE" ]]; then
log_message "Sending alert via Slack and Email." "WARN"
send_slack_alert "System Health Alert" "$ALERT_MESSAGE"
# Gửi mail nếu cần (đảm bảo mail utility đã cài đặt)
# echo "$ALERT_MESSAGE" | mail -s "System Alert: $HOSTNAME" $ADMIN_EMAIL
else
log_message "System health is normal." "INFO"
fi
Cấu hình Cron để thực thi định kỳ
Sau khi script đã hoàn thiện và được cấp quyền thực thi, bước tiếp theo là cấu hình lịch trình để script tự động chạy. Bạn có thể sử dụng lệnh crontab -e để chỉnh sửa bảng cron của user root hoặc tạo file cấu hình riêng trong thư mục /etc/cron.d/ để dễ quản lý hơn cho các máy chủ sản xuất. Việc sử dụng /etc/cron.d/ cho phép bạn đặt tên file rõ ràng (ví dụ: health_check.cron) và quản lý nó như một phần của cấu hình hệ thống, dễ dàng hơn khi sử dụng các công cụ deployment như Ansible sau này.
Trong bảng cron, các trường biểu thị thời gian gồm phút, giờ, ngày tháng, tháng và ngày trong tuần. Để chạy script kiểm tra sức khỏe hàng ngày vào lúc 8:00 sáng và 20:00 tối, bạn sẽ định nghĩa dòng lệnh tương ứng. Quan trọng hơn, để đảm bảo script chạy trong môi trường Cron với đầy đủ biến môi trường, bạn nên khai báo biến PATH ngay từ đầu file cron hoặc trong script. Ngoài ra, việc hướng stdout và stderr vào file log hoặc /dev/null là rất cần thiết để tránh việc Cron gửi email rỗng hàng ngày nếu script chạy thành công mà không có cảnh báo.
# Chỉnh sửa file cron trong thư mục /etc/cron.d/
# File: /etc/cron.d/health_check
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Chạy script kiểm tra sức khỏe mỗi ngày lúc 8:00 và 20:00
0 8 * * * root /usr/local/bin/health_check.sh >> /var/log/cron_health.log 2>&1
0 20 * * * root /usr/local/bin/health_check.sh >> /var/log/cron_health.log 2>&1
# Chạy script kiểm tra nhanh (chỉ disk) mỗi 15 phút
*/15 * * * * root /usr/local/bin/health_check.sh --quick >> /var/log/cron_health.log 2>&1
Lưu ý rằng dòng lệnh cuối cùng trong ví dụ trên sử dụng tham số --quick, điều này đòi hỏi bạn phải mở rộng script để xử lý các đối số từ dòng lệnh. Bạn có thể thêm logic trong script để nếu nhận thấy đối số --quick, script sẽ chỉ kiểm tra dung lượng ổ đĩa mà bỏ qua CPU và RAM để giảm tải hệ thống.
Lưu ý quan trọng về bảo mật và tối ưu hóa
Khi triển khai các script tự động hóa, vấn đề bảo mật luôn đi hàng đầu. Script của bạn sẽ chạy với quyền root thông qua Cron, do đó bất kỳ lỗ hổng nào trong logic script đều có thể bị kẻ tấn công lợi dụng. Tuyệt đối không chứa các thông tin nhạy cảm như mật khẩu hay API keys trực tiếp trong file script. Đối với Slack Webhook URL hay các cấu hình khác, bạn nên sử dụng biến môi trường từ file cấu hình riêng biệt, file này được đặt quyền truy cập rất hạn chế (ví dụ: chmod 600). Ngoài ra, hãy luôn ghi log chi tiết mọi hành động mà script thực hiện, bao gồm cả việc xóa file hay chạy lệnh, để dễ dàng truy vết (audit trail) nếu có sự cố xảy ra.
Về mặt tối ưu hóa, tránh chạy các lệnh quá nặng trong script nếu bạn thiết lập lịch chạy quá dày đặc. Ví dụ, lệnh top -bn1 có thể tạo thêm một quá trình mới và chiếm dụng một chút tài nguyên. Nếu bạn chạy script này mỗi phút, việc này có thể gây ra hiệu ứng ngược, làm tăng tải CPU thay vì giám sát nó. Trong trường hợp đó, bạn nên cân nhắc sử dụng các công cụ nhẹ hơn hoặc giảm tần suất chạy. Khi hệ thống đã ổn định, bạn có thể nâng cấp script này lên thành một Playbook Ansible để triển khai đồng loạt trên hàng trăm máy chủ, trong đó Ansible sẽ đóng vai trò phân phối script và cấu hình cron, còn Bash script vẫn đóng vai trò thực thi logic tại chỗ (local execution).
Kết luận
Việc xây dựng một cơ chế tự động hóa kiểm tra sức khỏe và vệ sinh log bằng Bash và Cron là bước đi đầu tiên nhưng vô cùng quan trọng trong hành trình trở thành một Sysadmin chuyên nghiệp. Giải pháp này không chỉ giúp bạn tiết kiệm thời gian kiểm tra thủ công mà còn cung cấp khả năng phản ứng nhanh với các sự cố về tài nguyên, ngăn chặn rủi ro mất dịch vụ. Qua bài viết, bạn đã nắm được cách viết script xử lý logic, cách cấu hình Cron để chạy định kỳ, cũng như những nguyên tắc an toàn cần tuân thủ. Khi đã thành thạo kỹ năng này, bạn hoàn toàn có thể mở rộng ứng dụng sang các tác vụ phức tạp hơn như tự động deploy ứng dụng, quản lý chứng chỉ SSL hay tích hợp với các công cụ monitoring hiện đại như Prometheus hay Zabbix.