journalctl: đọc log systemd nhanh và lọc lỗi theo thời gian

Cẩm nang journalctl thực tế: lọc log theo service, boot, thời gian, priority, follow realtime và lập quy trình xử lý systemd failed trên VPS.

NHT
· 8 phút đọc
Journalctl trên Linux với bảng log systemd timeline priority và các điểm lỗi được lọc

Khi một service systemd lỗi, câu hỏi quan trọng không phải chỉ là “nó đang failed hay không” mà là failed vào lúc nào, sau sự kiện nào và lỗi xuất hiện ở process nào. journalctl là công cụ truy vấn system journal, cho phép lọc log theo unit, boot, mốc thời gian, mức độ ưu tiên và theo dõi realtime.

Bài viết này xây dựng một quy trình đọc log thực tế cho VPS Linux: bắt đầu từ status, khoanh vùng service, lọc theo thời gian, đọc lần boot hiện tại, xem lỗi warning/error, theo dõi khi restart và xuất log phục vụ bàn giao. Các ví dụ dùng service tên myapp.service; hãy thay bằng tên unit thật của bạn.

1. journalctl và systemd journal là gì?

systemd-journald thu thập các entry log có cấu trúc từ kernel, service systemd và ứng dụng ghi ra stdout/stderr hoặc dùng API journal. journalctl đọc và lọc các entry đó. Khác với một file text duy nhất, journal có metadata như unit, boot ID, priority, process ID và timestamp, vì vậy có thể truy vấn theo nhiều chiều.

Tài liệu journalctl chính thức mô tả -u, --unit để lọc theo service, --since/--until để lọc thời gian, -b để lọc theo boot và --no-pager để tắt trình phân trang. Đây là các option nền tảng đủ dùng cho phần lớn thao tác troubleshooting hằng ngày.

journalctl in các entry được lưu trong system journal; khi truyền match hoặc option, output sẽ được lọc theo các trường tương ứng và có thể kết hợp nhiều điều kiện.Tóm lược từ tài liệu journalctl của freedesktop.org.

2. Bắt đầu bằng systemctl status

Trước khi đọc hàng nghìn dòng log, hãy xem trạng thái hiện tại của unit. Lệnh status thường cho biết service đang active, failed hay đang restart; process chính; vài dòng log gần nhất; cùng đường dẫn unit file.

sudo systemctl status myapp.service --no-pager -l
sudo systemctl is-active myapp.service
sudo systemctl show myapp.service -p ActiveState -p SubState -p Result -p ExecMainStatus

Nếu status cho thấy code=exited, status=1 hoặc process bị signal, đó là manh mối để chuyển sang journal. Không nên kết luận nguyên nhân chỉ từ màu đỏ của status; cần đọc log ở đúng thời điểm và đối chiếu với lần deploy, thay đổi config hoặc sự kiện reboot.

3. Lọc log theo service với -u

Cú pháp phổ biến nhất là journalctl -u myapp.service. Option này lọc theo trường systemd unit, nên chính xác hơn việc grep một chuỗi tên app trong toàn bộ journal. Bạn có thể truyền nhiều -u để xem nhóm service liên quan.

sudo journalctl -u myapp.service --no-pager
sudo journalctl -u myapp.service -n 100 --no-pager
sudo journalctl -u myapp.service -r --no-pager
sudo journalctl -u myapp.service -o short-iso --no-pager

-n 100 giới hạn số dòng gần nhất; -r hiển thị entry mới trước; -o short-iso giúp timestamp dễ đọc và nhất quán hơn khi gửi log. Nếu tên unit có instance như worker@1.service, hãy dùng đúng tên instance hoặc pattern phù hợp.

4. Lọc theo thời gian với since và until

Lọc theo thời gian giúp tránh nhiễu. Bạn có thể dùng thời điểm đầy đủ, từ khóa như today, yesterday, now hoặc biểu thức tương đối. Khi điều tra một lần deploy, hãy lấy mốc ngay trước deploy đến vài phút sau khi service fail.

sudo journalctl -u myapp.service --since "30 minutes ago" --no-pager
sudo journalctl -u myapp.service --since "2026-08-30 08:30:00" --until "2026-08-30 09:15:00" --no-pager
sudo journalctl -u myapp.service --since today --no-pager

Cần thống nhất timezone khi ghi nhận sự cố. Journal thường hiển thị theo local timezone của máy; trong incident report, hãy ghi rõ timezone hoặc dùng format ISO. Nếu nhiều máy ở timezone khác nhau, hãy chuẩn hóa timestamp trước khi so sánh release, reverse proxy và database log.

5. Xem log theo boot với -b

Khi lỗi xuất hiện sau reboot, lọc theo boot giúp phân biệt log cũ và log của lần khởi động hiện tại. journalctl -b xem boot hiện tại; -b -1 xem boot ngay trước đó; một boot ID cụ thể có thể dùng khi cần so sánh nhiều lần khởi động.

sudo journalctl -b -u myapp.service --no-pager
sudo journalctl -b -1 -u myapp.service --no-pager
sudo journalctl --list-boots --no-pager
sudo journalctl -b -p warning..err --no-pager

Nếu journal không giữ được boot cũ, hãy kiểm tra cấu hình lưu trữ journal và dung lượng đĩa. Đừng tự ý xóa journal để “làm sạch” lỗi trước khi lưu bằng chứng. Việc mất log có thể khiến bạn không thể chứng minh lỗi xảy ra sau thay đổi nào.

6. Lọc warning và error bằng priority

