Tắt log trong systemd service

1. Tổng quan

Trong quá trình viết hoặc triển khai một systemd service cho một script hoặc một chương trình nền (daemon), đôi khi chúng ta không muốn stdout (hoặc stderr) của service ghi log vào journalctl hay bị forward sang syslog. Việc ghi log không cần thiết không chỉ gây rác log, mà còn tốn tài nguyên lưu trữ.

Bài viết này sẽ hướng dẫn cách vô hiệu hóa hoàn toàn log hoặc chỉ log vào journal mà không forward sang syslog, một cách hiệu quả và chính xác theo khuyến nghị của systemd.

2. Dùng StandardOutput=null để tắt hoàn toàn log

Giả sử bạn có một service đơn giản chạy một script Python:

[Service]
ExecStart=/usr/bin/script-python.py
StandardOutput=null
StandardError=null

Điều gì xảy ra?

  • StandardOutput=null: Tắt hoàn toàn việc ghi stdout.
  • StandardError=null: Tắt hoàn toàn việc ghi stderr.
  • Không có log nào được ghi vào journal hay syslog.
  • Tương đương với việc bạn dùng shell redirect: script-python.py > /dev/null 2>&1.

🧠 Đây là cách tốt nhất nếu bạn không cần ghi log gì cả.

3. Trường hợp vẫn muốn log vào journal

Nếu bạn vẫn muốn giữ lại log để có thể xem bằng journalctl, nhưng không muốn ghi vào syslog, bạn có thể dùng:

[Service]
ExecStart=/usr/bin/script-python.py
StandardOutput=journal
StandardError=journal

Điều này có tác dụng gì?

  • Ghi log vào journalctl -u your-service-name.
  • Nhưng có thể vẫn bị forward sang syslog nếu file config /etc/systemd/journald.conf chứa dòng ForwardToSyslog=yes (đây là mặc định của một số hệ thống như Debian/Ubuntu).

🛠 Nếu bạn chỉ cần xem log bằng journalctl và muốn tránh syslog, hãy chắc chắn rằng ForwardToSyslog=no.

4. So sánh với cách redirect bằng shell

Bạn có thể thấy hai cách viết này là tương đương:

Cách 1:

ExecStart=/bin/sh -c '/usr/bin/script-python.py > /dev/null'

Cách 2:

ExecStart=/usr/bin/script-python.py
StandardOutput=null

Khác biệt ở đây là:

  • Cách 1 chỉ redirect stdout của script-python.py, nếu bạn có nhiều dòng trong shell script thì những dòng khác vẫn có thể ghi log.
  • Cách 2 (dùng StandardOutput=null) tắt luôn toàn bộ stdout của process chính trong service.

✅ Lời khuyên: Không cần bọc trong shell, systemd có thể chạy trực tiếp script hoặc binary.

🧹 Dọn dẹp cấu hình kiểu cũ (SysV init)

Nhiều người chuyển từ init script cũ (SysV) sang systemd vẫn giữ cấu hình như:

Type=forking
PIDFile=/dev/shm/abc.pid
ExecStart=/usr/bin/myscript.sh

Trong đó, myscript.sh sẽ gọi một tiến trình chạy nền rồi ghi PID thủ công vào file.

Với systemd, điều này không cần nữa:

  • Systemd quản lý PID và trạng thái tiến trình tự động.
  • Không cần Type=forking, không cần PIDFile và cũng không cần & để chạy nền trong script.
  • Hãy viết lại đơn giản như sau:
[Service]
ExecStart=/usr/bin/script-python.py
Type=simple
StandardOutput=null

⚡️ Điều này sẽ giúp service gọn gàng, hiệu quả và theo đúng chuẩn systemd.

🧠 Tổng kết

Mục tiêuCấu hình đề xuất
Tắt toàn bộ logStandardOutput=null StandardError=null
Chỉ log vào journalctlStandardOutput=journal StandardError=journal
Tránh dùng sh -c không cần thiếtChạy trực tiếp script bằng ExecStart=/usr/bin/myscript.py
Không cần Type=forking hay PIDFile= nữaDùng mặc định Type=simple

📌 Có thể kiểm tra forward syslog

Nếu bạn muốn kiểm tra xem journald có forward log sang syslog hay không, kiểm tra file:

cat /etc/systemd/journald.conf | grep ForwardToSyslog

Nếu đang là yes, bạn có thể sửa thành:

ForwardToSyslog=no

Rồi reload lại:

sudo systemctl restart systemd-journald

Hy vọng bài viết này giúp bạn hiểu rõ hơn về cách kiểm soát log trong systemd service. Hãy giữ cấu hình gọn gàng, hiệu quả và chỉ log khi thật sự cần thiết nhé!

Bài viết gần đây

spot_img

Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here

Đăng ký nhận thông tin bài viết qua email