37 คะแนน โดย GN⁺ 2025-12-22 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในระบบแบบกระจายสมัยใหม่ แนวทางล็อกแบบเดิมมีข้อจำกัดเชิงโครงสร้างที่ทำให้ไม่สามารถถ่ายทอดความจริงได้
  • ล็อกยังคงถูกออกแบบโดยยึดสมมติฐานของ สภาพแวดล้อมเซิร์ฟเวอร์เดี่ยวแบบปี 2005 ทำให้สูญเสียคอนเท็กซ์ของคำขอที่ต้องผ่านหลายบริการ ฐานข้อมูล และแคช
  • การค้นหาด้วยสตริงอย่างเดียวไม่เข้าใจ โครงสร้าง ความสัมพันธ์ และความเชื่อมโยง จึงทำให้หาสาเหตุของปัญหาได้ยาก
  • ทางแก้คือการบันทึก 'Wide Event' เดี่ยว (หรือ Canonical Log Line) ที่เก็บ ทุกคอนเท็กซ์ ของแต่ละคำขอ
  • วิธีนี้ทำให้ล็อกจากข้อความธรรมดาเปลี่ยนเป็น ทรัพย์สินข้อมูลที่วิเคราะห์ได้

ปัญหาพื้นฐานของการทำล็อก

  • ล็อกแบบเดิมถูกสร้างขึ้นโดยอิงกับ ยุคเซิร์ฟเวอร์โมโนลิธิก จึงไม่สามารถสะท้อน สถาปัตยกรรมบริการแบบกระจาย ในปัจจุบันได้
    • คำขอหนึ่งครั้งอาจผ่านหลายบริการ DB แคช และคิว แต่ล็อกก็ยังถูกบันทึกโดยยึดเกณฑ์ของเซิร์ฟเวอร์เดี่ยว
  • ในตัวอย่างล็อก มีการสร้าง 13 บรรทัดต่อ 1 คำขอ ทำให้เมื่อมี ผู้ใช้พร้อมกัน 10,000 คน จะมี 130,000 บรรทัดต่อวินาที แต่ข้อมูลส่วนใหญ่แทบไม่มีความหมาย
  • สิ่งที่ต้องการเมื่อเกิดปัญหาคือ คอนเท็กซ์ (context) แต่ล็อกปัจจุบันกลับขาดสิ่งนี้

ข้อจำกัดของการค้นหาด้วยสตริง

  • เมื่อผู้ใช้รายงานว่า “ชำระเงินไม่ได้” ต่อให้ค้นหาล็อกด้วยอีเมลหรือ user_id ก็ยากจะได้ผลลัพธ์ที่ใช้งานได้ เพราะ ไม่มีโครงสร้างที่สม่ำเสมอ
    • user ID เดียวกันอาจถูกบันทึกในรูปแบบ นับสิบแบบ เช่น user-123, user_id=user-123, {"userId":"user-123"}
  • รูปแบบล็อกระหว่างบริการต่างกัน ทำให้ ติดตามเหตุการณ์ที่เกี่ยวข้องกันข้ามบริการไม่ได้
  • ปัญหาสำคัญคือ ล็อกถูกออกแบบโดยเน้นฝั่ง การเขียน (write) และไม่ได้ปรับให้เหมาะกับ การค้นหา/คิวรี (query)

คำจำกัดความของแนวคิดหลัก

  • Structured Logging: วิธีบันทึกในรูปแบบ คีย์-ค่า (JSON) แทนสตริง
  • Cardinality: จำนวนค่าที่ไม่ซ้ำกันของฟิลด์ เช่น user_id จะมีค่าสูงมาก
  • Dimensionality: จำนวนฟิลด์ภายในเหตุการณ์ล็อก ยิ่งมากก็ยิ่งมีศักยภาพในการวิเคราะห์สูง
  • Wide Event / Canonical Log Line: เหตุการณ์ล็อกเดี่ยวที่มีคอนเท็กซ์ครบถ้วน ต่อหนึ่งคำขอ
  • ระบบล็อกส่วนใหญ่มัก จำกัดข้อมูลที่มี cardinality สูงเพราะปัญหาต้นทุน แต่ในความเป็นจริง ข้อมูลแบบนี้กลับมีประโยชน์ที่สุดต่อการดีบัก

