OpenTelemetry (OTel)
OpenTelemetry adalah standar open-source untuk observability: traces, metrics, dan logs. Vendor-neutral — data bisa dikirim ke Jaeger, Grafana, Datadog, dll.
Three Pillars of Observability
- Traces — Ikuti request dari awal sampai akhir melintasi service
- Metrics — Angka terukur: latency, error rate, throughput
- Logs — Event records dengan context
Tracing Concepts
// Trace = kumpulan spans
// Span = satu operasi (HTTP request, DB query, dll)
Trace: "POST /api/orders"
├── Span: API Gateway (2ms)
├── Span: Auth Middleware (5ms)
├── Span: OrderController.create (150ms)
│ ├── Span: DB: INSERT orders (30ms)
│ ├── Span: DB: UPDATE inventory (20ms)
│ └── Span: HTTP: POST payment-service (80ms)
└── Span: Response serialization (3ms)
Setup di Node.js
// tracing.js — load sebelum app code
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: "http://localhost:4318/v1/traces",
}),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
Custom Spans
import { trace } from "@opentelemetry/api";
const tracer = trace.getTracer("order-service");
async function processOrder(order) {
return tracer.startActiveSpan("processOrder", async (span) => {
span.setAttribute("order.id", order.id);
span.setAttribute("order.total", order.total);
try {
await validateOrder(order);
await chargePayment(order);
span.setStatus({ code: SpanStatusCode.OK });
} catch (err) {
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
throw err;
} finally {
span.end();
}
});
}