Operations

Cấu hình logrotate trên VPS quản lý log hiệu quả

SSH vào VPS đã chạy vài tuần, chạy lệnh ls -lah /var/log/ và thấy file log "ăn" vài GB là chuyện thường. Để mặc, rsyslog hoặc journald sẽ ghi cho tới khi đầy ổ, lúc đó hệ thống bắt đầu báo lỗi. logrotate là công cụ chuẩn POSIX giúp bạn chủ động cắt, nén và dọn log cũ, giữ cho ổ đĩa sạch và dịch vụ không bị ngắt. Bài này sẽ hướng dẫn cấu hình logrotate chi tiết trên Ubuntu 24.04 LTS, Debian 12 và AlmaLinux 9.

Yêu cầu trước khi bắt đầu

  • Một VPS chạy Ubuntu 24.04, Debian 12 hoặc AlmaLinux 9 với quyền root hoặc user có sudo.
  • Hiểu cơ bản về file log và quyền sở hữu file (user:group).
  • Đã cài rsyslog hoặc systemd-journald (mặc định đã có).
  • SSH key đã cấu hình, nên tham khảo bài quản lý user và phân quyền sudo an toàn trên Linux trước nếu cần.

Tại sao không thể bỏ qua logrotate?

Mỗi dịch vụ trên VPS đều ghi log: Nginx ghi thành công và lỗi, MariaDB ghi slow query và error, PHP-FPM ghi lỗi worker. Nếu không có logrotate:

  • Một file log syslog có thể lớn tới 20-30 GB sau vài tháng, đầy ổ /var → VPS tê liệt.
  • Việc xem log với grep hoặc tail sẽ cực kỳ chậm.
  • Không thể giữ lại log cũ để truy vết sự cố vì ổ đĩa không đủ chỗ.

logrotate tự động xoay (rotate) file log theo chu kỳ thời gian (ngày, tuần, tháng) hoặc kích thước file. Nó có thể đổi tên file cũ, nén bằng gzip (hoặc bzip2, xz), gửi tín hiệu SIGHUP/SIGUSR1 cho dịch vụ để ghi log vào file mới, và xoá log quá hạn. Đó là lý do mọi VPS sản xuất đều cần logrotate được cấu hình đúng, dù bạn dùng VPS Linux hay VPS Windows (bên Windows cần công cụ tương tự).

Bước 1 - Kiểm tra trạng thái và xem cấu hình mặc định

logrotate được cài sẵn trên hầu hết distro. Đầu tiên kiểm tra phiên bản:

logrotate --version

Output mẫu:

logrotate 3.21.0

Cấu hình mặc định nằm ở:

  • File chính: /etc/logrotate.conf
  • Thư mục include: /etc/logrotate.d/, mỗi gói phần mềm tự tạo một file cấu hình ở đây khi cài (ví dụ nginx, mariadb, rsyslog, apt).

logrotate được chạy tự động hàng ngày qua cron job mặc định của hệ thống. Kiểm tra job:

ls -l /etc/cron.daily/logrotate
cat /etc/cron.daily/logrotate

Trên Ubuntu/Debian, nội dung sẽ gọi /usr/sbin/logrotate /etc/logrotate.conf. Trên AlmaLinux, cơ chế tương tự qua anacron hoặc systemd timer.

Bước 2 - Cấu trúc cơ bản của file cấu hình logrotate

Một policy logrotate gồm: đường dẫn file log, các chỉ thịscript (tuỳ chọn). Cú pháp ví dụ cơ bản:

