Skip to content

14.4 Log reading & error hunting

บทนี้รวบรวม path ของ log ทุกประเภท, pattern ที่บ่งชี้ปัญหา, และตัวอย่างวิธีค้นหาต้นตอของ error

แผนภาพ log ทั้งระบบ

vtrc-api host
├── /home/dev/vtrc-api/api-logs/         ←── wlog.js เขียน (log file รายวัน)
│   ├── 2025-07-11.log                   ←── info log
│   ├── error_2025-07-11.log             ←── error log
│   ├── warning_2025-07-11.log           ←── warning log
│   ├── query_2025-07-11.log             ←── SQL query log
│   ├── notificationLog_2025-07-11.log
│   ├── notificationLogError_2025-07-11.log
│   ├── slipError_2025-07-11.log         ←── PDF payslip error
│   ├── verify_2025-07-11.log
│   └── forceLogs_2025-07-11.log

├── docker logs vtrc-api-nodejs          ←── stdout/stderr (console.log)
│   (แต่ละ replica แยกกัน: ...-2, ...-3, ...-5)

└── /home/dev/vtrc-api/nginx-log/
    ├── access-api-443.log               ←── access log ของ vtrcapi.redcross.or.th
    ├── error-api-443.log
    ├── access-web-443.log               ←── access log ของ vtrc.redcross.or.th
    └── error-web-443.log

cu-central-api host
├── /home/dev/cu-central-api/main-api/logs/
└── /home/dev/cu-central-api/nginx-log/

centralize-api host
└── /home/dev/centralize-api/logs/       ←── I3GatewayLogger

วิธีอ่าน log

อ่าน log ของ vtrc-api (wlog)

wlog.js เขียน log ในรูปแบบ:

2025-07-11 14:30:45 - {"CODE":"...","SOURCE":"Method:getUsers","TYPE":"INFO","text":"..."}

หรือ plain text ในไฟล์ info:

2025-07-11 14:30:45 - server started
bash
# อ่าน log ล่าสุดของวันนี้
tail -100 /home/dev/vtrc-api/api-logs/$(date +%Y-%m-%d).log

# ติดตาม log แบบ live
tail -f /home/dev/vtrc-api/api-logs/$(date +%Y-%m-%d).log

# อ่านเฉพาะ error
tail -f /home/dev/vtrc-api/api-logs/error_$(date +%Y-%m-%d).log

อ่าน stdout ของ container (console.log)

bash
# ดู 100 บรรทัดสุดท้ายของ replica 1
docker logs --tail 100 vtrc-api-nodejs

# ติดตาม live
docker logs -f vtrc-api-nodejs

# ดู log ตั้งแต่เวลาที่กำหนด
docker logs --since 2h vtrc-api-nodejs

# ดูเฉพาะช่วงเวลา
docker logs --since 2025-07-11T14:00:00 --until 2025-07-11T15:00:00 vtrc-api-nodejs

อ่าน nginx access log

bash
# request ล่าสุด 50 รายการที่ vtrcapi.redcross.or.th
tail -50 /home/dev/vtrc-api/nginx-log/access-api-443.log

# หา request ที่ status code 5xx
grep ' 5\d\d ' /home/dev/vtrc-api/nginx-log/access-api-443.log | tail -20

# หา request ที่ช้า (over 1 วินาที — คอลัมน์ `$request_time`)
awk '$NF > 1.0' /home/dev/vtrc-api/nginx-log/access-api-443.log | tail -20

Pattern ที่บ่งชี้ปัญหา

Error ระดับวิกฤต

Patternความหมายสาเหตุที่เป็นไปได้
Unable to connect to the databasevtrc-api เชื่อมต่อ MariaDB ไม่ได้db host down, credentials ผิด, network
JWT_SECRET is invalidJWT verification failsecret ถูกเปลี่ยนระหว่าง deploy
ECONNREFUSEDไม่สามารถเชื่อมต่อ service อื่นdownstream service ล้มเหลว
ETIMEDOUTconnection timeoutnetwork ช้า, downstream ไม่ตอบ
Cannot read property 'X' of undefinedbug ใน codeมักเกิดกับ GraphQL resolver
SequelizeConnectionAcquireTimeoutErrorconnection pool ไม่พอpool ล็อค, db ช้า
execSync ใน logPDF generation ทำงานปกติ แต่ถ้าบ่อยเกินไปแสดงว่าช้า
qpdf: command not foundqpdf binary ไม่อยู่Docker image ผิด
EACESLDAP bind ไม่สำเร็จcredentials ผิด, AD ล้มเหลว

Error ที่ควรสังเกต

Patternความหมาย
Too many connectionsMariaDB เปิด connection ไม่พอ
ER_LOCK_WAIT_TIMEOUTrow lock ค้างนาน — มักจาก transaction ที่ไม่ commit
ER_DUP_ENTRYINSERT ซ้ำ — มักเป็น race condition
REDIS ENOTFOUNDRedis ล้มเหลว
Failed to send notificationFCM หรือ push ล้มเหลว

การ grep หา error ของ user เฉพาะ

กรณีที่ 1 — รู้ empcode

bash
# nginx log มี empcode ใน URL (path /readfile/prs/...)
grep '/readfile/prs/.*EMP001' /home/dev/vtrc-api/nginx-log/access-api-443.log

