Đừng Grep văn bản tĩnh nữa: Phân tích Log Linux hiện đại với Journalctl

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

Sự chuyển dịch từ tệp văn bản sang luồng nhị phân

Nếu bạn từng dành 20 phút nheo mắt nhìn vào một bức tường chữ trắng xóa trong /var/log/syslog, bạn sẽ hiểu sự ức chế của cách ghi log truyền thống. Trong nhiều năm, việc khắc phục sự cố Linux đồng nghĩa với việc vật lộn với grep, awk và sed để tìm ra một sự kiện lỗi duy nhất. Mặc dù quy trình đó là một trải nghiệm nhập môn tất yếu, nhưng nó không hiệu quả. Khi systemd trở thành hệ thống init tiêu chuẩn, nó đã giới thiệu systemd-journald để hiện đại hóa cách chúng ta xử lý dữ liệu đo lường hệ thống (telemetry).

Systemd-journald không chỉ ghi văn bản thuần túy vào một tệp. Nó ghi lại log dưới định dạng nhị phân có cấu trúc và được lập chỉ mục (indexed). Cách tiếp cận giàu siêu dữ liệu (metadata) này cho phép bạn truy vấn log theo các trường cụ thể như Process ID (PID), User ID (UID) hoặc tên unit của systemd mà không cần viết các biểu thức chính quy (regular expressions) phức tạp. Nếu bạn vẫn chỉ dựa vào tail -f, bạn đang bỏ qua một công cụ có thể cắt giảm một nửa thời gian debug của mình.

So sánh các mô hình: Syslog và Journalctl

Để sử dụng các công cụ này hiệu quả, bạn cần hiểu sự khác biệt của chúng. Syslog truyền thống dựa vào một daemon như rsyslog để phân loại tin nhắn vào các tệp khác nhau dựa trên nguồn của chúng. Ngược lại, Journalctl cung cấp một giao diện truy vấn thống nhất cho toàn bộ hệ thống.

Ghi Log dựa trên văn bản truyền thống

  • Định dạng: Các tệp văn bản ASCII thuần túy.
  • Phương pháp tìm kiếm: Tìm kiếm chuỗi thủ công bằng các tiện ích dòng lệnh bên ngoài.
  • Metadata: Thường giới hạn ở dấu thời gian (timestamp), tên máy chủ (hostname) và nội dung tin nhắn.
  • Lưu trữ: Mặc định là vĩnh viễn, nhưng yêu cầu logrotate để tránh làm đầy đĩa cứng.

Journalctl (Tiêu chuẩn hiện đại)

  • Định dạng: Định dạng nhị phân được tối ưu hóa và lập chỉ mục để truy xuất tốc độ cao.
  • Phương pháp tìm kiếm: Công cụ lọc tích hợp sẵn cho các trường cụ thể và khoảng thời gian.
  • Metadata: Ngữ cảnh phong phú bao gồm tên Unit, trình tự Kernel và ngữ cảnh SELinux.
  • Lưu trữ: Có thể cấu hình để lưu trữ tạm thời trên RAM hoặc lưu trữ vĩnh viễn trên đĩa.

Những đánh đổi trong thực tế

Chuyển sang hệ thống log ưu tiên nhị phân mang lại hiệu năng cực lớn, nhưng không phải là không có những điểm đặc thù. Tôi đã từng quản lý các cụm máy chủ nơi journal là cứu cánh, và những cụm khác nơi nó đòi hỏi sự chăm sóc kỹ lưỡng hơn một chút.

Ưu điểm

  • Tốc độ: Tìm kiếm lỗi của một dịch vụ cụ thể trong 5GB log mất chưa đầy hai giây vì dữ liệu đã được lập chỉ mục.
  • Tính nhất quán: Mọi dịch vụ được quản lý bởi systemd đều tự động chuyển đầu ra của nó tới journal. Bạn không còn phải đi săn lùng các đường dẫn log tùy chỉnh nữa.
  • Khả năng hiển thị sớm: Nó ghi lại các thông báo từ đĩa RAM khởi tạo (initrd) từ rất lâu trước khi hệ thống tệp gốc (root filesystem) được gắn kết (mount).

Đánh đổi

  • Phụ thuộc công cụ: Bạn không thể mở các tệp journal bằng vim hoặc nano. Nếu tệp thực thi journalctl bị hỏng, việc đọc log sẽ trở nên khó khăn.
  • Rủi ro hỏng dữ liệu: Mất điện đột ngột đôi khi có thể làm hỏng tệp journal nhị phân. Tuy nhiên, systemd thường đủ kiên cố để tự động bắt đầu một tệp mới.

