← Blog

ระบบเฝ้าระวังข้อผิดพลาดที่ใช้งานได้จริง — บทเรียนจากข้อความที่หายวันละ 113 ฉบับ

การติดตั้งระบบเฝ้าระวังข้อผิดพลาดใช้เวลาไม่ถึงชั่วโมง

ส่วนการทำให้มันใช้งานได้จริง ใช้เวลาเป็นเดือนและต้องแก้เรื่องที่ไม่มีในคู่มือ

ปัญหาแรก — ตั้งค่าแล้วต้องรีสตาร์ตทั้งเครื่อง

เดิมการตั้งค่าระบบเฝ้าระวังต้องแก้ไฟล์ตั้งค่าของทุกบริการแล้วรีสตาร์ตทั้งหมด

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

เราย้ายการตั้งค่าทั้งหมดมาไว้ที่หน้าเว็บของเครื่องมือดูแลระบบ แล้วส่งค่าให้ทุกบริการตอนเริ่มทำงาน

พร้อมกันนั้นเราตัดสวิตช์เปิด/ปิดรายบริการทิ้ง ใช้ระดับเดียวทั้งเครื่องแทน เพราะความยืดหยุ่นที่ไม่มีใครใช้จริงคือความซับซ้อนเปล่า ๆ ที่สร้างสถานะแปลก ๆ อย่าง “บางบริการเก็บ บางบริการไม่เก็บ” แล้วงงว่าทำไมหาไม่เจอ

ปัญหาที่สอง — แยกไม่ออกว่ามาจากเครื่องไหน

เมื่อมีหลายเครื่องส่งข้อผิดพลาดเข้าที่เดียวกัน ทุกอย่างจะปนกัน

ที่แย่ที่สุดคือข้อผิดพลาดจากเครื่องทดสอบ ซึ่งมีเยอะเป็นธรรมชาติเพราะเป็นที่ที่ตั้งใจไปลองของ จะกลบข้อผิดพลาดจากเครื่องจริงที่กระทบลูกค้า จนคนดูเริ่มเมินการแจ้งเตือนทั้งหมด

เราจึงเพิ่มสองอย่าง — ระบุประเภทของเครื่อง (ใช้งานจริง / ทดสอบ / พัฒนา) และชื่อเรียกของเครื่อง ที่อ่านรู้เรื่อง แทนรหัสที่ระบบปฏิบัติการตั้งให้

ปุ่มทดสอบที่ทดสอบสิ่งที่ถูกต้อง

เรามีปุ่มทดสอบส่งอยู่แล้ว แต่มันบอกได้แค่ว่า “ส่งได้” ซึ่งไม่ใช่สิ่งที่อยากรู้

สิ่งที่อยากรู้จริง ๆ คือข้อมูลที่ส่งไปถูกต้องหรือเปล่า — เพราะถ้าตั้งชื่อเครื่องหรือประเภทผิด ปุ่มทดสอบแบบเดิมจะยังผ่าน แล้วไปรู้ตัวตอนมีปัญหาจริงและหาเครื่องต้นเหตุไม่เจอ ซึ่งเป็นเวลาที่แย่ที่สุดที่จะค้นพบว่าตั้งค่าผิด

เราจึงให้ปุ่มทดสอบแนบชื่อเครื่องและประเภทไปด้วย

เคสที่สอนเรามากที่สุด — ข้อความหายวันละ 113 ฉบับ

นี่คือเคสที่แสดงว่าการ “มีระบบเฝ้าระวัง” กับ “เจอปัญหา” เป็นคนละเรื่องกัน

ขนาดของปัญหา

ข้อผิดพลาดรายการเดียวกินไป 1,021 ครั้ง คิดเป็น 88% ของข้อผิดพลาดทั้งหมดบนเครื่องใช้งานจริง

สิ่งที่เกิดขึ้นจริงคือ ข้อความแจ้งเตือนขาเข้าจากแพลตฟอร์มถูกทำเครื่องหมายว่าล้มเหลวแล้วทิ้ง วันละราว 113 ฉบับ กระจายทั้ง Shopee, Lazada และ TikTok

ข้อความเหล่านี้คือการแจ้งว่ามีออเดอร์ใหม่ ออเดอร์ถูกยกเลิก หรือสถานะเปลี่ยน — การทิ้งมันแปลว่าข้อมูลในระบบไม่ตรงกับความจริงโดยไม่มีใครรู้

ทำไมถึงไล่ไม่เจอถึง 9 วัน

ทั้งที่มันใหญ่ขนาดนี้และอยู่บนหน้าจอเฝ้าระวังมาตลอด

คำตอบคือ ชื่อของข้อผิดพลาดนั้นเดาสาเหตุไว้ผิด

ตัวป้องกันที่เขียนไว้เขียนข้อความว่า อาการนี้เกิดได้ทางเดียวคือ “กระบวนการตายกลางคัน” ซึ่งเป็นสิ่งที่หายากและไม่มีร่องรอยอื่นประกอบ

