❤️ 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.

linux b11 logs

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ứa access.logerror.log củ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--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: emergalertcriterrwarningnoticeinfodebug. 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ấn n để tìm tiếp, N để tìm ngược)
  • G, nhảy xuống cuối file
  • g, nhảy lên đầu file
  • q, 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ẽ:

  1. Đổi tên file log hiện tại (ví dụ syslogsyslog.1)
  2. Tạo file log mới rỗng
  3. Nén file cũ (thành syslog.2.gz)
  4. 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ùng weekly, monthly)
  • rotate 14, giữ lại 14 file log cũ, xoá file thứ 15 trở đi
  • compress, nén file log cũ bằng gzip
  • delaycompress, 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ại
  • notifempty, không rotate nếu file rỗng
  • postrotate...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ặc sudo 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/log và 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.

Chia sẻ:
Bài viết đã được kiểm duyệt bởi AZDIGI Team

Về tác giả

Trần Thắng

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.

Hơn 10 năm phục vụ 80.000+ khách hàng

Bắt đầu dự án web của bạn với AZDIGI