Cấu hình khuyến nghị: Tính bền vững và Hiệu năng

Mặc định, một số bản phân phối (như Debian) lưu trữ log trong /run/log/journal. Điều này có nghĩa là log của bạn sẽ biến mất ngay khi bạn khởi động lại máy—một cơn ác mộng cho việc phân tích sau sự cố (post-mortem). Trong môi trường production, tôi luôn đảm bảo journal được lưu trữ vĩnh viễn và được giới hạn dung lượng nghiêm ngặt.

Trên một máy chủ web Ubuntu 22.04 tiêu chuẩn, tôi nhận thấy rằng việc bật lập chỉ mục vĩnh viễn đã giảm đáng kể thời gian điều tra các lỗi OOM (Out of Memory) kill. Thay vì phải phân tích lại các tệp cũ, hệ thống truy vấn trực tiếp các log đã được lập chỉ mục trên đĩa.

Để log của bạn tồn tại sau khi khởi động lại, hãy tạo thư mục lưu trữ và khởi động lại dịch vụ:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

Tiếp theo, chỉnh sửa /etc/systemd/journald.conf để ngăn journal tiêu tốn toàn bộ đĩa cứng của bạn. Tôi thường sử dụng các cài đặt này cho một máy ảo (VM) cỡ trung bình:

[Journal]
Storage=persistent
SystemMaxUse=1G
MaxRetentionSec=1month

Làm chủ công cụ truy vấn

Sức mạnh thực sự của journal là tốc độ bạn có thể trích xuất dữ liệu cụ thể. Dưới đây là các lệnh tôi thường xuyên sử dụng nhất khi máy chủ bắt đầu gặp trục trặc.

1. Theo dõi thời gian thực với ngữ cảnh

Lệnh journalctl -xe là tiêu chuẩn trong ngành để xem nhanh tình hình. Flag -x thêm các mục danh mục giải thích ý nghĩa thực sự của các lỗi cụ thể. Để theo dõi trực tiếp, hãy sử dụng flag follow:

journalctl -f

2. Kỹ thuật “Du hành thời gian”

Nếu một lập trình viên nói với bạn rằng API của họ bị lỗi 500 vào đúng 2:15 chiều, đừng cuộn chuột tìm kiếm. Hãy thu hẹp khoảng thời gian một cách chính xác:

# Xem log trong 20 phút qua
journalctl --since "20 min ago"

# Lọc cho một khoảng thời gian 10 phút cụ thể
journalctl --since "2024-03-10 14:10:00" --until "2024-03-10 14:20:00"

3. Loại bỏ nhiễu từ các dịch vụ

Ngừng nhìn vào các tác vụ cron không liên quan khi bạn đang cố gắng sửa lỗi Nginx. Sử dụng flag unit để cô lập dịch vụ:

journalctl -u nginx.service --since "today"

4. Lọc theo mức độ nghiêm trọng

Khi mọi thứ đang đổ vỡ, bạn chỉ muốn thấy những dòng chữ màu đỏ. Hãy lọc theo mức độ ưu tiên (3 là lỗi – error, 4 là cảnh báo – warning):

# Chỉ hiển thị lỗi từ lần khởi động hiện tại
journalctl -p err -b

Flag -b là một cứu cánh. Nó bỏ qua tất cả các log trước đó và chỉ hiển thị dữ liệu từ lần khởi động gần nhất.

5. Xuất dữ liệu để kiểm tra bên ngoài

Nếu bạn cần gửi log cho đội ngũ bảo mật hoặc một công cụ phân tích bên ngoài như ELK, hãy xuất chúng dưới dạng JSON. Điều này bảo toàn các metadata phong phú mà việc sao chép-dán thông thường sẽ làm mất đi:

journalctl -u ssh.service -o json-pretty --since "1 hour ago"

Bảo trì thực tế

Nếu đĩa của bạn đang đầy và bạn chưa cấu hình journald.conf, bạn có thể dọn dẹp log thủ công. Tôi luôn chạy các lệnh này trước khi tạo bản mẫu VM để giữ cho image gọn nhẹ:

# Thu nhỏ journal xuống đúng 500MB
sudo journalctl --vacuum-size=500M

# Xóa mọi thứ cũ hơn một tuần
sudo journalctl --vacuum-time=7d

Sử dụng journalctl hiệu quả là việc thay đổi tư duy của bạn. Đừng coi log là các tệp tĩnh nữa mà hãy bắt đầu coi chúng như một cơ sở dữ liệu có thể truy vấn. Một khi bạn làm chủ được các bộ lọc này, bạn sẽ tìm thấy các vấn đề trong vài giây mà trước đây phải mất hàng giờ để grep.

Share: