Log Rotation trên Linux với Logrotate: Giải Cứu Ổ Đĩa Lúc Nửa Đêm

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Bối cảnh & Tại sao cần: Khi log làm sập server lúc 2 giờ sáng

Bạn có bao giờ nhận cuộc gọi lúc 2 giờ sáng báo hệ thống lỗi, không ghi được dữ liệu vì ổ cứng đầy chưa? Tôi đã từng trải qua cảm giác đó. Trên các server production, nhất là những VPS tôi quản lý suốt 3 năm qua, các file log có thể phình to rất nhanh. Đây là những ghi chép quý giá của hệ thống và ứng dụng, giúp tôi theo dõi hoạt động, tìm lỗi và hiểu rõ các sự kiện.

Thế nhưng, nếu không quản lý cẩn thận, những file log này sẽ nhanh chóng chiếm hết dung lượng ổ đĩa. Tôi còn nhớ, một server chạy WordPress và Nginx từng báo lỗi 502 liên tục. Khi kiểm tra, file log của Nginx đã lên tới vài chục GB, và syslog cũng tương tự.

Hậu quả là ổ đĩa đầy, hệ thống không thể ghi thêm dữ liệu nào, kể cả session hay cache, dẫn đến downtime kéo dài. Với hơn 10 VPS Linux đã quản lý trong 3 năm, tôi đúc kết rằng cần kiểm tra kỹ mọi thay đổi trước khi áp dụng vào môi trường production – đặc biệt với những chi tiết nhỏ như log. **Logrotate** chính là giải pháp cho vấn đề này.

Logrotate là một tiện ích được thiết kế để tự động xoay vòng (rotate), nén (compress), xóa (remove) và gửi (mail) các file log. Nó giúp hệ thống không bị quá tải do các file log cũ và quá lớn, đồng thời vẫn giữ được lịch sử log cần thiết cho việc kiểm tra. Nếu thiếu Logrotate, bạn có thể sẽ lại thức trắng đêm vì những sự cố tương tự.

Cài đặt Logrotate trên Linux

Thông thường, hầu hết các bản phân phối Linux phổ biến đều đã cài đặt logrotate sẵn. Nếu server của bạn chưa có, việc cài đặt rất đơn giản:

Trên Debian/Ubuntu:


sudo apt update
sudo apt install logrotate

Trên CentOS/RHEL/Fedora:


sudo yum install logrotate
# Hoặc với các phiên bản mới hơn
sudo dnf install logrotate

Sau khi cài đặt, logrotate thường sẽ được kích hoạt tự động qua cronjob hoặc systemd timer. Bạn có thể kiểm tra hoạt động định kỳ của nó bằng cách xem các file cấu hình trong /etc/cron.daily/ hoặc /etc/systemd/system/timers.target.wants/ (đối với systemd).

Cấu hình chi tiết Logrotate

Logrotate sử dụng hai loại tệp cấu hình chính:

  • /etc/logrotate.conf: Tệp cấu hình tổng thể, chứa các thiết lập mặc định và tham chiếu đến các tệp cấu hình riêng lẻ khác.
  • /etc/logrotate.d/: Thư mục chứa các tệp cấu hình riêng cho từng ứng dụng hoặc dịch vụ. Đây là nơi lý tưởng để tạo các file cấu hình tùy chỉnh, ví dụ cho Nginx, Apache, MySQL hay các ứng dụng Python.

Tệp cấu hình tổng thể: /etc/logrotate.conf

Khi mở file này, bạn sẽ thấy các dòng cấu hình mặc định:


sudo cat /etc/logrotate.conf

# Logrotate.conf là file cấu hình mặc định cho toàn hệ thống.
# Tham khảo man logrotate để biết thêm chi tiết.

monthly             # Xoay log hàng tháng
rotate 4            # Giữ lại 4 bản xoay cũ
create              # Tạo file log mới sau khi xoay
include /etc/logrotate.d  # Bao gồm các tệp cấu hình trong thư mục này

/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

# Khác...

Dưới đây là giải thích một số directive quan trọng:

  • daily, weekly, monthly, yearly: Định nghĩa tần suất xoay log. Chọn tùy chọn phù hợp với nhu cầu.
  • rotate N: Chỉ định số lượng bản log đã xoay sẽ được giữ lại. Ví dụ, rotate 4 sẽ giữ 4 bản cũ nhất.
  • create [mode owner group]: Tạo file log trống mới với quyền (mode), chủ sở hữu (owner) và nhóm (group) sau khi file cũ được xoay. Nếu không chỉ định, quyền của file gốc sẽ được giữ lại.
  • include /path/to/directory: Chỉ thị cho logrotate đọc thêm các file cấu hình từ thư mục được chỉ định.

Cấu hình riêng cho ứng dụng: /etc/logrotate.d/

Đây là nơi bạn tùy chỉnh logrotate cho từng ứng dụng cụ thể. Mỗi file trong thư mục này định nghĩa cách xoay log cho một hoặc nhiều file. Ví dụ, ta sẽ tạo một file cấu hình cho Nginx:


sudo nano /etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily             # Xoay log hàng ngày
    missingok         # Không báo lỗi nếu file log không tồn tại
    rotate 7          # Giữ lại 7 bản log cũ (tương đương 1 tuần)
    compress          # Nén các file log cũ để tiết kiệm dung lượng
    delaycompress     # Hoãn nén bản log mới nhất đến chu kỳ tiếp theo
    notifempty        # Không xoay log nếu file trống
    create 0640 www-data adm # Tạo file log mới với quyền 0640, owner www-data, group adm
    sharedscripts     # Chỉ chạy script postrotate/prerotate một lần cho toàn bộ file được cấu hình
    postrotate        # Bắt đầu script chạy sau khi xoay log
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript         # Kết thúc script postrotate
}

