ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

Home อ่าน Log ระบบบน Linux ด้วย journalctl

อ่าน Log ระบบบน Linux ด้วย journalctl

บน Linux ที่ใช้ systemd ข้อความจาก Kernel และ Service ทุกตัวจะถูกเก็บรวมไว้ใน journal ซึ่งอ่านได้ด้วยคำสั่ง journalctl ข้อดีคือกรองได้ละเอียดกว่าการ grep ไฟล์ข้อความ เช่น ดูเฉพาะ Log ของ Nginx ในชั่วโมงที่ผ่านมา หรือดูเฉพาะ Error ตั้งแต่บูตครั้งก่อน ซึ่งมีประโยชน์มากเมื่อต้องหาสาเหตุว่าทำไม Service ล้มหรือทำไมเครื่องรีบูตเอง

บทความนี้ใช้ได้กับ Ubuntu 22.04/24.04 และ AlmaLinux/Rocky Linux 8-9 ส่วน Log ของโปรแกรมที่เขียนลงไฟล์เองโดยตรง เช่น Access Log ของ Nginx จะไม่อยู่ใน journal ให้อ่านจากไฟล์ใน /var/log/ ตามปกติ

สิ่งที่ต้องเตรียม

  • เซิร์ฟเวอร์ Linux ที่ใช้ systemd และเข้าผ่าน SSH ได้
  • สิทธิ์ sudo หรือเป็นสมาชิกกลุ่ม systemd-journal หรือ adm (ผู้ใช้ทั่วไปจะเห็นเฉพาะ Log ของตัวเอง)
  • รู้ชื่อ Service ที่ต้องการดู (ดูวิธีหาชื่อใน จัดการ Service บน Linux ด้วย systemctl)

ขั้นตอนที่ 1: ดู Log ล่าสุดและติดตามแบบสด

sudo journalctl -n 50
sudo journalctl -f
sudo journalctl -e

-n 50 แสดง 50 บรรทัดล่าสุด -f แสดงบรรทัดใหม่ต่อเนื่องจนกว่าจะกด Ctrl+C และ -e เปิดตัวอ่านแล้วกระโดดไปท้ายสุด ถ้ารัน journalctl เฉย ๆ จะเริ่มจาก Log เก่าที่สุด ซึ่งอาจยาวหลายแสนบรรทัด

ตัวอ่านที่ใช้คือ less เลื่อนด้วยลูกศร ค้นหาด้วย /คำค้น กด G ไปท้ายสุด และ q เพื่อออก ถ้าต้องการผลลัพธ์ต่อเข้าคำสั่งอื่นหรือบันทึกเป็นไฟล์ ให้ใส่ --no-pager

ขั้นตอนที่ 2: กรองตาม Service

sudo journalctl -u nginx
sudo journalctl -u nginx -n 100 --no-pager
sudo journalctl -u php8.3-fpm -u nginx -f

-u เลือก Unit ใส่ได้หลายตัวเพื่อดู Log ของ Nginx และ PHP-FPM สลับกันตามเวลา ซึ่งช่วยจับคู่เหตุการณ์ได้ง่าย เช่น เห็นว่า PHP-FPM ถึงขีดจำกัด max_children ในวินาทีเดียวกับที่ Nginx เริ่มตอบ 502

ถ้าไม่ได้ต้องการกรองตาม Unit แต่ตามโปรแกรม ใช้ Field ของ journal ได้ เช่น ดู Log จากโปรแกรม sshd ทั้งหมด

sudo journalctl _COMM=sshd --since today

ขั้นตอนที่ 3: กรองตามช่วงเวลา

sudo journalctl --since "1 hour ago"
sudo journalctl --since today
sudo journalctl --since "2026-09-18 09:00" --until "2026-09-18 10:30"
sudo journalctl -u mariadb --since yesterday --until today

