Referensi cepat OpenTelemetry. Traces, spans, metrics, logs, baggage, context propagation, auto dan manual instrumentation, OTLP exporter. Perfect buat developer yang mau observability di aplikasi Python dan JavaScript.
Login atau daftar akun gratis untuk membaca cheat sheet ini.
Cheat sheet ini berisi panduan praktis OpenTelemetry (OTel), standar observability open-source untuk traces, metrics, dan logs. Cocok buat developer yang ingin menerapkan distributed tracing di aplikasi Python dan JavaScript dengan backend seperti Jaeger atau Grafana Tempo.
OpenTelemetry adalah proyek CNCF yang menyediakan standar, SDK, dan tool untuk menghasilkan dan mengekspor data telemetri (traces, metrics, logs) dari aplikasi. OTel membebaskan kamu dari vendor lock-in karena bisa dikirim ke backend apa pun.
| Pilar | Fungsi | Contoh |
|---|---|---|
| Traces | Melacak request melalui multiple service | Request dari API gateway ke database |
| Metrics | Data numerik agregat | Request count, memory usage, error rate |
| Logs | Event diskrit dengan timestamp | "User 123 logged in" |
| Komponen |
|---|
| Fungsi |
|---|
| API | Interface yang dipakai di kode aplikasi |
| SDK | Implementasi API yang mengumpulkan dan mengekspor data |
| Instrumentation Libraries | Auto-instrumentation untuk library populer (Flask, Express, PostgreSQL) |
| Collector | Service proxy yang menerima, memproses, dan mengekspor telemetri |
| OTLP | OpenTelemetry Protocol, format standar untuk transfer data |
Trace adalah rekaman perjalanan satu request melalui sistem terdistribusi. Trace terdiri dari multiple span yang membentuk tree.
Trace: User checkout request
+-- Span: HTTP GET /checkout (gateway)
+-- Span: authenticate_user
+-- Span: get_cart_items
| +-- Span: SELECT * FROM cart (database)
+-- Span: process_payment
+-- Span: POST /api/payment (external API)Span adalah unit kerja tunggal dalam trace. Setiap span punya:
| Kind | Arti |
|---|---|
SERVER | Menerima request (HTTP server, RPC server) |
CLIENT | Mengirim request (HTTP client, RPC client) |
INTERNAL | Operasi internal dalam service |
PRODUCER | Mengirim pesan ke queue |
CONSUMER | Menerima pesan dari queue |
# requirements.txt: opentelemetry-api, opentelemetry-sdk,
# opentelemetry-exporter-otlp
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
# Cara 1: context manager
with tracer.start_as_current_span("process_order") as span:
span.set_attribute("order.id",
with tracer.start_as_current_span("database_query") as span:
# Attributes: metadata key-value
span.set_attribute("db.system", "postgresql")
span.set_attribute("db.statement", "SELECT * FROM users WHERE id = $1")
span.set_attribute("db.operation",
Span child otomatis terhubung ke span parent yang sedang aktif (current span).
def handle_request():
with tracer.start_as_current_span("handle_request") as parent:
# Span ini otomatis menjadi child dari "handle_request"
authenticate()
# Span ini juga child dari "handle_request"
process_data()
def authenticate():
with tracer.start_as_current_span(
// npm install @opentelemetry/api @opentelemetry/sdk-node
// @opentelemetry/exporter-trace-otlp-grpc
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } =
const opentelemetry = require('@opentelemetry/api');
const tracer
OTel menyediakan package auto-instrumentation yang otomatis membuat span untuk library populer tanpa mengubah kode aplikasi.
# Install instrumentation packages
pip install opentelemetry-distro
opentelemetry-bootstrap -a install
# Jalankan aplikasi dengan auto-instrumentation
opentelemetry-instrument \
--service_name checkout-service \
--exporter_otlp_endpoint http://localhost:4317 \
--resource_attributes deployment.environment=production \
python app.pyAuto-instrumentation otomatis men-trace:
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const sdk = new NodeSDK
Context propagation adalah mekanisme meneruskan trace context (trace ID, span ID, baggage) antar service lewat header HTTP atau metadata. Ini yang membuat distributed tracing bekerja.
| Propagator | Header | Keterangan |
|---|---|---|
| W3C TraceContext | traceparent, tracestate | Standar W3C, direkomendasikan |
| B3 (Zipkin) | X-B3-TraceId, X-B3-SpanId, dll | Kompatibel dengan Zipkin |
| Jaeger | uber-trace-id | Format Jaeger native |
traceparent: 00-{trace-id}-{span-id}-{trace-flags}Contoh:
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01from opentelemetry import trace, propagate
from opentelemetry.propagators.composite import CompositePropagator
# Inject context ke headers (di sisi client)
headers = {}
propagate.inject(headers)
# headers sekarang berisi traceparent, tracestate, dll
# Kirim headers ke service berikutnya
response = requests.post(
from opentelemetry.propagate import set_global_textmap
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
from opentelemetry.baggage.propagation import W3CBaggagePropagator
# Composite propagator (W3C TraceContext + Baggage)
set_global_textmap(CompositePropagator([
TraceContextTextMapPropagator(),
W3CBaggagePropagator(),
]))Baggage adalah mekanisme untuk meneruskan key-value data antar service tanpa membuat span. Berguna untuk data seperti user ID, tenant ID, atau feature flags yang perlu tersedia di seluruh rantai request.
from opentelemetry import baggage
# Set baggage di service A
ctx = baggage.set_baggage("user.id", "user_123")
ctx = baggage.set_baggage("tenant.id", "acme_corp", context=ctx)
baggage: user.id=user_123,tenant.id=acme_corp,feature.beta=truefrom opentelemetry import trace, baggage
with tracer.start_as_current_span("handle_request") as span:
# Copy semua baggage ke span attributes untuk visibility
entries = baggage.get_all()
for key, value in entries.items():
span.set_attribute(f"baggage.{key}from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
| Tipe | Deskripsi | Contoh |
|---|---|---|
| Counter | Nilai yang hanya naik | Total request count |
| UpDownCounter | Nilai naik atau turun | Active connections |
| Histogram | Distribusi nilai dalam bucket | Request latency |
| Observable Counter | Counter dari external source | CPU time |
| Gauge | Nilai sesaat | Memory usage |
# Histogram: ukur distribusi latency
request_duration = meter.create_histogram(
name="http_request_duration_seconds",
description="HTTP request duration in seconds",
unit="s"
)
# Record latency
request_duration.record(
OTel logs dirancang untuk berkorelasi dengan traces. Log bisa dikaitkan dengan span yang sedang aktif secara otomatis.
import logging
from opentelemetry import trace
from opentelemetry._logs import set_logger_provider
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
from
Collector adalah service proxy yang menerima telemetri dari aplikasi, memproses (filter, transform, batch), dan mengekspor ke backend. Memakai collector memisahkan aplikasi dari backend.
App --OTLP--> Collector --OTLP--> Jaeger
--OTLP--> Tempo
--OTLP--> Prometheus
--OTLP--> Datadog# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
docker run -p 4317:4317 -p 4318:4318 \
-v $(pwd)/otel-collector-config.yaml:/etc/otelcol/config.yaml \
otel/opentelemetry-collector-contrib:latestJaeger adalah distributed tracing backend open-source dari CNCF.
# Jalankan Jaeger all-in-one untuk development
docker run -d --name jaeger \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
jaegertracing/all-in-one:latest
# UI tersedia di http://localhost:16686Tempo adalah tracing backend dari Grafana Labs, dirancang untuk skala besar dengan object storage.
# tempo.yaml (minimal config)
server:
http_listen_port: 3200
distributor:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
storage:
trace:
backend
docker run -d -p 3200:3200 -p 4317:4317 \
-v $(pwd)/tempo.yaml:/etc/tempo.yaml \
grafana/tempo:latest -config.file=/etc/tempo.yamlPada traffic tinggi, merekam semua trace mahal. Sampling memilih subset trace untuk direkam.
| Tipe Sampling | Cara Kerja |
|---|---|
| AlwaysOn | Rekam semua trace |
| AlwaysOff | Jangan rekam trace sama sekali |
| TraceIDRatioBased | Rekam persentase berdasarkan trace ID |
| ParentBased | Ikuti keputusan sampler parent (head-based) |
| OTLP (tail-based) | Sampling di Collector berdasarkan trace lengkap |
from opentelemetry.sdk.trace.sampling import (
TraceIdRatioBased, ParentBased, ALWAYS_ON
)
sampler = ParentBased(root=TraceIdRatioBased(rate=0.1)) # 10% sampling
provider = TracerProvider(resource=resource, sampler=traceparent.http.method, db.system).