journalctl hỗ trợ lọc theo priority từ emergency đến debug. Trong troubleshooting production, một khoảng thường hữu ích là warning..err, nhưng cần nhớ rằng ứng dụng có thể ghi lỗi quan trọng ở mức info hoặc ghi warning không gây gián đoạn.

sudo journalctl -u myapp.service -p err --since "1 hour ago" --no-pager
sudo journalctl -u myapp.service -p warning..err --since today --no-pager
sudo journalctl -u myapp.service -p 3..4 --no-pager

Priority là bộ lọc hỗ trợ, không phải phán quyết cuối cùng. Hãy đọc một ít context trước và sau dòng lỗi, kiểm tra timestamp, PID và trạng thái service. Một lỗi connection refused có thể là triệu chứng của database restart, không nhất thiết là lỗi trong chính service đang được xem.

7. Theo dõi realtime bằng -f

Khi muốn tái hiện lỗi hoặc quan sát sau restart, dùng -f để follow entry mới. Mở một terminal theo dõi journal và terminal khác chạy lệnh restart hoặc gửi request test. Khi đã thu đủ log, nhấn Ctrl+C thay vì để session follow chạy vô hạn.

sudo journalctl -u myapp.service -f -n 50
sudo systemctl restart myapp.service
curl -fsS http://127.0.0.1:3000/health || true

Với worker, hãy gửi một job test có mã nhận diện riêng để nối log worker với kết quả xử lý. Với web app, ghi request ID ở ứng dụng hoặc reverse proxy nếu có thể. journalctl hiển thị log tốt hơn khi ứng dụng xuất thông tin có cấu trúc thay vì một chuỗi chung chung như “something failed”.

8. Đọc metadata và output phục vụ phân tích

Khi output mặc định chưa đủ, dùng các format khác nhau. -o verbose hiển thị metadata chi tiết; -o json hoặc -o json-pretty phù hợp cho máy xử lý nhưng cần cẩn thận với dữ liệu nhạy cảm khi gửi ra ngoài.

sudo journalctl -u myapp.service -n 20 -o verbose --no-pager
sudo journalctl -u myapp.service -n 20 -o json-pretty --no-pager
sudo journalctl -u myapp.service --since "10 minutes ago" > /tmp/myapp-journal.txt
sed -n '1,160p' /tmp/myapp-journal.txt

File log xuất ra có thể chứa path, username, request data, token hoặc stack trace. Hãy loại bỏ secret trước khi gửi cho nhà cung cấp hoặc đăng lên issue công khai. Nếu cần chia sẻ, ưu tiên trích đoạn có timestamp, unit và lỗi; không gửi toàn bộ journal của máy nếu chưa kiểm tra nội dung.

9. Quyền đọc journal và cách xử lý an toàn

Không phải user nào cũng đọc được system journal. Theo tài liệu chính thức, quyền truy cập phụ thuộc vào user journal, system journal và group được distro cấp như systemd-journal, adm hoặc wheel. Nếu lệnh yêu cầu quyền, hãy dùng sudo theo chính sách quản trị thay vì chmod rộng cho file journal.

id
groups
sudo journalctl -u myapp.service -n 50 --no-pager
stat -c "%A %U:%G %n" /var/log/journal 2>/dev/null || true

Bài quản lý user và sudo trên Linux giải thích cách giữ audit trail và quyền tối thiểu. Trong runbook, ghi rõ ai được đọc log production, ai được restart service và log nào có thể chứa dữ liệu cá nhân.

10. Quy trình xử lý service failed trong 10 phút

  1. Ghi thời điểm phát hiện, tên máy, tên unit và timezone trước khi chạy lệnh thay đổi.
  2. Chạy systemctl status với --no-pager -l để lấy trạng thái và vài dòng log gần nhất.
  3. Lọc journal theo unit trong khoảng 15–30 phút quanh sự kiện bằng --since và --until.
  4. Nếu máy vừa reboot, đối chiếu journalctl -b và boot trước bằng --list-boots.
  5. Lọc warning/error nhưng vẫn đọc context; kiểm tra exit code, PID, port và dependency.
  6. Tái hiện có kiểm soát bằng restart hoặc request health check, đồng thời theo dõi journalctl -f.
  7. Lưu trích đoạn đã che secret, ghi nguyên nhân, hành động khắc phục và bước phòng ngừa.

11. Các lỗi đọc journal thường gặp

Chỉ grep toàn bộ journal

Grep có thể bỏ sót metadata hoặc bắt nhầm service khác. Hãy lọc bằng -u trước rồi mới dùng grep cho một mã lỗi hoặc request ID cụ thể.

Chỉ xem dòng mới nhất

Một dòng “connection refused” không cho biết database đã restart hay app đọc nhầm port. Hãy lấy context theo khoảng thời gian và xem các unit liên quan.

Xóa log trước khi lưu bằng chứng

Xóa journal không làm nguyên nhân biến mất nhưng làm mất khả năng điều tra. Hãy kiểm tra dung lượng, retention và rotate theo kế hoạch thay vì xóa vội trong incident.

12. Kết luận

journalctl trở nên hữu ích nhất khi được dùng như một truy vấn có mục tiêu: unit nào, boot nào, khoảng thời gian nào, priority nào và cần output ở định dạng nào. Kết hợp status với journal, port check và thay đổi gần nhất giúp bạn phân biệt lỗi khởi động, lỗi permission, lỗi dependency và lỗi ứng dụng.

Hãy chuẩn hóa vài lệnh nền vào runbook của VPS, thêm timezone và nguyên tắc che secret khi chia sẻ log. Khi systemd service đã được tạo đúng cấu trúc, journalctl sẽ cung cấp bằng chứng đủ rõ để xử lý sự cố mà không cần đoán mò hoặc restart liên tục.