รูปแบบเวลาใช้ได้ทั้ง YYYY-MM-DD HH:MM:SS และคำอย่าง today, yesterday, "30 min ago" เวลาที่แสดงใช้ Timezone ของเครื่อง ถ้าเครื่องยังเป็น UTC เวลาจะช้ากว่าเวลาไทย 7 ชั่วโมง ตั้งค่าได้ตาม ตั้งค่า Timezone และซิงก์เวลาอัตโนมัติบน Linux Server หรือใส่ --utc เพื่อดูเวลาแบบ UTC

ขั้นตอนที่ 4: กรองตามระดับความรุนแรง

sudo journalctl -p err -b
sudo journalctl -p warning --since today

-p แสดงระดับที่กำหนดและรุนแรงกว่า ระดับเรียงจากรุนแรงมากไปน้อยคือ emerg (0), alert (1), crit (2), err (3), warning (4), notice (5), info (6) และ debug (7) คำสั่ง journalctl -p err -b จึงเป็นวิธีเร็วที่สุดในการดูว่าตั้งแต่บูตครั้งนี้มี Error อะไรบ้าง

ขั้นตอนที่ 5: ดู Log ตามรอบการบูต

sudo journalctl --list-boots
sudo journalctl -b
sudo journalctl -b -1 -n 100
sudo journalctl -k -b

-b คือรอบบูตปัจจุบัน -b -1 คือรอบก่อนหน้า ใช้หาสาเหตุเมื่อเครื่องรีบูตเองหรือค้าง โดยดูบรรทัดท้าย ๆ ของรอบก่อนหน้า ส่วน -k แสดงเฉพาะข้อความจาก Kernel คล้าย dmesg ใช้หาปัญหาดิสก์ หน่วยความจำ หรือ OOM Killer เช่น

sudo journalctl -k | grep -i "out of memory"

ถ้าพบบรรทัด Out of memory: Killed process แปลว่า RAM ไม่พอจนระบบต้องฆ่า Process ทิ้ง ดูแนวทางใน เพิ่ม Swap File บน Linux Server และ ตรวจสอบ CPU, RAM และ Load Average

ขั้นตอนที่ 6: เปิดการเก็บ Log แบบถาวร

การดู -b -1 จะทำได้ก็ต่อเมื่อ journal เก็บ Log ลงดิสก์ ถ้าเก็บไว้ในหน่วยความจำอย่างเดียว Log จะหายทุกครั้งที่รีบูต ตรวจได้ด้วย

ls -ld /var/log/journal
sudo journalctl --list-boots | head

ถ้ามีโฟลเดอร์ /var/log/journal และ --list-boots แสดงหลายรอบ แปลว่าเก็บถาวรอยู่แล้ว ซึ่งเป็นค่าปกติของ Ubuntu ถ้าไม่มี (พบได้ในบาง Image ของ AlmaLinux/Rocky ที่พึ่ง rsyslog เขียน /var/log/messages) ให้แก้ไฟล์ /etc/systemd/journald.conf ในส่วน [Journal]

[Journal]
Storage=persistent
SystemMaxUse=500M
sudo systemctl restart systemd-journald

Storage=persistent สร้างโฟลเดอร์และเขียนลงดิสก์ ส่วน SystemMaxUse จำกัดพื้นที่รวมที่ journal ใช้ได้ ถ้าไม่ตั้ง ค่าเริ่มต้นคือ 10% ของขนาด Filesystem โดยมีเพดานที่ 4 GB

ขั้นตอนที่ 7: ตรวจและลดพื้นที่ที่ journal ใช้

journalctl --disk-usage
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=14d

--vacuum-size ลบไฟล์ journal เก่าจนเหลือไม่เกินขนาดที่กำหนด ส่วน --vacuum-time ลบ Log ที่เก่ากว่าจำนวนวันที่กำหนด การลบนี้กระทบเฉพาะไฟล์ที่ถูกปิดไปแล้ว จึงอาจเหลือมากกว่าที่ระบุเล็กน้อย การ vacuum เป็นการแก้เฉพาะหน้า ถ้าต้องการให้คงที่ให้ตั้ง SystemMaxUse ตามขั้นตอนที่ 6 ส่วนไฟล์ Log ข้อความอื่น ๆ ใน /var/log ควบคุมด้วย logrotate