# wlog อาจมี empcode ใน JSON
grep 'EMP001' /home/dev/vtrc-api/api-logs/error_$(date +%Y-%m-%d).log

กรณีที่ 2 — รู้เวลาที่เกิดปัญหา

bash
# ดู nginx log ในช่วงเวลาที่รายงาน
awk '/11\/Jul\/2025:14:[3-4][0-9]:/' /home/dev/vtrc-api/nginx-log/access-api-443.log

# ดู wlog ในช่วงเวลา
grep '2025-07-11 14:3' /home/dev/vtrc-api/api-logs/error_2025-07-11.log

กรณีที่ 3 — รู้ feature ที่ใช้

bash
# หา log ที่เกี่ยวกับ leave request
grep -i 'leave' /home/dev/vtrc-api/api-logs/error_2025-07-11.log

# หา log ที่เกี่ยวกับ payslip
grep -i 'slip\|prs\|pdf' /home/dev/vtrc-api/api-logs/slipError_2025-07-11.log

ตัวอย่าง error จริงจาก codebase

ตัวอย่างที่ 1 — PDF payslip ไม่ออก

log ใน slipError_*.log:

2025-07-11 14:30:45 - {"CODE":"PDF_GEN_FAIL","SOURCE":"Mutation:genSlip","TYPE":"ERROR","text":"execSync failed: Command failed: qpdf --encrypt ..."}

ตีความ: qpdf ทำงานผิดพลาด อาจเป็นเพราะ:

  • password PDF มีอักขระพิเศษที่ break shell command (SEC-1)
  • qpdf binary ไม่ได้ติดตั้ง (ตรวจสอบ Docker image)
  • disk เต็ม

ตัวอย่างที่ 2 — login ไม่สำเร็จ

log ใน error_*.log:

2025-07-11 14:30:45 - {"CODE":"LDAP_FAIL","SOURCE":"Mutation:login","TYPE":"ERROR","text":"Invalid Credentials"}

หรือจาก cu-central-api stdout:

LDAP connection error: ECONNREFUSED 10.188.128.213:389

ตีความ: LDAP ไม่ตอบ ตรวจสอบ network ระหว่าง cu-central-api host กับ on-prem

ตัวอย่างที่ 3 — cron ไม่รัน

ไม่มี log ใน notificationLog_*.log หรือ forceLogs_*.log ในวันที่คาดไว้

ตีความ (แยกตาม job):

  • ถ้าเป็น fund rate (updateSuccessFundChangeRateByJob) หรือ cron ของ cu-central → ตรวจว่า replica APP_NO=1 ยังรัน (docker exec … printenv APP_NO)
  • ถ้าเป็น updateDelegatesExpire / statLog → job เหล่านี้รันทุก replica; อย่าโทษ APP_NO=1 เป็น SPOF — ตรวจ timezone, error ใน log ของทุก replica, และ idempotency ของ handler

วิธีการทำ log rotation

ปัจจุบันไม่มี log rotation ที่ automate — ทีมต้องลบเอง

ลบ log เก่า (manual)

bash
# ลบ log ที่เก่ากว่า 30 วัน
find /home/dev/vtrc-api/api-logs/ -mtime +30 -delete
find /home/dev/vtrc-api/nginx-log/ -mtime +30 -delete

# ดูขนาด log ก่อนลบ
du -sh /home/dev/vtrc-api/api-logs/
ls -lhS /home/dev/vtrc-api/api-logs/ | head

Docker container log rotation

Docker log ของ container เก็บใน /var/lib/docker/containers/<id>/<id>-json.log — โตขึ้นเรื่อย ๆ

ตั้งค่าใน /etc/docker/daemon.json:

json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "5"
  }
}

ต้อง restart Docker daemon หลังแก้

nginx log rotation

ใช้ logrotate ของ host:

bash
cat > /etc/logrotate.d/vtrc-nginx <<EOF
/home/dev/vtrc-api/nginx-log/*.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
    create 644 root root
    sharedscripts
    postrotate
        docker exec vtrc-web-server nginx -s reopen 2>/dev/null || true
    endscript
}
EOF

ปัญหาเฉพาะตัวของระบบนี้

1. log กระจายหลายที่

ไม่มีจุดรวม — ต้องดูทั้ง api-logs/, docker logs, nginx-log/ แยกกัน

2. PII ใน log

nginx access log มี pid (identityCard) และ empcode ใน URL — ต้องระวังการ share log กับบุคคลภายนอก

3. log format ไม่ consistent

บางบรรทัดเป็น JSON, บางบรรทัดเป็น plain text — grep ยาก

4. timestamp ใช้ timezone ท้องถิ่น

log ใช้ Asia/Bangkok — ต้องระวังเวลาเทียบกับ UTC ถ้ารวมข้าม timezone

แนะนำ

  1. เก็บ log อย่างน้อย 90 วัน สำหรับ audit
  2. อย่า share log ดิบกับบุคคลภายนอก โดยไม่ redact PII
  3. ทดลอง grep ใน UAT ก่อนทำบน production
  4. ติดตั้ง logrotate ทุก host เพื่อกัน disk เต็ม
  5. พิจารณาใช้ log aggregation (Loki, ELK) ในระยะยาว — รายละเอียด Volume 15