เทคโนโลยีโดย milo อ่าน 5 นาทีเรียบเรียงโดยมี AI ช่วย

สร้างระบบบันทึกเหตุการณ์อัตโนมัติด้วย Syslog และ jq สำหรับสคริปต์ Infrastructure

เคยเจอปัญหารันสคริปต์จัดการเซิร์ฟเวอร์แล้วพังโดยไม่รู้สาเหตุไหม? มาสร้างระบบ Log อัตโนมัติแบบ Real-time ด้วย Syslog และ jq เพื่อตรวจจับบักก่อนระบบล่มกัน

สารบัญ

จินตนาการว่าคุณรันสคริปต์ Deploy ขนาดใหญ่ก่อนกลับบ้าน ทุกอย่างดูเรียบร้อย แต่ตอนตี 2 ระบบดันพังเพราะ Disk ไม่พอ หรือ Memory รั่ว ปัญหาคือเรามักไม่รู้สาเหตุ เพราะสคริปต์ส่วนใหญ่แค่ echo ออกหน้าจอแล้วหายไปพร้อมกับเซสชันที่ปิดลง

วันนี้เราจะมาแก้ปัญหานี้ด้วยการสร้างระบบบันทึกเหตุการณ์ (Logging) แบบอัตโนมัติ โดยใช้เครื่องมือมาตรฐานอย่าง Syslog และตัวช่วยประมวลผล JSON อย่าง jq เพื่อให้คุณสามารถตรวจจับบักและติดตามสถานะของสคริปต์ได้แบบเรียลไทม์

ทำไมต้อง Syslog และ JSON?

การเขียน Log ลงไฟล์ .txt ธรรมดา ทำให้การค้นหาและกรองข้อมูลทำได้ยาก โดยเฉพาะเมื่อ Log มีขนาดใหญ่ขึ้น การส่ง Log เข้าสู่ระบบ Syslog ของเครื่อง (ซึ่งมีอยู่แล้วใน Linux ทุกดิสทริบิวชัน) จะช่วยให้ระบบปฏิบัติการจัดการการหมุนเวียนไฟล์ (Log Rotation) ให้อัตโนมัติ

ที่สำคัญคือเราจะส่งข้อมูลในรูปแบบ JSON (Structured Logging) แทนที่จะเป็นข้อความธรรมดา เพื่อให้เราสามารถใช้ jq ดึงค่าเฉพาะฟิลด์ (เช่น level, message, timestamp) ออกมาวิเคราะห์ได้อย่างรวดเร็วและแม่นยำ

เริ่มต้นสร้าง Log แบบ Structured จากสคริปต์

ไม่ว่าคุณจะเขียนสคริปต์ด้วย Bash หรือ Python การส่ง Log เข้า Syslog ทำได้ง่ายมาก

ตัวอย่างจาก Bash Script

ใน Bash เราสามารถใช้คำสั่ง logger ที่มีอยู่แล้วในระบบ เพื่อส่งข้อความเข้า Syslog โดยตรง แต่เราจะแปลงข้อมูลให้เป็น JSON ก่อนส่ง

#!/bin/bash

log_event() {
  local level=$1
  local message=$2
  # สร้าง JSON string แบบง่ายๆ
  local log_payload="{\"timestamp\":\"$(date -u +%FT%TZ)\",\"level\":\"$level\",\"script\":\"deploy.sh\",\"msg\":\"$message\"}"
  
  # ส่งเข้า Syslog โดยใช้ tag ว่า my_infra_script
  logger -t my_infra_script "$log_payload"
}

# การใช้งาน
log_event "info" "เริ่มกระบวนการ Deploy"
# ... ทำงานบางอย่าง ...
if [ $? -ne 0 ]; then
  log_event "error" "ไม่สามารถ Pull Image จาก Registry ได้"
  exit 1
fi
log_event "info" "Deploy สำเร็จ"

เมื่อรันสคริปต์นี้ ข้อมูลจะถูกเก็บไว้ใน /var/log/syslog หรือ /var/log/messages ของเครื่องทันที

ตัวอย่างจาก Python Script

สำหรับ Python การทำงานจะสะอาดกว่า เราสามารถใช้ logging library ร่วมกับ SysLogHandler และฟอร์แมตข้อมูลเป็น JSON ได้

import logging
import logging.handlers
import json
from datetime import datetime

class JsonFormatter(logging.Formatter):
    def format(self, record):
        log_record = {
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "level": record.levelname.lower(),
            "script": "db_backup.py",
            "msg": record.getMessage()
        }
        return json.dumps(log_record)

# ตั้งค่า Syslog Handler
handler = logging.handlers.SysLogHandler(address='/dev/log')
handler.setFormatter(JsonFormatter())