ขั้นตอนที่ 8: เปลี่ยนรูปแบบการแสดงผล

sudo journalctl -u nginx -o short-iso -n 20
sudo journalctl -u nginx -o cat -n 20
sudo journalctl -u nginx -o json-pretty -n 1

short-iso แสดงเวลาแบบ ISO ที่มีปีและ Timezone cat แสดงเฉพาะข้อความ ส่วน json-pretty แสดงทุก Field ของบันทึก เช่น _PID, _SYSTEMD_UNIT ซึ่งช่วยให้รู้ว่าจะกรองด้วย Field อะไรได้บ้าง

ตัวอย่างการใช้งานจริง

สถานการณ์คำสั่ง
Nginx start ไม่ขึ้นหลังแก้ Configsudo journalctl -u nginx -n 30 --no-pager
ดูว่ามีใครพยายามเข้า SSH วันนี้sudo journalctl -u ssh --since today | grep -i "failed" (AlmaLinux ใช้ -u sshd)
เครื่องรีบูตเองเมื่อคืนsudo journalctl -b -1 -e
สงสัยว่า MySQL ถูก OOM Killsudo journalctl -k --since yesterday | grep -i oom
ส่ง Log ให้ทีมซัพพอร์ตsudo journalctl -u mariadb --since "2 hours ago" --no-pager > mariadb.log

ตรวจสอบผลลัพธ์

รัน sudo systemctl restart cron (AlmaLinux/Rocky ใช้ crond) จากนั้นรัน sudo journalctl -u cron --since "2 min ago" ควรเห็นบรรทัด Stopped และ Started พร้อมเวลาที่ตรงกับตอนที่สั่ง ถ้าตั้งค่าเก็บถาวรแล้ว หลังรีบูตครั้งถัดไป journalctl --list-boots ต้องแสดงอย่างน้อย 2 รายการ

ปัญหาที่พบบ่อย

No journal files were found หรือเห็น Log น้อยผิดปกติ

ผู้ใช้ปัจจุบันไม่มีสิทธิ์อ่าน journal ของระบบ ให้ใส่ sudo หรือเพิ่มผู้ใช้เข้ากลุ่มด้วย sudo usermod -aG systemd-journal ชื่อผู้ใช้ แล้วออกจาก SSH และเข้าใหม่

Specifying boot ID or boot offset has no effect, no persistent journal was found

journal ไม่ได้เก็บลงดิสก์ จึงไม่มีข้อมูลรอบบูตก่อนหน้า ให้เปิด Storage=persistent ตามขั้นตอนที่ 6 Log ที่หายไปก่อนหน้านี้กู้คืนไม่ได้ แต่ครั้งต่อไปจะเก็บไว้

journal ใช้พื้นที่หลาย GB

ตั้ง SystemMaxUse แล้ว restart systemd-journald และหาต้นเหตุด้วยว่า Service ใดเขียน Log ถี่ผิดปกติ ใช้คำสั่ง sudo journalctl --since "10 min ago" -o json | grep -o '"_SYSTEMD_UNIT":"[^"]*"' | sort | uniq -c | sort -rn | head

ไม่เห็น Log ของแอปใน journal

แอปอาจเขียน Log ลงไฟล์ของตัวเอง เช่น /var/log/nginx/ หรือ storage/logs ของ Laravel ให้ตรวจการตั้งค่า Log ของแอปนั้น สำหรับเว็บไซต์บน Plesk ดูได้ที่ ดู Log เว็บไซต์บน Plesk เพื่อหาสาเหตุ Error

หากทำตามขั้นตอนแล้วยังติดปัญหา สามารถติดต่อทีมงาน THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/ โดยแจ้งชื่อเซิร์ฟเวอร์ ระบบปฏิบัติการ คำสั่งที่ใช้ และข้อความ Error ที่พบ เพื่อให้ตรวจสอบได้รวดเร็วขึ้น

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security