ข้อจำกัดของ OpenTelemetry

  • OpenTelemetry(OTel) คือ ชุดโปรโตคอลและ SDK ที่ให้เพียงมาตรฐานสำหรับการเก็บรวบรวมและส่งข้อมูล
  • แต่ OTel ไม่ได้ทำสิ่งต่อไปนี้
    1. ไม่ได้ตัดสินใจว่าจะล็อกอะไร
    2. ไม่ได้เพิ่มคอนเท็กซ์ทางธุรกิจโดยอัตโนมัติ (เช่น ระดับสมาชิก ยอดในตะกร้า ฯลฯ)
    3. ไม่ได้เปลี่ยน วิธีคิดเรื่องการทำล็อก ของนักพัฒนา
  • แม้จะใช้ไลบรารีเดียวกัน แต่ประสบการณ์การดีบักระหว่างการทำ instrumentation ที่ ตั้งใจเพิ่มคอนเท็กซ์ กับการทำแบบพื้นฐานนั้นแตกต่างกันอย่างชัดเจน
  • OTel เป็นเพียง ท่อส่งข้อมูล (plumbing) และ นักพัฒนาต้องเป็นผู้ตัดสินใจเองว่าจะส่งอะไรผ่านท่อนั้น

แนวทาง Wide Event / Canonical Log Line

  • ต้องเลิกทำล็อกแบบที่เน้นว่า “โค้ดกำลังทำอะไร” แล้วหันมาบันทึกว่า “เกิดอะไรขึ้นกับคำขอนี้
  • สำหรับแต่ละคำขอ ให้สร้าง เหตุการณ์แบบกว้างหนึ่งรายการ ในระดับบริการ
    • สามารถมีฟิลด์ได้มากกว่า 50 ฟิลด์ เช่น คำขอ ผู้ใช้ การชำระเงิน ข้อผิดพลาด และสภาพแวดล้อม
  • ตัวอย่าง JSON มี คอนเท็กซ์สำหรับการดีบักทั้งหมด เช่น user_id, subscription_tier, service_version, error_code
  • ทำให้สามารถค้นหาเพียงครั้งเดียวเพื่อ วิเคราะห์ได้ทันที เช่น “สาเหตุของความล้มเหลวในการชำระเงินของผู้ใช้พรีเมียม”

การใช้คิวรีกับ Wide Event

  • Wide Event ไม่ได้ถูกใช้ผ่านการค้นหาข้อความธรรมดา แต่ใช้เป็น การคิวรีข้อมูลแบบมีโครงสร้าง
  • ด้วยข้อมูลที่มี cardinality สูงและหลายมิติ จึงสามารถดีบักได้ในระดับ การวิเคราะห์แบบเรียลไทม์
  • ตัวอย่างเช่น สามารถรันคิวรีได้ทันทีอย่าง “สรุปอัตราความล้มเหลวของการชำระเงินของผู้ใช้พรีเมียมในช่วง 1 ชั่วโมงที่ผ่านมา แยกตาม error code”

รูปแบบการนำไปใช้

  • สร้างเหตุการณ์ตลอดทั้งวงจรชีวิตของคำขอ และ แสดงผลเพียงครั้งเดียวในตอนท้าย
    • กำหนดค่าเริ่มต้นของฟิลด์พื้นฐานใน middleware เช่น request_id, timestamp, method, path
    • ค่อย ๆ เพิ่มข้อมูลผู้ใช้ ตะกร้า การชำระเงิน และข้อผิดพลาดจากใน handler
  • สุดท้ายบันทึกเหตุการณ์ JSON เดี่ยวด้วย logger.info(event)

ควบคุมต้นทุนด้วยการทำ Sampling

  • หากบันทึกมากกว่า 50 ฟิลด์ต่อคำขอ ต้นทุนจะพุ่งสูง จึงจำเป็นต้องมี sampling
  • การสุ่มตัวอย่างแบบสุ่มธรรมดาอาจทำให้พลาดข้อผิดพลาดสำคัญได้
  • มีการเสนอแนวทาง Tail Sampling
    1. เก็บข้อผิดพลาด (เช่น 500) ไว้เสมอ
    2. เก็บคำขอที่ช้า (p99 ขึ้นไป) ไว้เสมอ
    3. เก็บผู้ใช้ VIP หรือเซสชันที่มีแฟล็กเฉพาะไว้เสมอ
    4. ส่วนที่เหลือสุ่มเก็บเพียง 1~5%
  • วิธีนี้ช่วยให้ ลดต้นทุนและรักษาเหตุการณ์สำคัญไว้ได้พร้อมกัน