logger = logging.getLogger('my_infra_script')
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# การใช้งาน
logger.info("เริ่มสำรองข้อมูลฐานข้อมูล")
try:
    # จำลองการทำงาน
    pass
except Exception as e:
    logger.error(f"เกิดข้อผิดพลาดระหว่าง Backup: {str(e)}")

ใช้ jq ตรวจจับปัญหาแบบเรียลไทม์

ตอนนี้ Log ของเราถูกเก็บในระบบแล้ว ขั้นตอนต่อไปคือการดึงข้อมูลเฉพาะสคริปต์ของเราออกมาดู และกรองเฉพาะ Error หรือ Warning โดยใช้ jq

เปิด Terminal แล้วลองรันคำสั่งนี้:

tail -f /var/log/syslog | grep "my_infra_script" | jq -R 'fromjson | select(.level == "error" or .level == "warning")'

คำอธิบายคำสั่ง:

  • tail -f: อ่านไฟล์ Log แบบเรียลไทม์ (ติดตามทุกบรรทัดใหม่)
  • grep "my_infra_script": กรองเฉพาะ Log ที่มาจากสคริปต์ของเรา (ตาม tag ที่ตั้งไว้)
  • jq -R 'fromjson': บอก jq ให้รับข้อมูลเข้ามาเป็น Raw string แล้วแปลงเป็น JSON
  • select(.level == "error"): กรองเอาเฉพาะออบเจกต์ที่มีฟิลด์ level เท่ากับ error

ผลลัพธ์ที่ได้จะแสดงเฉพาะข้อความ Error ที่เกิดขึ้นจากสคริปต์ของคุณ ทำให้คุณเห็นปัญหาทันทีที่มันเกิดขึ้น

กรณีศึกษา: การตรวจสอบ Disk Space อัตโนมัติ

สมมติว่าคุณมีสคริปต์ตรวจสอบ Disk Space รันทุก 5 นาทีผ่าน Cronjob หาก Disk เริ่มเต็ม คุณอยากให้ระบบส่ง Log แจ้งเตือน

#!/bin/bash
# check_disk.sh

USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')

if [ "$USAGE" -gt 90 ]; then
  logger -t disk_monitor "{\"level\":\"critical\",\"msg\":\"Disk usage สูงเกิน 90% (ปัจจุบัน $USAGE%)\"}"
else
  logger -t disk_monitor "{\"level\":\"info\",\"msg\":\"Disk usage ปกติ ($USAGE%)\"}"
fi

ในอีกหน้าต่าง Terminal คุณเปิดคำสั่ง jq รอไว้:

tail -f /var/log/syslog | grep "disk_monitor" | jq -r 'select(.level == "critical") | "ALERT: " + .msg'

เมื่อสคริปต์รันและพบว่า Disk เกิน 90% หน้าจอ Monitor ของคุณจะแสดง ALERT: Disk usage สูงเกิน 90% (ปัจจุบัน 92%) ทันที คุณสามารถนำเอาตัวกรองนี้ไปต่อกับคำสั่งส่ง Line Notify หรือ Slack Webhook ได้โดยง่าย

สรุปและก้าวต่อไป

การใช้ logger ส่งข้อมูลแบบ JSON เข้า Syslog และใช้ jq กรองข้อมูล คือวิธีการที่ต้นทุนต่ำแต่ทรงพลังมาก คุณไม่ต้องติดตั้งระบบอย่าง ELK Stack หรือ Datadog เพื่อเริ่มต้นจัดการ Log ของสคริปต์ระดับเล็กถึงกลาง แถมยังเป็นพื้นฐานที่ดีในการทำความเข้าใจ Structured Logging ก่อนจะขยับไปใช้ระบบ Centralized Logging ในอนาคต

ลองนำเทคนิคนี้ไปปรับใช้กับสคริปต์ Infrastructure ของคุณดูสิ แล้วอย่าลืมแวะมาแชร์ในคอมเมนต์ว่าคุณใช้ jq กรอง Log แบบไหนเพิ่มเติม หรือกดติดตามบทความต่อไปของเราเกี่ยวกับการส่ง Log เข้าระบบ Cloud เพื่อพัฒนาทักษะ DevOps ของคุณให้ก้าวหน้ายิ่งขึ้น!

เนื้อหาที่จัดทำโดยมี AI ช่วยจะมีป้ายกำกับ "เรียบเรียงโดยมี AI ช่วย" เพื่อให้คุณทราบอย่างชัดเจน เราถือว่าความโปร่งใสเรื่องการใช้ AI เป็นสิ่งสำคัญต่อความไว้วางใจของผู้อ่าน

พบข้อมูลที่ไม่ถูกต้องหรือคลาดเคลื่อน?เข้าสู่ระบบเพื่อทักท้วง
บทความนี้เป็นอย่างไร?

ยังไม่มีความคิดเห็น — มาเป็นคนแรกกันเถอะ!