ตัวอย่างการใช้งาน OpenTelemetry กับ Node.js Express Application แบบต่างๆ
OpenTelemetry รองรับ 3 signals หลัก:
| Signal | Description | Example Use Case |
|---|---|---|
| 📝 Traces | ติดตาม request flow ผ่าน services | วิเคราะห์ latency ของแต่ละ operation |
| 📈 Metrics | วัดและ aggregate ค่าต่างๆ | Monitor request rate, error rate, duration |
| 🗒️ Logs | บันทึกเหตุการณ์และข้อความ | ดู error messages, user actions |
ตัวอย่างนี้รองรับครบทั้ง 3 signals!
- ติดตาม Express และ HTTP requests อัตโนมัติ
- Setup รวดเร็ว ใช้โค้ดน้อย
- เหมาะสำหรับ quick start และ production
- รองรับ: Traces + Metrics + Logs
- Port:
3001
- ควบคุมการสร้าง span ได้อย่างละเอียด
- เหมาะสำหรับ custom business logic
- เรียนรู้การทำงานของ OpenTelemetry อย่างลึกซึ้ง
- รองรับ: Traces + Metrics + Logs
- Port:
3002
- Trace requests ข้ามหลาย microservices (A → B → C)
- แสดงทั้ง Auto และ Manual context propagation
- เหมาะสำหรับเรียนรู้ microservices tracing
- รองรับ: Traces + Metrics + Logs
- Ports:
3010-3012(Auto),3020-3022(Manual)
- เอกสารครบถ้วนเกี่ยวกับ OpenTelemetry Logs
- วิธีใช้งาน LoggerProvider และ Logger
- Best practices สำหรับ structured logging
- การเชื่อมโยง Logs กับ Traces
- Node.js 16+
- Docker และ Docker Compose
- npm หรือ yarn
หน่วง: แต่ละตัวอย่างมี config files และ observability stack ของตัวเองแล้ว!
แต่ละตัวอย่างสามารถรันได้เองโดยไม่ต้องพึ่ง example หลัก
Auto-Instrumentation (Standalone):
cd auto-instrumentation
docker-compose up --build
# เข้าถึงได้ที่ http://localhost:3001Manual-Instrumentation (Standalone):
cd manual-instrumentation
docker-compose up --build
# เข้าถึงได้ที่ http://localhost:3002Distributed-Tracing (Standalone):
cd distributed-tracing
docker-compose up --build
# Auto services: 3010-3012
# Manual services: 3020-3022ถ้าต้องการรันหลายตัวอย่างพร้อมกัน และใช้ stack เดียวกัน:
- เริ่ม Observability Stack (Collector, Jaeger, Prometheus, Grafana, Loki):
# ใน example/
docker-compose up -d- รัน App ด้วย npm:
# Auto-Instrumentation
cd auto-instrumentation
npm install && npm start
# Manual-Instrumentation (Terminal ใหม่)
cd manual-instrumentation
npm install && npm startข้อดี:
- ✅ ใช้ Observability Stack เดียว (ประหยัด resources)
- ✅ เปลี่ยนโค้ดและ restart ง่าย
- ✅ เห็น console logs ชัดเจน
- ✅ เหมาะสำหรับ development
# Terminal 1: Observability Stack
docker-compose up -d
# Terminal 2: Auto-Instrumentation
cd auto-instrumentation && npm start
# Terminal 3: Manual-Instrumentation
cd manual-instrumentation && npm start
# Terminal 4: Distributed Tracing
cd distributed-tracing && docker-compose up --build# หยุด Observability Stack
docker-compose down
# หยุด specific example
cd auto-instrumentation
docker-compose downdocker-compose up --build
## 🧪 ทดสอบ API
### Auto-Instrumentation Example (Port 3001)
```bash
# ทดสอบ endpoint หลัก
curl http://localhost:3001/
# ทดสอบ endpoint ที่มี custom span
curl http://localhost:3001/api/users/123
# ทดสอบ POST request
curl -X POST http://localhost:3001/api/process \
-H "Content-Type: application/json" \
-d '{"data": "test data"}'
# ทดสอบ endpoint หลัก
curl http://localhost:3002/
# ทดสอบ endpoint ที่มี nested spans
curl http://localhost:3002/api/users/456
# ทดสอบ POST request
curl -X POST http://localhost:3002/api/process \
-H "Content-Type: application/json" \
-d '{"data": "manual test"}'
# ทดสอบ complex operation with multiple steps
curl http://localhost:3002/api/complexAuto-Instrumentation (Ports 3010-3012):
# ทดสอบ distributed request (A → B → C)
curl http://localhost:3010/api/orders/12345
# ทดสอบ parallel calls
curl http://localhost:3010/api/dashboardManual-Instrumentation (Ports 3020-3022):
# ทดสอบ distributed request (A → B → C)
curl http://localhost:3020/api/orders/67890
# ทดสอบ parallel calls
curl http://localhost:3020/api/dashboardเมื่อ stack ทำงานแล้ว คุณสามารถเข้าถึง UI ต่างๆ ได้ที่:
-
Jaeger UI (Traces): http://localhost:16686
- ดู distributed traces และ service dependencies
- วิเคราะห์ latency และ performance
-
Prometheus (Metrics): http://localhost:9090
- Query metrics ด้วย PromQL
- ดู request rate, error rate, duration
-
Grafana (Visualization): http://localhost:3001
- Username:
admin - Password:
admin - สร้าง dashboard สำหรับ metrics และ logs
- Add Data Sources: Prometheus และ Loki
- Username:
-
Loki (Logs): http://localhost:3100
- Query logs ด้วย LogQL
- ดู structured logs พร้อม TraceID
- Correlation กับ Traces
ตัวอย่างทั้งหมดรองรับ OpenTelemetry Logs แล้ว!
Application → OTLP Collector → Loki → Grafana
- เปิด Grafana: http://localhost:3001
- Add Data Source → Loki (URL:
http://loki:3100) - Explore → Loki → Query:
# ดู logs ทั้งหมด
{service_name="auto-instrumentation-example"}
# ดู ERROR logs เท่านั้น
{service_name="auto-instrumentation-example"} |= "ERROR"
# ดู logs ของ specific trace
{service_name="auto-instrumentation-example"} | json | trace_id="abc123"
# ดู logs จากทุก service
{service_name=~"service-.*"}
แต่ละ log record จะมี TraceID และ SpanID เชื่อมโยงกับ Traces:
// Log ภายใน span
const span = tracer.startSpan('operation');
context.with(trace.setSpan(context.active(), span), () => {
logger.emit({
severityNumber: SeverityNumber.INFO,
body: 'Processing started',
});
// Log นี้จะมี TraceID เดียวกับ span
});➡️ ดูเอกสารเพิ่มเติม: Logs Documentation
example/
├── docker-compose.yml # Observability stack เท่านั้น (optional)
├── otel-collector-config.yaml # Reference config
├── prometheus.yml # Reference config
├── README.md # เอกสารนี้
│
├── auto-instrumentation/ # 🤖 Auto-Instrumentation Example (STANDALONE)
│ ├── app.js # Express app with auto-instrumentation + logs
│ ├── tracing.js # SDK config with auto-instrumentations + LoggerProvider
│ ├── package.json # Dependencies
│ ├── Dockerfile # Container image
│ ├── docker-compose.yml # ✅ Full stack (App + Observability)
│ ├── otel-collector-config.yaml # ✅ OTLP Collector config
│ ├── prometheus.yml # ✅ Prometheus config
│ └── README.md # เอกสารโดยละเอียด
│
├── manual-instrumentation/ # ✍️ Manual-Instrumentation Example (STANDALONE)
│ ├── app.js # Express app with manual spans + logs
│ ├── tracing.js # SDK config without auto-instrumentations + LoggerProvider
│ ├── package.json # Dependencies
│ ├── Dockerfile # Container image
│ ├── docker-compose.yml # ✅ Full stack (App + Observability)
│ ├── otel-collector-config.yaml # ✅ OTLP Collector config
│ ├── prometheus.yml # ✅ Prometheus config
│ └── README.md # เอกสารโดยละเอียด
│
├── logs/ # 🗒️ Logs Documentation
│ └── README.md # คู่มือการใช้งาน OpenTelemetry Logs
│
└── distributed-tracing/ # 🌐 Distributed-Tracing Example (STANDALONE)
├── auto-instrumentation/ # Auto context propagation
│ ├── service-a/ # Frontend API (Port 3010)
│ ├── service-b/ # Backend API (Port 3011)
│ └── service-c/ # Database Service (Port 3012)
├── manual-instrumentation/ # Manual context propagation
│ ├── service-a/ # Frontend API (Port 3020)
│ ├── service-b/ # Backend API (Port 3021)
│ └── service-c/ # Database Service (Port 3022)
├── docker-compose.yml # ✅ Full stack with all services
├── LOGS.md # วิธีเพิ่ม logs ใน distributed services
└── README.md # เอกสารโดยละเอียด
หมายเหตุ: แต่ละตัวอย่างมี config files และ observability stack ของตัวเองแล้ว สามารถรันได้เป็น standalone!
| คุณสมบัติ | Auto-Instrumentation | Manual-Instrumentation | Distributed-Tracing |
|---|---|---|---|
| Complexity | ✅ ต่ำ | ❌ สูง | |
| Setup Time | ⚡ รวดเร็วมาก | 🐢 ใช้เวลามากกว่า | 🏗️ ต้อง setup หลาย services |
| Code Amount | ✅ น้อยมาก | ❌ เยอะกว่า | 📦 หลาย services |
| Use Case | Single app | Single app | Microservices |
| Context Propagation | ✅ อัตโนมัติ | ✍️ Manual | 🔗 ข้าม services |
| Signals Supported | 📝📈🗒️ Traces + Metrics + Logs | 📝📈🗒️ Traces + Metrics + Logs | 📝📈🗒️ Traces + Metrics + Logs |
| Learning Value | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
- 🚀 ต้องการเริ่มต้นอย่างรวดเร็ว
- 🏢 Production application ที่ใช้ standard frameworks
- 📊 ต้องการ coverage ที่กว้าง
- ⏰ มีเวลาจำกัดในการ implement
- 🎯 ต้องการ trace custom business logic
- 🔧 ใช้กับ legacy systems หรือ custom frameworks
- ⚡ Performance optimization เป็นสิ่งสำคัญ
- 📚 ต้องการเรียนรู้ OpenTelemetry อย่างลึกซึ้ง
- 🌐 มี microservices architecture
- 🔗 ต้องการ trace requests ข้าม services
- 📊 วิเคราะห์ service-to-service communication
- 🐛 Debug issues ในระบบ distributed
- Auto สำหรับ HTTP/Express (พื้นฐาน)
- Manual สำหรับ business-critical operations
- Distributed สำหรับ microservices communication
- ✅ Auto-Tracing: HTTP requests และ Express routes ถูก trace อัตโนมัติ
- ✅ Custom Spans: เพิ่ม custom spans เพื่อ trace business logic เฉพาะ
- ✅ Attributes & Events: เพิ่มข้อมูลเพิ่มเติมให้กับ spans
- ✅ Error Tracking: จับและบันทึก exceptions อัตโนมัติ
- ✅ Logs Support: ใช้ OpenTelemetry Logger พร้อม TraceID
- ✅ Full Control: สร้างและควบคุม spans ทุกอันด้วยตัวเอง
- ✅ Context Propagation: จัดการ parent-child span relationships
- ✅ Nested Spans: สร้าง complex tracing hierarchies
- ✅ Custom Middleware: สร้าง HTTP tracing middleware เอง
- ✅ Span Kinds: ใช้ SERVER, CLIENT, INTERNAL span kinds
- ✅ Logs Support: ใช้ OpenTelemetry Logger พร้อม TraceID
- ✅ OTLP Export: ส่งข้อมูลไปยัง OpenTelemetry Collector
- ✅ Metrics Export: ส่งข้อมูล metrics พร้อม traces
- ✅ Logs Export: ส่ง structured logs ไปยัง Loki
- ✅ Resource Attributes: กำหนด service name และ version
- ✅ Complete Observability: Traces + Metrics + Logs
- ✅ Context Propagation: ส่ง trace context ข้าม services
- ✅ W3C Trace Context: ใช้ standard W3C headers
- ✅ Service-to-Service Tracing: ติดตาม requests ข้ามหลาย services
- ✅ Microservices Pattern: แสดงสถาปัตยกรรม A → B → C
- ✅ Auto vs Manual: เปรียบเทียบทั้งสองวิธี
- ✅ Logs Across Services: บันทึก logs พร้อม TraceID ทุก service
Auto-Instrumentation - แก้ไขใน auto-instrumentation/tracing.js:
const resource = Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'your-auto-service',
[SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0',
})
);Manual-Instrumentation - แก้ไขใน manual-instrumentation/tracing.js:
const resource = Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'your-manual-service',
[SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0',
})
);แก้ไขใน tracing.js ของแต่ละ example:
const traceExporter = new OTLPTraceExporter({
url: 'http://your-collector:4318/v1/traces',
});Auto-Instrumentation - แก้ไขใน auto-instrumentation/app.js:
const PORT = 3001; // เปลี่ยนเป็น port ที่ต้องการManual-Instrumentation - แก้ไขใน manual-instrumentation/app.js:
const PORT = 3002; // เปลี่ยนเป็น port ที่ต้องการหยุด Docker containers:
docker-compose downลบ volumes (ถ้าต้องการ):
docker-compose down -v- Auto-Instrumentation Example - README
- Manual-Instrumentation Example - README
- Distributed-Tracing Example - README