ทุกคนที่เปิดดูจึงอ่านชื่อแล้วเชื่อตาม แล้วไปตามหาสาเหตุที่ไม่มีอยู่จริง

สาเหตุจริง

มีอีกเส้นทางหนึ่งที่คนเขียนตัวป้องกันไม่ได้คิดถึง

  1. การประมวลผลข้อความล้มเหลว — ปกติ ระบบดักจับไว้แล้วเขียนสถานะสุดท้ายลงฐานข้อมูล
  2. แต่สิ่งที่ล้มเหลวคือการเชื่อมต่อฐานข้อมูลเอง
  3. การเขียนสถานะจึงล้มเหลวตามไปด้วย แล้วหลุดออกจากรอบการทำงานทั้งดุ้น
  4. ข้อความค้างอยู่ในสถานะ “กำลังประมวลผล”
  5. รอบถัดไปตัวกู้คืนดึงกลับมาลองใหม่ แล้ววนแบบนี้จนครบเพดานจำนวนครั้ง สุดท้ายถูกทิ้ง

พูดอีกอย่างคือตัวจัดการข้อผิดพลาดล้มเหลวด้วยสาเหตุเดียวกับสิ่งที่มันกำลังจัดการอยู่

บทเรียน

สองข้อที่เราเอามาใช้ต่อ

  • ข้อความในโค้ดที่ยืนยันว่า “เกิดได้ทางเดียว” อันตรายมาก — มันหยุดการคิดของคนที่มาอ่านทีหลัง เขียนว่า “น่าจะเกิดจาก” ต่างจากเขียนว่า “เกิดจาก” อย่างสิ้นเชิง
  • เส้นทางจัดการข้อผิดพลาดต้องเผื่อว่าตัวมันเองจะล้มเหลว — โดยเฉพาะเมื่อมันต้องพึ่งพาสิ่งเดียวกับที่เพิ่งพัง

เสียงรบกวนคือศัตรูของระบบเฝ้าระวัง

เคสข้างบนสอนอีกอย่าง — ปัญหาใหญ่ซ่อนตัวได้ถ้ามีเรื่องอื่นเยอะพอ เราจึงจริงจังกับการลดเสียงรบกวน

สิ่งที่ไม่ใช่ข้อผิดพลาดต้องไม่ถูกรายงาน

ตัวอย่างที่ชัดคือการหยุดงานตอนปิดระบบ — ทุกครั้งที่อัปเดตระบบ งานเบื้องหลังที่กำลังทำอยู่จะถูกสั่งหยุด ซึ่งเป็นพฤติกรรมที่ถูกต้อง แต่โค้ดเดิมรายงานมันเป็นข้อผิดพลาด

ผลคือทุกรอบการอัปเดตยิงข้อผิดพลาดปลอมเข้าระบบเฝ้าระวังฟรี ๆ เป็นชุด

ความล้มเหลวที่คาดไว้แล้วต้องลดระดับ

บางกรณีเป็นความล้มเหลวจริงแต่คาดไว้แล้วและไม่ต้องแก้อะไร เช่นผู้ใช้ทิ้งหน้าจอไว้จนหมดเวลาแล้วกลับมากด หรือยังไม่ได้เลือกบริษัทก่อนใช้งาน

เดิมกรณีเหล่านี้กลายเป็นข้อผิดพลาดระดับร้ายแรงพร้อมรายงาน เราเปลี่ยนให้ตอบเป็นข้อความภาษาไทยที่ผู้ใช้ทำต่อได้ และบันทึกเป็นระดับเตือนแทน

ผลคือหน้าจอเฝ้าระวังเหลือแต่เรื่องที่ต้องมีคนแก้จริง

ปลายทางที่จำกัดจำนวนครั้งไม่ใช่ข้อผิดพลาด

เมื่อแพลตฟอร์มบอกว่าเรียกถี่เกินไป สิ่งที่ควรทำคือรอแล้วลองใหม่ ไม่ใช่รายงานว่าพัง ส่วนกรณีที่ข้อมูลไม่ครบตามที่ปลายทางต้องการ ก็ควรบอกผู้ใช้เป็นภาษาไทยว่าขาดอะไร

ทำให้ระบบเฝ้าระวังกลายเป็นคิวงานจริง

สิ่งที่เปลี่ยนวิธีทำงานของเรามากที่สุดไม่ใช่เครื่องมือ แต่เป็นข้อตกลงข้อหนึ่ง

ทุกครั้งที่แก้บั๊กที่มาจากระบบเฝ้าระวัง ให้อ้างอิงรหัสของรายการนั้นไว้ในบันทึกการแก้ไข

ผลที่ได้มากกว่าที่คิด

  • ตอบได้ว่ารายการนี้แก้ไปหรือยัง และแก้ด้วยอะไร — ค้นย้อนกลับได้ทั้งสองทาง
  • เห็นว่ารายการเดียวถูกแก้ซ้ำหลายรอบ ซึ่งเป็นสัญญาณว่าครั้งก่อนแก้ไม่ตรงจุด
  • เห็นว่าอาการเดียวกันโผล่หลายที่ ซึ่งแปลว่าเป็นปัญหาเชิงรูปแบบ ไม่ใช่บั๊กเดี่ยว

