Skip to content

16.2 · Debugging cross-service issues

แพลตฟอร์ม VTRC เป็น "distributed monolith" — ~30 repo ที่แยก deploy กันแล้ว แต่ผูกกันแน่นด้วย shared database, shared secret, และ hardcoded URL (Canonical Truths) การ debug ปัญหาที่ข้าม repo จึงยากกว่าระบบ microservice ที่ออกแบบมาให้ decouple จริง เพราะไม่มีเครื่องมือ observability กลางที่ช่วยเชื่อมจุดให้

16.2.1 · ไม่มี correlation ID ข้าม service — ต้อง trace ด้วยเวลาและ business key แทน

ยืนยันจาก vtrc-api/09-cross-cutting §สิ่งที่มี/ไม่มีvtrc-api มี request log + response log แต่ไม่มี tracing ID/correlation ID ที่ผูก request เดียวกันข้าม service เข้าด้วยกัน เมื่อ vtrc-api เรียก cu-central-api ทั้งสอง log แยกกันคนละไฟล์คนละ format ไม่มี field ร่วมที่ join ได้ตรง ๆ

วิธี trace แทน correlation ID:

  1. บันทึกเวลาที่ user รายงานปัญหาให้ละเอียดที่สุด (นาที:วินาที)
  2. หา business key ที่ unique พอ — userId, citizenId (ระวัง PII — ดู runbook 7 ใน 16.1), หรือ ID ของ record ที่เกี่ยวข้อง (เช่น withdraw request ID)
  3. Grep log ของ service ต้นทาง (vtrc-api) หา business key นั้นในช่วงเวลาที่ user รายงาน
  4. ถ้า log บอกว่าเรียกไป downstream (cu-central-api, benefit-api, ฯลฯ) ให้ไปหา log ของฝั่งนั้นในช่วงเวลาเดียวกัน ±2-3 วินาที (เผื่อ network latency)
  5. ทำซ้ำจนถึง service ปลายทางที่ error เกิดขึ้นจริง

ข้อจำกัด — วิธีนี้พังทันทีถ้า business key ไม่ปรากฏใน log ของทุก hop (เช่น ถ้า vtrc-api log ด้วย userId แต่ benefit-api log ด้วย record ID ภายในที่ generate ใหม่โดยไม่ผูกกับ userId ในบรรทัดเดียวกัน) — ต้องอ่านโค้ด logging ของแต่ละ service ก่อนเพื่อรู้ว่า field ไหนใช้ join ได้จริง

16.2.2 · Log location ต่อ repo type

ไม่มี log aggregation กลาง (Vol 15) — ต้องเข้าไปดู log ที่ host ของแต่ละ service เอง รูปแบบต่างกันตาม stack:

Stackรูปแบบ logตำแหน่ง
vtrc-api (Express + custom wlog)ไฟล์ JSON string ต่อบรรทัด แยกตาม typelogs/{yyyy}/{mm}/{dd}/ ภายใน container/host (vtrc-api/09-cross-cutting)
vtrc-api request/response logApollo plugin log ทุก GraphQL request+response พร้อม PII redaction เฉพาะ headerไฟล์แยกจาก app log — รูปแบบเดียวกับที่ report-log เคย consume (request_{yyyy-mm-dd}.log)
NestJS service ทั่วไป (benefit-api, recruitment-api, pms-api, ฯลฯ)console.log/Nest built-in logger → stdout ของ containerdocker logs {container} — ไม่มี rotation กลาง ต้องพึ่ง Docker log driver ของ host
Express service อื่น (ai-recruitment-api, meeting-vtrc-api, 2way-vtrc-api)console.log ล้วน ไม่มี structured loggerstdout ของ container เช่นกัน
cu-central-apiไม่ยืนยันรูปแบบ log แยกในรอบสำรวจนี้ — UNVERIFIEDต้องตรวจกับทีมที่ดูแลจริง

ข้อสังเกตสำคัญ — เพราะทุก service ใช้ console.log/stdout เป็นหลัก การ debug production ต้องมีสิทธิ์ SSH เข้า host ที่รัน container นั้นโดยตรง (หรือสิทธิ์ดู Docker log ผ่านเครื่องมือ orchestration ถ้ามี) ไม่มีทางดู log จาก dashboard กลางได้

16.2.3 · ลำดับการ trace ที่แนะนำเมื่อปัญหาข้าม repo

  1. ระบุ entry point ที่ user เห็น — frontend ไหน (vtrc-web, vtrc-mobile, backoffice ตัวใด) เรียก endpoint/query อะไร ใช้ browser_network_requests หรือ mobile network log เพื่อยืนยัน URL ปลายทางจริง (ห้ามเดาจากชื่อ repo — ดู runbook 10 ใน 16.1)
  2. หา service ที่รับ request นั้นตรง — เทียบกับ Volume 13 §03 Inter-service map ว่า service นี้ต่อไปที่ไหนอีกบ้าง
  3. เช็ค log ของ service แรกก่อน — ถ้า error เกิดที่นี่เลย (validation, auth) ไม่ต้องไล่ต่อ
  4. ถ้า log บอกว่าเรียก downstream แล้ว error — ระบุว่าเป็น network error (timeout, connection refused) หรือ business error (4xx/5xx ที่มี body) — network error ให้เช็คว่า downstream service ยังรันอยู่ก่อน (ดู runbook 5 ใน 16.1 เป็นตัวอย่าง)
  5. ถ้าสงสัยว่าเป็น data drift ระหว่าง 2 schema (เช่น WdHospitals) — เทียบ record ตรงด้วย SQL ทั้งสองฝั่งแทนการไล่ log เพราะ sync เป็น manual/raw-SQL ไม่ผ่าน API ที่ log ได้ (Vol 14 §02)
  6. ถ้าสงสัยว่าเป็น auth — เช็คว่า service ไหน verify token ด้วย secret ตัวไหน (SEC-API-02 — 4 service ใช้ secret เดียวกัน, vtrc-api/cu-central-api ใช้คนละ mechanism) — token ที่ valid ที่ service หนึ่งอาจ invalid ที่อีกตัวถ้า issuer/secret ไม่ match

16.2.4 · ข้อจำกัดที่ต้องยอมรับ

  • ไม่มีทาง reconstruct request timeline ข้าม 3+ service ได้แม่นยำระดับ millisecond เพราะไม่มี distributed tracing (Jaeger/Zipkin/OpenTelemetry) ในทุก repo ที่ตรวจสอบ
  • Log ที่มี PII (ดู runbook 7 ใน 16.1) ต้องระมัดระวังเป็นพิเศษตอน grep/copy ออกมาวิเคราะห์ — ห้าม commit ไฟล์ log ที่มี PII เข้า repo ใหม่ไม่ว่าเพื่อจุดประสงค์ใด (บทเรียนจาก report-log)
  • ถ้าปัญหาเกี่ยวกับ cron/scheduled job ที่ไม่มี health-check (Vol 14 §03 CORR-BIZ-03) log อาจไม่มีหลักฐานว่า cron "ควรจะ" รันแต่ไม่รัน (silent failure) — ต้องเทียบ timestamp ของ record ล่าสุดกับความถี่ cron ที่ประกาศในโค้ดเสมอ ไม่ใช่แค่ดูว่า log มี error หรือไม่

ไป กลับสู่ Volume 16 index