OpenTelemetry
OpenTelemetry è lo standard CNCF per raccogliere dati di telemetria (tracce, metriche, log) da applicazioni e infrastrutture.
Installazione
Node.js/JavaScript
# Core packages
npm install @opentelemetry/api @opentelemetry/sdk-node
# Auto-instrumentation
npm install @opentelemetry/auto
# Exporters
npm install @opentelemetry/exporter-trace-otlp-http
npm install @opentelemetry/exporter-metrics-otlp-http
# Instrumentation for libraries
npm install @opentelemetry/instrumentation-express
npm install @opentelemetry/instrumentation-http
npm install @opentelemetry/instrumentation-pg
Python
# Core packages
pip install opentelemetry-api
pip install opentelemetry-sdk
# Exporters
pip install opentelemetry-exporter-otlp
pip install opentelemetry-exporter-jaeger
# Instrumentation
pip install opentelemetry-instrumentation-flask
pip install opentelemetry-instrumentation-requests
pip install opentelemetry-instrumentation-sqlalchemy
Java
# Maven dependencies
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<version>1.28.0</version>
</dependency>
# Java agent auto-instrumentation
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.28.0/opentelemetry-javaagent.jar
Configurazione di Base
Tracciatura di Node.js
// tracing.js
const { NodeSDK } = require("@opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({
url: "http://localhost:4318/v1/traces"
}),
instrumentations: [getNodeAutoInstrumentations()]
});
sdk.start();
console.log("Tracing initialized");
Tracciatura di Python
# tracing.py
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
# Setup OTLP exporter
otlp_exporter = OTLPSpanExporter(
endpoint="http://localhost:4318/v1/traces"
)
# Setup tracer provider
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(otlp_exporter)
)
# Auto-instrument libraries
FlaskInstrumentor().instrument()
RequestsInstrumentor().instrument()
tracer = trace.get_tracer(__name__)
Tracciatura di Java
# Run with Java agent
java -javaagent:opentelemetry-javaagent.jar \
-Dotel.exporter.otlp.endpoint=http://localhost:4318 \
-Dotel.service.name=my-app \
-jar app.jar
Strumentazione Manuale
Creazione di Span
// Node.js
const { trace } = require("@opentelemetry/api");
const tracer = trace.getTracer("my-app");
const span = tracer.startSpan("process-request", {
attributes: {
"http.method": "GET",
"http.url": "/api/users"
}
});
try {
// Do work
span.addEvent("Processing user data");
span.setStatus({ code: 0 });
} catch (error) {
span.recordException(error);
span.setStatus({ code: 2, message: error.message });
} finally {
span.end();
}
# Python
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("process_request") as span:
span.set_attribute("http.method", "GET")
span.set_attribute("http.url", "/api/users")
try:
# Do work
span.add_event("Processing user data")
except Exception as e:
span.record_exception(e)
raise
Raccolta di Metriche
Metriche JavaScript
// metrics.js
const { MeterProvider, PeriodicExportingMetricReader } = require("@opentelemetry/sdk-metrics");
const { OTLPMetricExporter } = require("@opentelemetry/exporter-metrics-otlp-http");
const reader = new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: "http://localhost:4318/v1/metrics"
})
});
const meterProvider = new MeterProvider({ reader });
const meter = meterProvider.getMeter("my-app");
// Create counter
const requestCounter = meter.createCounter("http.requests", {
description: "Total HTTP requests"
});
requestCounter.add(1, {
"http.method": "GET",
"http.status_code": 200
});
// Create histogram
const latencyHistogram = meter.createHistogram("http.duration", {
unit: "ms",
description: "HTTP request duration"
});
latencyHistogram.record(123, {
"http.method": "GET"
});
Metriche Python
# metrics.py
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
reader = PeriodicExportingMetricReader(
OTLPMetricExporter(endpoint="http://localhost:4318/v1/metrics")
)
meter_provider = MeterProvider(metric_readers=[reader])
meter = meter_provider.get_meter("my-app")
# Counter
request_counter = meter.create_counter(
"http.requests",
description="Total HTTP requests"
)
request_counter.add(1, {"http.method": "GET", "http.status_code": 200})
# Histogram
latency_histogram = meter.create_histogram(
"http.duration",
unit="ms",
description="HTTP request duration"
)
latency_histogram.record(123, {"http.method": "GET"})
Configurazione degli Esportatori
Esportatore OTLP
// Over HTTP
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");
const exporter = new OTLPTraceExporter({
url: "http://localhost:4318/v1/traces",
headers: {
"api-key": "your-api-key"
},
concurrencyLimit: 10,
timeoutMillis: 30000
});
// Over gRPC
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-grpc");
const exporter = new OTLPTraceExporter({
url: "grpc://localhost:4317"
});
Esportatore Jaeger
// Node.js
const { JaegerExporter } = require("@opentelemetry/exporter-jaeger");
const exporter = new JaegerExporter({
host: "localhost",
port: 6831,
serviceName: "my-app"
});
# Python
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
jaeger_exporter = JaegerExporter(
agent_host_name="localhost",
agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter)
)
Esportatore Zipkin
// Node.js
const { ZipkinExporter } = require("@opentelemetry/exporter-zipkin");
const exporter = new ZipkinExporter({
url: "http://localhost:9411/api/v2/spans",
serviceName: "my-app"
});
Propagazione del Contesto
Contesto di Tracciatura W3C
// Propagator setup
const { W3CTraceContextPropagator } = require("@opentelemetry/core");
const { CompositePropagator } = require("@opentelemetry/core");
const propagator = new CompositePropagator({
propagators: [new W3CTraceContextPropagator()]
});
// Extract context from request
const ctx = propagator.extract(context.active(), {
get: (key) => req.headers[key.toLowerCase()]
});
// Inject context into outgoing request
propagator.inject(ctx, carrier, {
set: (key, value) => outgoingRequest.headers[key] = value
});
Elaborazione in Batch
JavaScript
const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-node");
const batchProcessor = new BatchSpanProcessor(otlpExporter, {
maxQueueSize: 2048,
maxExportBatchSize: 512,
scheduledDelayMillis: 5000,
exportTimeoutMillis: 30000
});
tracerProvider.addSpanProcessor(batchProcessor);
Configurazione di Docker Compose
# docker-compose.yml
version: '3'
services:
otel-collector:
image: otel/opentelemetry-collector:latest
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "9411:9411" # Zipkin
volumes:
- ./otel-config.yaml:/etc/otel-collector-config.yaml
command: ["--config=/etc/otel-collector-config.yaml"]
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "6831:6831/udp"
- "16686:16686" # Jaeger UI
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
Migliori Pratiche
- Inizializza la tracciatura all’inizio dell’avvio dell’applicazione
- Usa la propagazione del contesto per la tracciatura distribuita tra i servizi
- Imposta attributi span significativi per il debug e il filtraggio
- Implementa il campionamento per ridurre l’overhead nei sistemi ad alto traffico
- Configura processori batch per una migliore velocità effettiva
- Usa la registrazione strutturata insieme agli span
- Monitora la salute dell’esportatore e le esportazioni non riuscite
- Imposta soglie di avviso per la latenza della traccia
- Usa strumentazione personalizzata per le metriche aziendali
- Documenta gli attributi span personalizzati e i loro significati
- Rivedi e aggiorna regolarmente i pacchetti di strumentazione
- Testa il campionamento di traccia in ambienti simili alla produzione
Risorse
Last updated: 2025-03-30