ตัวอย่างจริงจากช่วงกลางปีที่ผ่านมา — ข้อมูลจากแพลตฟอร์มที่ไม่ครบทำให้หน้าจอพังหลายจุดในสัปดาห์เดียวกัน พอเห็นเรียงกันจึงชัดว่าปัญหาไม่ใช่แต่ละหน้า แต่คือเราเชื่อข้อมูลจากภายนอกมากเกินไปทั้งระบบ

อีกตัวอย่างคือคำนำหน้าชื่อลูกค้าบางแบบทำให้บันทึกข้อมูลไม่ได้ ซึ่งเป็นปัญหาที่ผู้ใช้อาจไม่แจ้งเพราะคิดว่าตัวเองกรอกผิด แต่ระบบเฝ้าระวังเห็น

สิ่งที่วัดได้

ประโยชน์ที่จับต้องได้ที่สุดคือเราแก้ปัญหาที่ลูกค้ายังไม่ได้แจ้ง

เคสข้อความหายวันละ 113 ฉบับไม่มีลูกค้ารายไหนแจ้งเข้ามาเลย เพราะจากมุมของเขามันไม่มีอาการ — มีแค่ออเดอร์บางรายการที่ไม่ปรากฏ ซึ่งแยกไม่ออกจากการที่ยังไม่มีออเดอร์เข้ามา

ปัญหาแบบนี้ถ้าไม่มีระบบเฝ้าระวัง จะถูกพบก็ต่อเมื่อมันสะสมจนมีคนสังเกตว่ายอดไม่ตรง ซึ่งตอนนั้นการไล่ย้อนหลังจะยากกว่ามาก

สรุป

  1. ติดตั้งระบบเฝ้าระวังเป็นแค่จุดเริ่มต้น — สิ่งที่ทำให้มันมีค่าคือการลดเสียงรบกวนจนเหลือแต่เรื่องที่ต้องแก้
  2. ชื่อของข้อผิดพลาดมีอิทธิพลต่อการไล่หาสาเหตุมาก — ชื่อที่เดาผิดทำให้ปัญหาใหญ่ซ่อนตัวได้เป็นสัปดาห์
  3. ผูกการแก้ไขกลับไปหารายการที่รายงาน — เปลี่ยนระบบเฝ้าระวังจากที่กองข้อผิดพลาด เป็นคิวงานที่ตามได้
  4. ชั้นที่จัดการข้อผิดพลาดต้องเผื่อว่าตัวเองจะล้มเหลว

สำหรับเรา ประโยคที่สรุปเรื่องนี้ได้ดีที่สุดคือ — ระบบเฝ้าระวังที่ไม่มีใครเปิดดูเพราะมันส่งเสียงตลอดเวลา มีค่าเท่ากับไม่มีเลย

Freeable

บริหารจัดการข้อมูลในองค์กร ครบในที่เดียว

ดูรายละเอียด →

อ่านต่อ

Freeable

ค่าหนึ่งค่ามี 4 หน้าที่ — มาตรฐานการแทนค่า เก็บ · ส่ง · คำนวณ · แสดง

ปัญหาเรื่องวันที่ไม่ใช่ปัญหาของวันที่ แต่เป็นหนึ่งตัวอย่างของปัญหาตระกูลเดียวกัน — ค่าหนึ่งค่าถูกใช้ทำ 4 หน้าที่ที่ต่างกัน พอรูปแบบของหน้าที่หนึ่งรั่วไปอีกหน้าที่ ตัวเลขก็เพี้ยนเงียบ ๆ

Freeable

เวลาในระบบมีหลายชั้น และมันไม่ตรงกัน — บทเรียนจากบั๊กที่ไล่ 8 วันแล้วสรุปผิดหลายรอบ

บนเครื่องจริงของเรามีเขตเวลาอยู่ 3 ชั้นและไม่ตรงกันสักคู่ ทำให้ตัวเลขที่ดูเหมือนเทียบกันได้จริง ๆ เทียบไม่ได้ บทความนี้เล่าว่าเวลาซ่อนอยู่ที่ไหนบ้าง ทำไม "วันนี้" ถึงเป็นคำที่อันตราย และงานอัตโนมัติที่ค้าง 11 วันเพราะนาฬิกาเดินล้ำหน้า

Freeable

ตั้งรหัส error อย่างไรให้ใช้งานได้จริง — รหัสสองประเภทที่ทำงานคู่กัน

ระบบส่วนใหญ่มีรหัส error ไว้ให้ผู้ใช้แจ้ง support แต่ไม่ค่อยมีใครคิดว่ารหัสควรตอบคำถามอะไร บทความนี้เล่าว่าเราแยกรหัสเป็นสองประเภทเพราะอะไร และกฎข้อเดียวที่ใช้ตัดสินว่าเมื่อไรควรตั้งรหัสใหม่