สรุปความเข้าใจผิดที่พบบ่อย

  • Structured Logging ≠ Wide Event: แค่ใช้ฟอร์แมต JSON ยังไม่พอ คอนเท็กซ์คือหัวใจสำคัญ
  • ใช้ OpenTelemetry ≠ มี observability ครบถ้วน: มันเพียงทำให้การเก็บรวบรวมเป็นมาตรฐาน แต่ จะบันทึกอะไรยังเป็นหน้าที่ของนักพัฒนา
  • ไม่ใช่สิ่งเดียวกับ Tracing: tracing แสดงการไหลระหว่างบริการ ส่วน Wide Event ให้ คอนเท็กซ์ภายในบริการ
  • การแบ่งว่า ล็อกมีไว้ดีบัก ส่วนเมตริกมีไว้ทำแดชบอร์ด นั้นไม่จำเป็น — Wide Event ตอบโจทย์ได้ทั้งสองแบบ
  • ความเชื่อที่ว่า ข้อมูล cardinality สูงมีราคาแพง นั้นล้าสมัยแล้ว เพราะ ClickHouse, BigQuery และฐานข้อมูลสมัยใหม่ จัดการเรื่องนี้ได้อย่างมีประสิทธิภาพ

ผลลัพธ์ของการนำ Wide Event มาใช้

  • การดีบักเปลี่ยนจาก การขุดค้น (archaeology) ไปเป็น การวิเคราะห์ (analytics)
  • จากเดิมที่ต้องใช้ grep กับล็อกของ 50 บริการเพื่อหาว่า “ผู้ใช้ชำระเงินล้มเหลว”
    มาเป็นการวิเคราะห์แบบ คิวรีเดียว ว่า “อัตราความล้มเหลวของการชำระเงินของผู้ใช้พรีเมียมแยกตาม error code”
  • ผลลัพธ์คือ ล็อกเปลี่ยนจาก เครื่องมือที่พูดโกหก ไปเป็น ทรัพย์สินข้อมูลที่บอกความจริง

1 ความคิดเห็น

 
GN⁺ 2025-12-22
ความเห็นจาก Hacker News
  • บทความอ่านยากและให้ความรู้สึกว่า เหมือนมี AI ช่วยเขียน ถึงอย่างนั้นสาระก็ยังมีคุณค่า และน่าจะดีกว่านี้ถ้ากระชับกว่านี้
    สิ่งที่ฉันคิดไว้ล่าสุดมีดังนี้

    • เนื่องจากมีการยืนยันตัวตนอยู่ทั่วทั้งสแตก จึงเริ่มใส่ user id ลงในทุกบรรทัดของล็อก ทำให้มองภาพรวมประสบการณ์ที่ผู้ใช้เจอได้ง่ายขึ้น
    • การบันทึก error แยกเป็นอีกบรรทัดจาก request log นั้นยุ่งยาก แม้จะกรองด้วย trace ได้ แต่ก็ยากที่จะเขียนคิวรีแบบ “แสดงเฉพาะ error ที่เกี่ยวข้องกับคำขอ 5xx”
    • การเพิ่มคอนเท็กซ์แบบนี้อย่างเดียวไม่พอ ต้อง สอน เพื่อนร่วมทีมด้วยว่ามีฟิลด์ใหม่เพิ่มเข้ามา ไม่อย่างนั้นหลายคนจะลำบากเองเพราะไม่รู้
    • ถ้าลงทุนกับ เครื่องมือ tracing ที่ดีกว่า ก็จะดีบักได้ในระดับที่ล็อกธรรมดาทำไม่ได้ ถือเป็นการขยายแนวคิดการใช้ user id เป็น trace
    • ถ้าในโค้ดเบสมีแนวคิดเรื่อง request ID อยู่แล้ว ก็ใช้สิ่งนั้นติดตามพฤติกรรมของผู้ใช้ได้ละเอียดขึ้น
    • ถ้าบังคับใช้ TID ทั่วทั้งบริการ ไม่ว่าทีมไหนก็จะติดตามทรานแซ็กชันทั้งหมดได้ด้วย TID ตัวเดียว
    • คอมเมนต์ทำนองว่า “มีกลิ่น AI” แบบนี้ อีกไม่นานน่าจะกลายเป็น วัฒนธรรมที่ถูกวิจารณ์
  • สำหรับหัวข้อนี้จะไม่พูดถึง Charity Majors ก็คงไม่ได้ เธอเผยแพร่แนวคิด “wide events” และ “observability” มานานกว่าสิบปี และสร้าง Honeycomb.io ขึ้นบนปรัชญานั้น
    ทุกวันนี้มีเครื่องมือหลายแบบที่ทำแนวทางนี้ได้ สิ่งสำคัญคือใช้ structured logs หรือ traces เพื่อเก็บ wide event และใช้เครื่องมือที่มีการแสดงผลอย่าง time series, histogram ฯลฯ อย่างครบถ้วน

    • แต่คำว่า “observability” เองนั้นไม่ใช่คำที่เธอเป็นคนคิด มันเป็นแนวคิดที่ใช้กันมาหลายสิบปีแล้วในหลายสาขา เธอเป็นผู้ปฏิบัติงานที่ทรงอิทธิพล แต่ไม่ใช่ผู้ให้กำเนิดคำนี้
    • บล็อกของเธอและเรื่องราวเบื้องหลัง Honeycomb เป็นสิ่งที่คนในวงการควรหาอ่าน เป็นหนึ่งในทีมแรก ๆ ที่มองเห็นคุณค่าของแนวทางนี้
    • บทความนี้คล้ายสไตล์ของเธอมาก จนฉันนึกว่าท้ายบทจะมีโฆษณา Honeycomb แต่กลับไม่มี เลยค่อนข้างแปลกใจ
    • ในระบบนิเวศ .NET นั้น Nick Blumhardt พูดถึง structured logging มานานแล้ว และ Seq กับ Serilog ก็รองรับสิ่งนี้
    • คอนเทนต์ของเธอดีมาก แต่ไม่มีใครเป็นเจ้าของแบรนด์คำว่า “observability” ควรให้ความเคารพแต่ไม่ควรกล่าวเกินจริง
  • ฉันเห็นด้วยกับข้ออ้างบางส่วนของบทความ แต่แนวทางที่เก็บแค่ wide event เดียว มีจุดอันตรายอยู่ ถ้ามี exception หรือ timeout เกิดขึ้นกลางคำขอ ก็อาจไม่เหลืออะไรเลย
    ล็อกจากเฟรมเวิร์กพื้นฐานของภาษา หรือจาก dependency ต่าง ๆ ก็อาจหายไปด้วย
    เพราะฉะนั้นควรใช้สิ่งนี้เป็น เลเยอร์เสริม ที่วางทับบนล็อกเดิมมากกว่า โดยมี ID ระดับ request/session แล้วค่อย aggregate ใน ClickHouse หรือที่คล้ายกัน

    • ถ้าปัญหาคือมองไม่เห็นสิ่งที่เกิดขึ้นในชั้นกลาง แปลว่า event นั้น ยัง wide ไม่พอ ไม่ว่าจะเป็น log.error(data) หรือ wide_event.attach(error, data) แก่นแท้ก็เหมือนกัน
    • ล็อกอย่าง “connection X:Y accepted at Z ns” และ “closed at Z ns” มีประโยชน์มากในการดีบักระบบที่ช้า
    • ฉันแก้ปัญหานี้ใน PHP framework โดยสร้าง LoggerInterface ขึ้นมา จับ exception ด้วย global handler แล้วเก็บลง DB ในรูปแบบ wide มี boilerplate อยู่บ้าง แต่ทำงานดีมากจนตอนนี้ถ้าไม่มีจะรู้สึกขาดไป
  • พรีเซนเทชันและ ตัวอย่างแบบโต้ตอบได้ ทำได้ยอดเยี่ยม แต่สุดท้ายแล้วก็สรุปได้ว่า “เพิ่มแท็กที่มีโครงสร้างลงในล็อก”
    ฉันรู้สึกว่า wide log ให้ประโยชน์ไม่มากเมื่อเทียบกับความซับซ้อนและ ความอ่านยากที่เพิ่มขึ้น
    แค่ grep \"uid=user-123\" application.log ก็มักพอแล้ว จะต้องใส่ถึงวิธีจัดส่งของผู้ใช้ลงไปด้วยจริงหรือ
    (อนึ่ง ในเบราว์เซอร์ Brave บน Android checkbox ใช้งานไม่ได้)

    • ถ้าเป็น JSON log ก็ยังค้นหาด้วย grep '\"uid\": \"user-123\"' ได้อยู่ และใช้ตัวเลือก --context เพื่อดูบรรทัดรอบ ๆ ได้
  • ฉันเคยทำงานในสภาพแวดล้อมการผลิตเซมิคอนดักเตอร์ที่มี ผู้เข้าร่วมใน message bus หลายพันตัว ระบบสร้างล็อก 300~400MB ต่อชั่วโมง แต่ก็ยัง จัดการได้สบายด้วย grep และเครื่องมือ CLI เท่านั้น
    ล็อกเป็นเพียงลำดับเหตุการณ์ตามเวลา ส่วนการวิเคราะห์เชิงรายละเอียดใช้ Oracle query จัดการ ล็อกคือเครื่องมือสำหรับทำความเข้าใจความเป็นเหตุเป็นผลของเหตุการณ์

    • ล็อกมีไว้เพื่อ ทำความเข้าใจไทม์ไลน์ ไม่ใช่เพื่อใส่ข้อมูลทั้งหมดของ request/response ถ้าใส่ข้อมูลมากเกินไปกลับจะยิ่งเข้าใจยาก
      ล็อกบอกว่า “เมื่อไร มีอะไรเกิดขึ้น” ส่วน “ทำไม” ต้องหาเอาจากการผสมกันของโค้ด ข้อมูล และเหตุการณ์
      สำหรับฉัน อินเทอร์เฟซอย่าง ELK stack ไม่ค่อยเหมาะกับการสำรวจแบบสัญชาตญาณ ล็อกควรถูกอ่านแบบไล่ตามด้วยความรู้สึกได้
    • ล็อก 400MB ต่อชั่วโมงจริง ๆ แล้วไม่ได้มากนัก ดังนั้น grep ธรรมดาก็รับมือได้สบาย
  • คำแนะนำช่วงท้ายบทความที่ว่า “ให้ล็อกทุก error, exception และ slow request” เป็นแนวคิดที่ อันตราย
    ตัวอย่างเช่น ถ้า dependency ช้าลง ปริมาณล็อกอาจพุ่งขึ้น 100 เท่า
    ในช่วงเกิดเหตุขัดข้อง ระบบควรทำงานให้น้อยลงเพื่อฟื้นตัวได้ง่ายขึ้น แต่ล็อกที่พุ่งสูงกลับอาจทำให้เกิด ความล้มเหลวต่อเนื่อง

    • ที่ Cloudflare ใช้ adaptive sampling โดยแบ่ง batch ของล็อกเป็น bucket ตามฟิลด์ แล้วเก็บไว้เพียงค่ารากที่สองหรือค่าลอการิทึมของจำนวนล็อกที่เข้ามาในแต่ละ bucket
      ยิ่งล็อกเยอะ อัตราการ sampling ก็จะถูกปรับอัตโนมัติเพื่อไม่ให้ระบบโอเวอร์โหลด
    • ค่า threshold แบบเวทมนตร์ พวกนี้อันตราย ค่าจำพวก P(99) ควรถูกอัปเดตแบบไดนามิก ถ้าให้ OTEL provider ดึงค่าจริงมาเป็นระยะจะปลอดภัยกว่า
    • บริการ production ควรถูกออกแบบให้การเก็บล็อก ขยายตัวตามความต้องการ ได้ แม้แค่มี local disk buffering ก็ช่วยได้มาก
    • ถ้าเป็นบริการทราฟฟิกสูง ก็สามารถ สุ่มเฉพาะคำขอที่ปกติ ด้วยวิธีอย่าง trace_id mod 100 == 0
    • ถ้าล็อกกลายเป็นคอขวด แปลว่าการออกแบบระบบมีปัญหา การทำล็อกอย่างมีประสิทธิภาพรองรับได้ถึง หลายร้อยล้านรายการต่อวินาที
  • ในซอฟต์แวร์สมัยใหม่ การจะอธิบายว่า “เกิดอะไรขึ้น” ให้ครบด้วยล็อกเพียงตัวเดียวนั้นทำได้ยาก
    ดังนั้นจึงต้องมีทั้ง Vertical correlation และ Horizontal correlation
    ระหว่างชั้นบนล่างในสแตกควรแชร์ค่า correlation เดียวกัน และเมื่อระบบสื่อสารกันก็ควรมี correlation ระหว่าง peer ด้วย
    การเพิ่มค่าพวกนี้เข้าไปใน API หรือโปรโตคอลนั้นทำได้ยาก แต่ถ้าออกแบบ transaction ID ไว้ล่วงหน้า ก็จะติดตามทั้งระบบได้

  • ฉันคิดว่าการ จดโดเมนแยกสำหรับบทความเดียว นั้นไม่ค่อยยั่งยืน
    เพราะต้องจ่ายค่าต่ออายุทุกปี ใช้บล็อกส่วนตัวหรือ subdomain น่าจะดีกว่า
    ตัวอย่างเช่น logging-sucks.boristane.com ในรูปแบบนี้น่าจะเหมาะกว่า

    • ที่จริงโดเมนนี้กับบทความนี้มีไว้ โปรโมต observability SaaS ของผู้เขียน ต้องมีบัญชี Cloudflare แต่ใช้ฟรีได้ จึงดูเป็นกลยุทธ์การตลาดระยะยาว ถึงอย่างนั้นก็ยังมีประโยชน์ และฉันก็มีบัญชี CF อยู่แล้วเลยคิดว่าจะลองใช้ดู
    • บทความนี้อยู่ในบริบทคล้ายกับ Simon Willison's “Give people something to link to”
    • สิ่งนี้ใกล้เคียงกับ หน้า lead generation สำหรับการตลาดดิจิทัล มากกว่าจะเป็นบล็อกโพสต์ และชัดเจนว่าโปรโมตบริการอยู่
  • สำหรับคำกล่าวที่ว่า “ล็อกเป็นของเหลือจากยุค monolithic” ฉันคิดว่า ล็อกในเครื่องยังคงมีประโยชน์
    หน้าที่ดั้งเดิมของมันคือบันทึกบทสนทนาภายใน local process และถ้าจะเข้าใจสถานการณ์ของเซิร์ฟเวอร์อื่นก็ต้องใช้ transaction tracing
    แค่ดูล็อกในตำแหน่งที่เหมาะสมก็มักไปถึงต้นตอของปัญหาได้

    • แต่ล็อกไม่ได้มีไว้แค่วิเคราะห์สาเหตุเท่านั้น มันยังให้ข้อมูลเชิงธุรกิจ เช่น ใครได้รับผลกระทบ, ความสัมพันธ์ระหว่างประสิทธิภาพกับอินพุต, ผลกระทบของช่องโหว่ด้านความปลอดภัย ฯลฯ
      ล็อกที่มีคอนเท็กซ์สมบูรณ์ เมื่อจับคู่กับเอนจินวิเคราะห์ ก็สามารถนำไปใช้ปรับปรุงผลิตภัณฑ์ได้
    • เมื่อมีคนพูดว่า “คำขอหนึ่งผ่าน 15 บริการกับ 3 ฐานข้อมูล” ก็มีคนตอบกลับว่าควรหลีกเลี่ยงความซับซ้อนแบบนั้นแต่แรก
    • ฉันรู้สึกว่าแค่ APN/Kibana ก็เพียงพอสำหรับการวิเคราะห์ล็อกแล้ว
  • ฉันเห็นด้วยกับประโยคที่ว่า “อย่าล็อกสิ่งที่โค้ดทำ แต่ให้ล็อกว่าสิ่งใดเกิดขึ้นกับคำขอ” แต่ผู้เขียนดูเหมือนยังมีประสบการณ์ไม่มาก
    ฉันเรียกสิ่งนี้ว่า “bug parts logging” และคิดว่าควรใส่ สัญญาณล่วงหน้า อย่างเส้นทางการประมวลผล จำนวนครั้ง และเวลาไว้ด้วย
    ล็อกไม่เหมือน metric หรือ audit ถ้าล็อกล้มเหลว การประมวลผลควรดำเนินต่อได้ แต่ถ้า audit ล้มเหลวถือว่าร้ายแรง
    เหมือนแนวคิด “historian” ในระบบ SCADA เราควรแยก สิ่งที่สังเกตได้ (observables) ออกจาก สิ่งที่ใช้ประเมิน (evaluatives)
    ตัวอย่างเช่น event ละเอียดจากเซ็นเซอร์เชื้อเพลิงมีประโยชน์ต่อการวินิจฉัย แต่ไม่จำเป็นต่อคำถามว่า “ไปถึงจุดหมายได้ไหม”
    ท้ายที่สุดสิ่งสำคัญคือการทำให้ชัดว่า จะสังเกตอะไร และจะประเมินอะไร

    • ฉันสนับสนุน “ทฤษฎีรวมของ observability” ล็อก เมตริก และ audit ล้วนเป็นเพียง bit stream และแปลงกันได้โดยไม่สูญเสีย
      แม้วิธีจัดเก็บ แปลง และสืบค้นจะแตกต่างกัน แต่ก็สามารถออกแบบ จุดใช้งานและกลไก ให้เหมือนกันได้
      แบบนี้จะทำให้การออกแบบระบบง่ายขึ้น และยังสามารถนำล็อกที่เก็บระยะยาวกลับมาประมวลผลใหม่ในภายหลังได้