❤️ AZDIGI chính thức cập nhật hệ thống blog mới hoàn chỉnh. Tuy nhiên có thể một số bài viết bị sai lệch hình ảnh, hãy ấn nút Báo cáo bài viết ở cuối bài để AZDIGI cập nhật trong thời gian nhanh nhất. Chân thành cám ơn.
Khi VPS gặp sự cố, câu hỏi đầu tiên luôn là “chuyện gì vừa xảy ra?”. Website trả về lỗi 502, SSH bị từ chối, service tự dưng chết, tất cả đều để lại dấu vết trong log hệ thống. Biết cách đọc log là kỹ năng quan trọng nhất để bạn tự xử lý sự cố thay vì phải chờ support.

Trong bài này, mình sẽ hướng dẫn bạn cách đọc log trên Linux VPS bằng hai công cụ chính: thư mục /var/log chứa các file log truyền thống, và journalctl để truy vấn log từ systemd journal.
Tại sao cần đọc log?
Log ghi lại mọi thứ đang diễn ra trên hệ thống. Bạn sẽ cần đọc log trong ba tình huống chính:
Debug lỗi: Khi một service không chạy, log cho bạn biết chính xác nó fail ở đâu. Thay vì đoán mò, bạn đọc log và biết ngay nguyên nhân, thiếu config, port bị chiếm, file permission sai.
Giám sát bảo mật: Ai đang cố SSH vào server? Có request bất thường nào tới web server không? Log ghi lại tất cả các lần đăng nhập thành công lẫn thất bại, giúp bạn phát hiện tấn công sớm.
Audit và theo dõi: Khi bạn cần biết ai đã làm gì trên server, hoặc xem lại lịch sử hoạt động của một service trong tuần qua, log là nguồn thông tin duy nhất đáng tin cậy.
Cấu trúc thư mục /var/log
Thư mục /var/log là nơi tập trung hầu hết các file log trên Linux. Tuỳ distro mà tên file sẽ khác nhau một chút.
Liệt kê nội dung thư mục /var/log:
ls -la /var/log/
Dưới đây là các file log quan trọng nhất mà bạn sẽ thường xuyên làm việc:
Log hệ thống chung
Trên Ubuntu/Debian, log hệ thống chung nằm ở /var/log/syslog. Trên AlmaLinux/CentOS, file tương đương là /var/log/messages. Cả hai đều ghi lại các sự kiện chung của hệ thống: service khởi động, lỗi phần cứng, thông báo từ kernel.
# Ubuntu/Debian
tail -20 /var/log/syslog
# AlmaLinux/CentOS
tail -20 /var/log/messages
Log xác thực (authentication)
Trên Ubuntu/Debian: /var/log/auth.log. Trên AlmaLinux/CentOS: /var/log/secure. File này ghi lại mọi lần đăng nhập SSH, sudo, và các hoạt động xác thực khác. Đây là nơi đầu tiên bạn kiểm tra khi nghi ngờ có ai đó đang cố truy cập trái phép.
# Ubuntu/Debian
tail -20 /var/log/auth.log
# AlmaLinux/CentOS
tail -20 /var/log/secure
Log kernel và phần cứng
/var/log/kern.log (Ubuntu) chứa log từ kernel Linux, bao gồm thông tin về driver, lỗi phần cứng, và các vấn đề ở tầng thấp. Trên AlmaLinux, thông tin kernel thường nằm chung trong /var/log/messages.
Lệnh dmesg cũng cho phép xem kernel log trực tiếp từ ring buffer, hữu ích để kiểm tra các sự kiện gần nhất:
# Xem kernel log gần nhất
dmesg | tail -30
# Chỉ xem lỗi và cảnh báo
dmesg --level=err,warn
Log ứng dụng
Các ứng dụng lớn thường tạo thư mục log riêng trong /var/log:
/var/log/nginx/, chứaaccess.logvàerror.logcủa Nginx/var/log/apache2/(Ubuntu) hoặc/var/log/httpd/(AlmaLinux), log của Apache/var/log/mysql/hoặc/var/log/mariadb/, log database/var/log/php-fpm/, log PHP-FPM (AlmaLinux), trên Ubuntu thường nằm trong syslog
Đọc log bằng journalctl
journalctl là công cụ đọc log của systemd, có trên hầu hết các distro Linux hiện đại. So với việc đọc file text trong /var/log, journalctl có lợi thế là cho phép lọc log theo nhiều tiêu chí khác nhau mà không cần nhớ tên file.
Xem toàn bộ log
# Xem tất cả log (cuộn từ đầu)
journalctl
# Xem log và nhảy thẳng xuống cuối (log mới nhất)
journalctl -e
Mặc định journalctl mở log trong pager (giống less), bạn dùng phím mũi tên để cuộn, nhấn q để thoát.
Lọc theo service (unit)
Đây là cách dùng phổ biến nhất. Khi một service gặp lỗi, bạn xem log riêng của nó bằng flag -u:
# Log của Nginx
journalctl -u nginx
# Log của SSH
journalctl -u sshd
# Log của MySQL/MariaDB
journalctl -u mysqld # AlmaLinux
journalctl -u mysql # Ubuntu
# Log của PHP-FPM
journalctl -u php-fpm # AlmaLinux
journalctl -u php8.3-fpm # Ubuntu (thay 8.3 bằng version bạn dùng)
Lọc theo thời gian
Khi bạn biết sự cố xảy ra vào khoảng thời gian nào, dùng --since và --until để thu hẹp phạm vi:
# Log từ 1 giờ trước đến giờ
journalctl --since "1 hour ago"
# Log trong khoảng thời gian cụ thể
journalctl --since "2025-03-15 08:00" --until "2025-03-15 12:00"
# Log từ hôm nay
journalctl --since today
# Log từ hôm qua
journalctl --since yesterday --until today
Kết hợp lọc thời gian với lọc unit để xem chính xác log của một service trong khoảng thời gian nhất định:
# Log Nginx trong 30 phút qua
journalctl -u nginx --since "30 min ago"
Theo dõi log realtime
Flag -f (follow) cho phép bạn xem log realtime, giống tail -f. Rất hữu ích khi bạn đang debug và cần thấy log xuất hiện ngay khi sự kiện xảy ra:
# Follow tất cả log hệ thống
journalctl -f
# Follow log của một service cụ thể
journalctl -u nginx -f
Nhấn Ctrl+C để dừng theo dõi.
Lọc theo lần boot
Nếu server vừa bị restart và bạn muốn xem chuyện gì xảy ra trước khi reboot:
# Log của lần boot hiện tại
journalctl -b
# Log của lần boot trước đó
journalctl -b -1
# Liệt kê tất cả các lần boot đã ghi log
journalctl --list-boots
Lọc theo mức độ nghiêm trọng (priority)
Khi log quá nhiều và bạn chỉ muốn xem lỗi, dùng -p để lọc theo priority level:
# Chỉ xem lỗi (error) trở lên
journalctl -p err
# Chỉ xem cảnh báo (warning) trở lên
journalctl -p warning
# Xem critical và emergency
journalctl -p crit
Các mức priority từ cao đến thấp: emerg → alert → crit → err → warning → notice → info → debug. Khi bạn chọn một mức, journalctl sẽ hiển thị mức đó và tất cả các mức nghiêm trọng hơn.
Giới hạn số dòng và xuất ra file
# Chỉ xem 50 dòng cuối
journalctl -n 50
# Xuất log ra file text (không dùng pager)
journalctl -u nginx --since today --no-pager > /tmp/nginx-log.txt
Đọc log bằng các lệnh Linux cơ bản
Không phải lúc nào bạn cũng cần journalctl. Nhiều ứng dụng ghi log trực tiếp vào file text trong /var/log, và bạn có thể đọc chúng bằng các lệnh Linux cơ bản.
tail, Xem dòng cuối và theo dõi realtime
# Xem 20 dòng cuối của file log
tail -20 /var/log/nginx/error.log
# Theo dõi log realtime (dừng bằng Ctrl+C)
tail -f /var/log/nginx/error.log
# Theo dõi nhiều file cùng lúc
tail -f /var/log/nginx/error.log /var/log/nginx/access.log
tail -f là lệnh mình dùng nhiều nhất khi debug. Mở một terminal chạy tail -f, terminal khác thực hiện thao tác gây lỗi, rồi quay lại xem log xuất hiện.
grep, Tìm kiếm trong log
grep giúp bạn lọc ra những dòng chứa từ khoá cụ thể trong file log:
# Tìm dòng chứa "error" (không phân biệt hoa/thường)
grep -i error /var/log/syslog
# Tìm lỗi 502 trong access log của Nginx
grep "502" /var/log/nginx/access.log
# Tìm các lần đăng nhập SSH thất bại
grep "Failed password" /var/log/auth.log # Ubuntu
grep "Failed password" /var/log/secure # AlmaLinux
# Đếm số lần xuất hiện
grep -c "Failed password" /var/log/auth.log
Kết hợp pipe để lọc mạnh hơn
Sức mạnh thực sự nằm ở việc kết hợp nhiều lệnh bằng pipe (|):
# Tìm lỗi trong syslog, chỉ lấy 10 dòng cuối
grep -i error /var/log/syslog | tail -10
# Liệt kê IP nào login SSH thất bại nhiều nhất
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# Xem access log Nginx, chỉ lấy request trả về status 500
awk '$9 == 500' /var/log/nginx/access.log
# Xem log trong khoảng thời gian cụ thể (ví dụ ngày 15/03)
grep "Mar 15" /var/log/syslog | grep -i error
less, Đọc file log lớn
Với file log lớn hàng trăm MB, dùng cat sẽ đổ hết ra terminal rất khó đọc. Dùng less để cuộn và tìm kiếm:
# Mở file log bằng less
less /var/log/syslog
Các phím tắt hữu ích trong less:
/từ_khoá, tìm kiếm (nhấnnđể tìm tiếp,Nđể tìm ngược)G, nhảy xuống cuối fileg, nhảy lên đầu fileq, thoát
Log rotation với logrotate
File log sẽ lớn dần theo thời gian. Nếu không xử lý, chúng có thể ngốn hết dung lượng ổ đĩa. logrotate là công cụ tự động xoay vòng (rotate), nén, và xoá log cũ.
Cách logrotate hoạt động
logrotate chạy hàng ngày qua cron/systemd timer. Khi file log đạt điều kiện (theo thời gian hoặc dung lượng), nó sẽ:
- Đổi tên file log hiện tại (ví dụ
syslog→syslog.1) - Tạo file log mới rỗng
- Nén file cũ (thành
syslog.2.gz) - Xoá file quá cũ theo số lượng giữ lại
File cấu hình chính nằm tại /etc/logrotate.conf, và các config riêng cho từng ứng dụng nằm trong /etc/logrotate.d/:
# Xem config logrotate chính
cat /etc/logrotate.conf
# Liệt kê config của các ứng dụng
ls /etc/logrotate.d/
Đọc hiểu config logrotate
Xem config của Nginx làm ví dụ:
cat /etc/logrotate.d/nginx
Nội dung thường trông như thế này:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
Giải thích các directive:
daily, rotate mỗi ngày (có thể dùngweekly,monthly)rotate 14, giữ lại 14 file log cũ, xoá file thứ 15 trở đicompress, nén file log cũ bằng gzipdelaycompress, chưa nén file log vừa rotate lần gần nhất (tiện cho debug)missingok, không báo lỗi nếu file log không tồn tạinotifempty, không rotate nếu file rỗngpostrotate...endscript, lệnh chạy sau khi rotate (thường để reload service)
Tạo config logrotate cho ứng dụng riêng
Nếu bạn chạy một ứng dụng tự ghi log vào file riêng (ví dụ một app Node.js ghi log vào /var/log/myapp/), bạn nên tạo config logrotate cho nó:
sudo nano /etc/logrotate.d/myapp
Nội dung:
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
}
Lưu ý directive copytruncate: thay vì rename file log (khiến app mất handle), logrotate sẽ copy nội dung ra file mới rồi truncate file gốc. Cách này an toàn hơn cho các app không hỗ trợ tín hiệu reload.
Test config mới mà không thực sự rotate:
# Chạy thử (dry run)
sudo logrotate -d /etc/logrotate.d/myapp
# Chạy thật (force rotate ngay)
sudo logrotate -f /etc/logrotate.d/myapp
Rsyslog cơ bản
rsyslog là daemon chịu trách nhiệm thu thập và ghi log từ các nguồn khác nhau vào file trong /var/log. Nó là “người trung gian” nhận log từ kernel, các service, và ứng dụng, rồi phân phối vào đúng file.
File cấu hình chính:
# Xem config rsyslog
cat /etc/rsyslog.conf
# Các config bổ sung
ls /etc/rsyslog.d/
Trong file config, bạn sẽ thấy các rule dạng:
# facility.priority đích đến
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none /var/log/syslog
kern.* /var/log/kern.log
Cách đọc rule: auth,authpriv.* nghĩa là “mọi log từ facility auth và authpriv, ở mọi mức priority, ghi vào /var/log/auth.log“. Còn *.*;auth,authpriv.none nghĩa là “tất cả log trừ auth, ghi vào syslog”.
Trên thực tế, bạn hiếm khi cần sửa rsyslog config. Nhưng hiểu cách nó hoạt động giúp bạn biết tại sao log nằm ở file nào, và có thể tuỳ chỉnh khi cần (ví dụ tách log của một ứng dụng ra file riêng).
Kiểm tra trạng thái rsyslog:
systemctl status rsyslog
Ví dụ troubleshoot thực tế
Nắm lý thuyết rồi, giờ mình đi vào hai tình huống thực tế mà bạn sẽ gặp thường xuyên khi quản trị VPS.
Tình huống 1: Website trả về lỗi 502 Bad Gateway
Lỗi 502 nghĩa là Nginx nhận request nhưng không kết nối được tới backend (thường là PHP-FPM). Quy trình debug:
Bước 1: Xem error log của Nginx để biết Nginx báo lỗi gì:
tail -20 /var/log/nginx/error.log
Nếu thấy dòng kiểu connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory), nghĩa là PHP-FPM không chạy hoặc socket path sai.
Bước 2: Kiểm tra PHP-FPM có đang chạy không:
# Kiểm tra status
systemctl status php8.3-fpm # Ubuntu
systemctl status php-fpm # AlmaLinux
# Xem log PHP-FPM
journalctl -u php8.3-fpm -n 30 # Ubuntu
journalctl -u php-fpm -n 30 # AlmaLinux
Bước 3: Nếu PHP-FPM chạy rồi mà vẫn lỗi, có thể do PHP-FPM bị quá tải. Kiểm tra log xem có thông báo pool đầy không:
# Tìm log cảnh báo max_children
grep -i "max_children" /var/log/php*fpm*.log 2>/dev/null
journalctl -u php-fpm --since "1 hour ago" | grep -i "max_children"
Nếu thấy server reached pm.max_children, bạn cần tăng giá trị pm.max_children trong config pool của PHP-FPM.
Tình huống 2: Phát hiện SSH brute force
Bạn để ý server chậm bất thường, hoặc muốn kiểm tra xem có ai đang cố đoán mật khẩu SSH. Cách kiểm tra:
# Tìm các lần login thất bại
grep "Failed password" /var/log/auth.log # Ubuntu
grep "Failed password" /var/log/secure # AlmaLinux
# Đếm số lần thất bại theo IP
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
Kết quả sẽ trông như thế này:
847 203.0.113.45
523 198.51.100.12
291 192.0.2.78
Nếu thấy hàng trăm lần thử từ cùng một IP, đó là brute force. Bạn có thể:
- Chặn IP bằng firewall:
sudo ufw deny from 203.0.113.45(Ubuntu) hoặcsudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.45" drop'(AlmaLinux) - Cài fail2ban để tự động chặn (sẽ nói ở bài khác)
- Đổi port SSH và tắt password authentication, chỉ dùng SSH key
Cũng dùng journalctl để xem nhanh:
# Xem log SSH thất bại qua journalctl
journalctl -u sshd --since "24 hours ago" | grep "Failed password" | tail -20
Checkpoint
Sau bài này, bạn nên nắm được:
- Biết các file log quan trọng trong
/var/logvà sự khác biệt giữa Ubuntu và AlmaLinux - Dùng
journalctlđể lọc log theo service, thời gian, mức priority - Dùng
tail -f,grep,lessđể đọc và tìm kiếm trong file log - Hiểu cách logrotate quản lý log và tự tạo config cho ứng dụng riêng
- Biết quy trình troubleshoot dựa trên log: xác định vấn đề → tìm file log phù hợp → đọc và phân tích
Mẹo: Tạo alias cho các lệnh log bạn dùng thường xuyên. Ví dụ thêm vào ~/.bashrc:alias syslog='tail -f /var/log/syslog'alias authlog='tail -f /var/log/auth.log'alias nginxerr='tail -f /var/log/nginx/error.log'
Sau đó chạy source ~/.bashrc để áp dụng. Lần sau chỉ cần gõ nginxerr là xem được log Nginx ngay.
Ở bài tiếp theo, mình sẽ hướng dẫn bạn cách quản lý firewall trên VPS với UFW và firewalld để bảo vệ server khỏi các truy cập không mong muốn.
Có thể bạn cần xem thêm
- Systemd và quản lý service trên Linux VPS
- Troubleshooting VPS Linux - Cách xủ lý sự cố VPS phổ biến
- Cấu trúc thư mục Linux - Mọi thứ nằm ở đâu trên VPS
- Grep, Pipe và Redirect trên Linux - Xử lý text như pro
- Docker Logging – Quản lý log hiệu quả
- User và Permission nâng cao trên Linux VPS - Least Privilege
Về tác giả
Trần Thắng
Chuyên gia tại AZDIGI với nhiều năm kinh nghiệm trong lĩnh vực web hosting và quản trị hệ thống.