/var/log/example/*.log {
    su www-data www-data
    rotate 7
    daily
    compress
    delaycompress
    missingok
    notifempty
    postrotate
        systemctl reload nginx > /dev/null 2>&1 || true
    endscript
}

Giải thích các chỉ thị chính:

Chỉ thịÝ nghĩa
rotate NGiữ lại N bản log cũ nhất, xoá log cũ hơn.
daily, weekly, monthly, yearlyChu kỳ xoay log (theo ngày, tuần, tháng, năm). Có thể dùng size S để xoay theo kích thước (vd size 100M).
compressNén log cũ bằng gzip thành file .gz.
delaycompressTrì hoãn nén 1 chu kỳ: log vừa rotate chưa nén ngay, bản tiếp theo mới nén. Hữu ích nếu dịch vụ chưa kịp ghi xong log cũ.
missingokKhông báo lỗi nếu file log không tồn tại.
notifemptyKhông xoay nếu file log rỗng.
postrotate ... endscriptLệnh chạy sau khi rotate, thường để reload dịch vụ.
su user groupChạy rotate với user/group cụ thể (tránh lỗi quyền trên file log do dịch vụ sở hữu).

Thứ tự xoay: logrotate sẽ thực hiện rotate trên cả group file log, rename loglog.1, log.1log.2, …, gửi script postrotate cho toàn bộ group xong rồi mới chạy dịch vụ reload.

Bước 3 - Cấu hình logrotate cho Nginx (ví dụ thực tế)

Mở file cấu hình riêng:

sudo nano /etc/logrotate.d/nginx

Thêm nội dung sau (nếu chưa có):

/var/log/nginx/*.log {
    su www-data adm
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

Giải thích:

  • su www-data adm: rotate với quyền www-data (sở hữu log), nhóm adm.
  • rotate 14: giữ 14 bản (tương đương 2 tuần nếu daily).
  • create 0640 www-data adm: tạo file log mới với quyền 0640.
  • sharedscripts: chạy postrotate một lần riêng biệt cho nhóm file, thay vì mỗi file một lần (quan trọng cho Nginx).
  • kill -USR1: yêu cầu Nginx mở lại file log mới (không cần restart).

Lưu ý: Trên Ubuntu 24.04, gói Nginx từ apt đã tự tạo file /etc/logrotate.d/nginx. Hãy kiểm tra và điều chỉnh, không ghi đè lung tung. kill -USR1 là cách chuẩn từ tài liệu Nginx, dù bạn dùng systemctl reload nginx cũng được nhưng nặng hơn.

Bước 4 - Test cấu hình trước khi chạy thật

Luôn kiểm tra cú pháp trước khi để tự động:

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

-d (debug): in ra hành động mà logrotate sẽ làm mà không thực hiện thật. Output hiển thị “rotating pattern”, các bước rename file, nén, và script. Không thấy “error” là ổn.

Để chạy thử (force rotate ngay):

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

Kiểm tra kết quả:

ls -la /var/log/nginx/

File log gốc sẽ được rename, có thể đã nén thành .gz. Nếu có lỗi “refused to rotate because parent is set securely”, sửa quyền thư mục /var/log/nginx thành 755 và chủ sở hữu đúng (www-data).

Verify thường xuyên:

sudo logrotate -v /etc/logrotate.conf

-v verbose: in chi tiết mọi policy đang được xử lý. Nếu bạn chạy /etc/cron.daily/logrotate thủ công, output gửi vào syslog, xem bằng grep logrotate /var/log/syslog.

Bước 5 - Cấu hình logrotate trên AlmaLinux 9 (firewalld, httpd)

Trên AlmaLinux, Apache httpd cũng có cấu hình mặc định. Mình thường chỉnh nhẹ để tương thích với firewalld (dùng log riêng) và giữ log lâu hơn. Mở file:

sudo nano /etc/logrotate.d/httpd

Và cập nhật (giữ nguyên đường dẫn log của httpd, ví dụ /var/log/httpd/*log):

/var/log/httpd/*log {
    su apache adm
    weekly
    rotate 8
    compress
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        /sbin/service httpd reload > /dev/null 2>&1 || true
    endscript
}

Kiểm tra tương tự:

sudo logrotate -d /etc/logrotate.d/httpd

Đối với các VPS chạy AlmaLinux mà bạn thuê tại thueVPS, các dịch vụ httpd, mysqld, php-fpm có thể cần cấu hình logrotate riêng. Nhưng nguyên tắc chung là kiểm tra thư mục /etc/logrotate.d/ xem đã có file nào chưa, đừng tạo trùng lặp.

Xử lý lỗi thường gặp với logrotate

Lỗi 1: "error: failed to rename log to log.1: Permission denied"

Nguyên nhân: logrotate hiện tại chạy với quyền root, nhưng file log do dịch vụ sở hữu (vd www-data) và thư mục không cho phép di chuyển/đổi tên.
Khắc phục: Thêm chỉ thị su www-data adm vào policy để rotate với user sở hữu log. Kiểm tra quyền thư mục /var/log: ls -ld /var/log (phải drwxr-xr-x root root). Cấp lại quyền nếu cần: sudo chmod 755 /var/log.

Lỗi 2: "error: skipping because parent is set securely"

Nguyên nhân: Thư mục chứa log có owner không phải root và có setuid/setgbit không phù hợp.
Khắc phục: sudo chown root:root /var/log/nginxsudo chmod 755 /var/log/nginx.

Lỗi 3: Log không xoay dù đã đến ngày

Nguyên nhân: cron job logrotate không chạy, hoặc file log quá nhỏ (notifempty), hoặc state file (/var/lib/logrotate/status) ghi sai.
Khắc phục: Kiểm tra cron job đã chạy chưa: sudo run-parts --test /etc/cron.daily (trên Debian/Ubuntu). Xem state: cat /var/lib/logrotate/status | grep nginx. Có thể force: sudo logrotate -f /etc/logrotate.d/nginx. Nếu vẫn không, thêm dateext vào policy để tên file log có ngày tháng.

Câu hỏi thường gặp

Có cần xoá log cũ thủ công không?

Không nên. logrotate quản lý vòng đời log tự động nếu bạn cấu hình rotate đúng. Xoá thủ công dễ gây conflict với state file hoặc làm mất dấu vết sự cố.

Làm sao để giữ log 1 năm?

Đặt rotate 365 + daily (giữ 365 file). Hãy chắc chắn dung lượng ổ đĩa đáp ứng. Nếu ổ NVMe 40 GB của VPS hẹp, nên nén (compress) và giới hạn rotate dưới 30. Bạn có thể dùng gói VPS NVMe dung lượng lớn nếu cần lưu log dài hạn.

logrotate có nén log cũ không?

Có, với chỉ thị compress. Mặc định dùng gzip, tạo file .gz. Có thể đổi sang delaycompress để nén chậm hơn 1 chu kỳ.

Tôi dùng systemd journal, có cần logrotate không?

journald tự quản lý log nội bộ của nó. Nhưng các dịch vụ như Nginx, Apache, MariaDB thường ghi log riêng ra /var/log/, nên bạn vẫn cần logrotate cho các file đó. journald và logrotate bổ trợ cho nhau.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.