Giải thích thêm về các directive quan trọng:

  • /var/log/nginx/*.log: Đường dẫn đến các file log cần xoay. Có thể sử dụng ký tự đại diện (wildcard) *.
  • missingok: Nếu file log không tồn tại, logrotate sẽ bỏ qua mà không báo lỗi. Điều này hữu ích cho các ứng dụng không phải lúc nào cũng tạo log.
  • compress: Nén các file log đã xoay bằng gzip (mặc định), giúp tiết kiệm đáng kể dung lượng. Ví dụ: access.log.1 sẽ trở thành access.log.1.gz.
  • delaycompress: Khi sử dụng compress, file log mới nhất (kết thúc bằng .1) sẽ không nén ngay mà chờ đến chu kỳ xoay tiếp theo. Điều này có lợi nếu một ứng dụng vẫn đang đọc file .1 sau khi xoay.
  • notifempty: Ngăn logrotate xoay các file log trống.
  • postrotate / endscript: Các lệnh trong khối này sẽ thực thi sau khi logrotate hoàn tất việc xoay file. Với Nginx, cần gửi tín hiệu USR1 để Nginx mở lại các file log mới sau khi chúng đã được xoay. Nếu không, Nginx sẽ tiếp tục ghi vào file log cũ đã được đổi tên.
  • prerotate / endscript: Tương tự postrotate, nhưng các lệnh này sẽ chạy trước khi xoay log.
  • dateext: Thêm ngày vào tên file log đã xoay, ví dụ: access.log-20240310.gz. Tính năng này giúp dễ dàng xác định ngày của file log.
  • mail [email protected]: Gửi file log đã xoay đến địa chỉ email được chỉ định.
  • olddir /path/to/archive: Di chuyển các file log đã xoay vào một thư mục lưu trữ khác, thay vì giữ chúng trong cùng thư mục với file gốc.

Cần đặc biệt lưu ý đến các script prerotatepostrotate. Với các ứng dụng yêu cầu reload hoặc restart để nhận diện file log mới (ví dụ: Nginx, Apache, PHP-FPM…), việc gửi tín hiệu hoặc chạy lệnh restart là cực kỳ quan trọng. Nếu bỏ qua, log có thể tiếp tục ghi vào file cũ đã đổi tên, hoặc tệ hơn là dừng ghi log hoàn toàn!

Kiểm tra & Monitoring Logrotate

Chạy thử (Dry Run)

Đây là bước không thể bỏ qua trước khi triển khai bất kỳ cấu hình mới nào lên production. Luôn chạy thử để đảm bảo mọi thứ hoạt động như mong muốn mà không ảnh hưởng đến hệ thống:


sudo logrotate -d /etc/logrotate.conf

Lệnh này sẽ mô phỏng hoạt động của logrotate mà không thực sự thay đổi bất kỳ file nào. Bạn sẽ thấy chi tiết từng bước kiểm tra, quyết định xoay log và các lệnh sẽ được thực thi.

Để kiểm tra một file cấu hình riêng biệt, ví dụ cho Nginx:


sudo logrotate -d /etc/logrotate.d/nginx

Chạy ép buộc (Force Run)

Trong trường hợp cần kiểm tra ngay lập tức hoặc giải phóng dung lượng khẩn cấp:


sudo logrotate -f /etc/logrotate.conf

Lệnh này buộc logrotate chạy và thực hiện xoay log theo cấu hình, bất kể điều kiện tần suất (daily, weekly) đã đáp ứng hay chưa. Hãy thận trọng khi sử dụng -f trên môi trường production, đặc biệt nếu hệ thống có nhiều log đang hoạt động. Luôn kiểm tra kỹ các script postrotate để tránh gián đoạn dịch vụ.

Kiểm tra trạng thái và lịch trình

Logrotate thường chạy định kỳ thông qua cron hoặc systemd timer. Bạn có thể kiểm tra lịch sử hoạt động của nó tại:

  • /var/lib/logrotate/status: File này lưu trữ thông tin về lần cuối cùng mỗi file log được xoay.

sudo cat /var/lib/logrotate/status

Bạn cũng có thể xem log của hệ thống để biết logrotate đã chạy và kết thúc ra sao:


journalctl -u logrotate.timer
journalctl -u logrotate.service

Đối với các hệ thống cũ hoặc cronjob truyền thống:


sudo grep logrotate /var/log/syslog

Hoặc kiểm tra file /var/log/cron trên CentOS/RHEL.

Theo dõi và khắc phục sự cố

Nếu logrotate không hoạt động như mong đợi, hãy thực hiện các bước sau:

  1. Kiểm tra file status: Xem /var/lib/logrotate/status để biết lần cuối log được xoay.
  2. Kiểm tra quyền hạn: Đảm bảo logrotate có quyền đọc/ghi vào thư mục chứa log và thực thi các script postrotate/prerotate.
  3. Xem log của logrotate: Sử dụng journalctl hoặc grep trên log hệ thống để tìm lỗi.
  4. Chạy dry run: Đây luôn là cách hiệu quả nhất để mô phỏng và phát hiện vấn đề trước khi chúng ảnh hưởng đến hệ thống thực.

Quản lý log là một phần thiết yếu trong vận hành hệ thống. Bằng cách hiểu và cấu hình logrotate đúng cách, bạn không chỉ duy trì sự ổn định cho server mà còn tránh được những đêm thức trắng khắc phục sự cố do ổ đĩa đầy gây ra.

Share: