OpenTelemetry ใช้งานได้สำเร็จแล้ว แต่ทำไมมันถึงซับซ้อนขนาดนี้?
(iconsolutions.com)- OpenTelemetry (OTel) คือเฟรมเวิร์กและชุดเครื่องมือด้าน observability
- เครื่องมือเดิมที่มีอยู่ได้แก่ Prometheus (metrics), Logstash (logs), OpenTracing (distributed tracing)
- OTel ทำให้สัญญาณ 3 ประเภทคือ metrics, logs และ tracing กลายเป็นมาตรฐานเดียวกัน พร้อม提供 OpenTelemetry Protocol (OTLP), OpenTelemetry Collector และ SDK สำหรับหลายภาษา
- ตอบโจทย์คำฮิตครบทุกอย่าง ทั้งโอเพนซอร์ส, เป็นอิสระจากผู้ให้บริการ, เป็นอิสระจากภาษา, กระจายศูนย์, zero-code ฯลฯ
ปัญหาของ OTel
- logs และ metrics คล้ายกับเครื่องมือเดิม จึงผสานรวมได้ง่าย สามารถย้ายมาใช้ OTel ได้เพียงเพิ่มการตั้งค่า
- ความยากอยู่ที่การทำ tracing
- Context Propagation: จำเป็นสำหรับการส่งต่อข้อมูลคำขอระหว่างระบบแบบกระจาย
- แบ่งหน่วยของคำขอเป็น Trace และ Span
- ตัวอย่าง: คลิกปุ่ม "ซื้อ" → Frontend → Backend → ความสัมพันธ์ระหว่างบริการ Payment/Shipping ถูกแสดงเป็น Span
- วิธีที่ OTel รองรับ:
- มีมาตรฐาน Context Propagation หลายแบบให้ใช้ (เช่น b3, W3C Trace Context)
- OTel จำเป็นต้องรองรับหลายมาตรฐาน
- เมื่อย้ายจาก OpenTracing เดิมมาเป็น OTel อาจเกิดการชนกันที่คาดไม่ถึง
- Lightbend Telemetry รองรับ logs และ metrics ของ OpenTelemetry แต่ไม่รองรับ tracing
- Context Propagation: จำเป็นสำหรับการส่งต่อข้อมูลคำขอระหว่างระบบแบบกระจาย
ปัญหาการชนกันระหว่าง API
ปัญหาการผสานรวมระหว่าง Spring และ Akka
- Spring: ใช้สำหรับการบูตสแตรปแอปพลิเคชันและจัดการคอนฟิก
- Akka: ใช้สำหรับ event sourcing, scheduling, clustering เป็นต้น
- ปัญหา:
- เมื่อใช้ OTel, tracing API ของ Spring และ Akka ไม่ทำงานร่วมกัน
- ไม่สามารถแชร์ Trace ID เดียวกันได้ → ทำให้ผลการ tracing ผิดพลาด
วิธีแก้: OpenTracing Shim
- เครื่องมือสำหรับแปลง OTel Tracer ให้เป็น OpenTracing Tracer
- ปัญหา:
- Lightbend Telemetry ของ Akka ไม่สอดคล้องกับ implementation ของ OpenTracing
- Jaeger และ OTel ต้องการ SpanContext คนละแบบ จึงเกิดการชนกัน
กระบวนการแก้ปัญหา
การผสานรวม OTel และ OpenTracing แบบแมนนวล
- แปลง OTel Context เป็น Jaeger SpanContext ด้วยตนเอง:
- ใส่ OTel context ลงใน Java Map
- ดึงแมปนั้นออกมาเป็น Jaeger SpanContext แล้วตั้งค่าด้วยตนเอง
- ตัวอย่างโค้ด:
var otelContext = new HashMap<>(); GlobalOpenTelemetry.get().getPropagators().getTextMapPropagator() .inject(Context.current(), otelContext, (carrier, key, value) -> carrier.put(key, value)); var openTracingContext = new TextMapCodec(false).extract(new TextMapAdapter(otelContext)); GlobalExtendedTracer.get().local().activateContext(openTracingContext); - ผลลัพธ์:
- ผสานรวมข้อมูล tracing ระหว่าง Spring และ Akka ได้สำเร็จ
- Trace เชื่อมต่อกันได้ถูกต้องข้ามขอบเขต HTTP
บทสรุป
สาเหตุของความซับซ้อน
- ความพยายามในการผสานรวมไลบรารี tracing ที่ต่างกันสองตัว
- มาตรฐานที่ OpenTelemetry มีให้ใช้นั้นมีประโยชน์ แต่ก็อาจชนกับเครื่องมือเดิมได้
คุณค่าของ OpenTelemetry
- OpenTelemetry มีบทบาทสำคัญต่อการทำมาตรฐานด้าน observability
- เป็นโปรเจกต์โอเพนซอร์สที่ซับซ้อนแต่ทรงพลัง
งานที่ต้องทำต่อไป
- ต้องตรวจสอบว่า Trace Context ของ Akka ถูกส่งต่ออย่างถูกต้องระหว่างเธรดหรือไม่
- จำเป็นต้องมีการทดสอบและรับฟีดแบ็กเพิ่มเติมเพื่อปรับปรุงโปรเจกต์
1 ความคิดเห็น
ความเห็นจาก Hacker News
ระหว่างเรียนรู้และพอร์ต Otel รู้สึกเหมือนได้กลับไปอยู่ในโลกของ Java อีกครั้ง ตอนสำรวจโค้ดให้ความรู้สึกแบบ EnterpriseFizzBuzz และแทบไม่มี discoverability เลย บน NodeJS ใช้ CPU มากกว่า StatsD ราว 4 เท่า และลดลงได้ด้วยการทำ aggregate เอง OTEL ไม่เป็นมิตรกับภาษาที่ใช้หนึ่งโปรเซสต่อหนึ่งคอร์ ควรใช้ Prometheus มากกว่า
Otel อาจทำให้รู้สึกซับซ้อนเพราะมี SDK, เอเจนต์ และ API จากผู้ให้บริการ observability หลายราย ตอนนี้ OpenTelemetry กลายเป็นมาตรฐานไปแล้ว และขอชื่นชมที่ Grafana รองรับ OpenTelemetry ราคาของ Datadog พุ่งจนควบคุมไม่ได้สำหรับบริษัทขนาดกลางไปจนถึงองค์กรใหญ่ เอกสารยังปรับปรุงได้อีก และเอกสาร onboarding ก็แตกต่างกันไปตามภาษาโปรแกรม ได้ทำแพ็กเกจและตัวอย่าง Grafana stack สำหรับเริ่มต้น OpenTelemetry บนสแตก NodeJS/Typescript ได้อย่างรวดเร็ว
ต้องการให้รองรับ log, trace และ metric ในการพัฒนาแบบโลคัล แต่ไม่อยากรัน Docker image หลายตัว ทีม .NET ได้ออก .NET Aspire มา ซึ่งช่วยให้มองเห็นทุกอย่างใน local development stack ได้ง่าย เวลา deploy ไปที่ k8s ก็แค่ชี้ OTEL endpoint ไปที่ DataDog agent ทุกอย่างก็ทำงานได้ ใช้ OTEL เพื่อหลีกเลี่ยง tracing library และ SDK แบบเฉพาะของ DataDog
OpenTelemetry อาจซับซ้อนมากหรือน้อยตามสิ่งที่ต้องการ ทีมของเราใช้อย่างเรียบง่าย โดยใช้ manual instrumentation เพื่อเลือกอย่างระมัดระวังว่าจะสังเกตอะไรบ้าง ใช้สองแบ็กเอนด์ โดยตัวหนึ่งเป็นบริการ third-party ราคาถูก และอีกตัวเป็นการติดตั้ง Jaeger สำหรับการพัฒนาแบบโลคัล
ถ้าใช้ Otel บน Python แนะนำให้ใช้ไคลเอนต์ของ Logfire ไคลเอนต์ที่ทีม Pydantic ทำมาดีกว่าและง่ายกว่าไลบรารี Otel ทางการมาก
เว็บเฟรมเวิร์กหลายตัวจัดการ instrumentation ส่วนใหญ่ให้อัตโนมัติอยู่แล้ว ใช้ opentelemetry-js และโฮสต์เองด้วยอะไรอย่าง Signoz ก็เก็บข้อมูลได้มากภายในเวลาไม่ถึงชั่วโมง
ได้เริ่มโปรเจกต์โอเพนซอร์สที่รันได้ด้วยคำสั่งเดียว เพื่อให้การนำ OpenTelemetry ไปใช้ทำได้ง่ายขึ้น
ถ้าใช้สแตกมาตรฐานบน Python ก็สามารถติดตามทุกอย่างได้อัตโนมัติด้วย import เพียงไม่กี่ตัว Otel ซับซ้อนเพราะมันถูกออกแบบมาสำหรับบริษัทที่ขายซอฟต์แวร์ซึ่งรองรับ Otel
OpenTelemetry เริ่มจาก tracing แต่สำหรับ metric และ log นั้นควรปล่อยให้โซลูชันเฉพาะทางจัดการจะดีกว่า ความพยายามที่จะเอาทุกอย่างมาไว้ใต้ร่มเดียวกันให้ความรู้สึกเหมือนปัญหา "leaky abstraction" ฐานข้อมูล SQL ก็ทำได้หลายอย่างพร้อมกันเหมือนกัน แต่ไม่ได้แปลว่าควรทำแบบนั้น