Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

OpenTelemetry — distributed tracing dla aplikacji na VPS

Opublikowano: 10 kwietnia 2026 · Kategoria: VPS

Gdy aplikacja webowa jest wolna, monitoring CPU i RAM rzadko wyjaśni dlaczego konkretne żądanie trwało 3 sekundy zamiast 200ms. Distributed tracing rozwiązuje ten problem: śledzi żądanie przez wszystkie mikroserwisy, bazy danych i zewnętrzne API, pokazując dokładnie gdzie czas jest tracony. OpenTelemetry to otwarty standard który pozwala instrumentować aplikację raz i wysyłać dane do dowolnego backendu — bez vendor lock-in. Ten artykuł pokazuje setup OTel z Node.js, Python, OpenTelemetry Collector i Jaeger jako backend.

Koncepcja: traces, spans i context propagation

Distributed tracing opiera się na trzech podstawowych konceptach:

  • Trace — pełna ścieżka jednego żądania przez system. Identyfikowany przez unikalny TraceID (128-bit hex). Może obejmować dziesiątki serwisów i setki operacji.
  • Span — pojedyncza operacja w ramach trace. Ma: nazwę, SpanID, czas start i end, atrybuty (np. http.method=GET, db.statement=SELECT...), status (OK/ERROR) i eventy (timestamped log entries wewnątrz spana).
  • Context propagation — mechanizm przekazywania TraceID i SpanID między serwisami przez nagłówki HTTP (traceparent w standardzie W3C TraceContext, X-B3-TraceId w Zipkin B3). Dzięki temu serwisy A, B, C piszą spany do tego samego trace.

Uruchomienie Jaeger (backend do przechowywania traces)

# Jaeger all-in-one (do testow i dev, in-memory storage)
docker run -d \
  --name jaeger \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  jaegertracing/all-in-one:latest

# Porty:
# 16686 - Jaeger UI (przegladarka)
# 4317  - OTLP gRPC (odbiera traces z OTel Collector / SDK)
# 4318  - OTLP HTTP

# Sprawdz czy dziala
curl http://localhost:16686/api/services

Instrumentacja Node.js — automatic i manual

OpenTelemetry dla Node.js oferuje automatic instrumentation — biblioteka automatycznie dodaje spany dla popularnych frameworków (Express, Fastify, HTTP, MySQL, PostgreSQL, Redis) bez zmian w kodzie aplikacji.

# Instalacja pakietow OTel dla Node.js
npm install @opentelemetry/sdk-node \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-http

# tracing.js - plik inicjalizacji (ladowany przed aplikacja)
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');

const exporter = new OTLPTraceExporter({
  url: 'http://localhost:4318/v1/traces',
});

const sdk = new NodeSDK({
  traceExporter: exporter,
  instrumentations: [getNodeAutoInstrumentations()],
  serviceName: 'my-express-app',
});

sdk.start();

// Uruchomienie z tracing.js zaladowanym przed aplikacja:
// node --require ./tracing.js app.js
// Lub w package.json scripts:
// "start": "node --require ./tracing.js app.js"

Instrumentacja Python — FastAPI i automatyczne spany

# Instalacja
pip install opentelemetry-sdk \
  opentelemetry-exporter-otlp \
  opentelemetry-instrumentation-fastapi \
  opentelemetry-instrumentation-sqlalchemy \
  opentelemetry-instrumentation-httpx

# main.py - inicjalizacja OTel
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.fastapi import FastAPIInstrumentor

# Konfiguracja provider i exporter
provider = TracerProvider()
exporter = OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces")
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)

app = FastAPI()
FastAPIInstrumentor.instrument_app(app)  # Auto-instrument FastAPI

# Reczne spany (manual instrumentation)
tracer = trace.get_tracer(__name__)

@app.get("/items/{item_id}")
async def get_item(item_id: int):
    with tracer.start_as_current_span("get_item_from_db") as span:
        span.set_attribute("item.id", item_id)
        # ... kod
        return {"id": item_id}

OpenTelemetry Collector — centralne przetwarzanie danych

OTel Collector to middleware między aplikacjami a backendami. Aplikacje wysyłają traces do Collectora, który je przetwarza (filtruje, próbkuje, enriches) i przekazuje do jednego lub wielu backendów. Zmiana backendu wymaga tylko zmiany konfiguracji Collectora, nie kodu aplikacji.

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 1s
    send_batch_size: 1024
  # Probkowanie: zachowaj 10% traces
  probabilistic_sampler:
    sampling_percentage: 10

exporters:
  otlp:
    endpoint: jaeger:4317
    tls:
      insecure: true
  # Rownoczesny eksport do Grafana Tempo
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, probabilistic_sampler]
      exporters: [otlp, otlp/tempo]

---
# docker-compose.yml fragment
services:
  otel-collector:
    image: otel/opentelemetry-collector-contrib:latest
    volumes:
      - ./otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
    ports:
      - "4317:4317"
      - "4318:4318"

Porównanie backendów dla traces

Backend Typ Storage Koszt Integracja Grafana
Jaeger Self-hosted OSS In-memory / Elasticsearch / Cassandra Darmowy (self-hosted) Plugin Jaeger datasource
Grafana Tempo Self-hosted OSS Lokalne bloki / S3 / GCS Darmowy (self-hosted) Natywna integracja
Zipkin Self-hosted OSS In-memory / MySQL / Elasticsearch Darmowy (self-hosted) Plugin Zipkin datasource
Datadog APM SaaS Chmura Datadog Od 31 USD/host/msc Osobna platforma
Grafana Cloud SaaS (managed Tempo) Chmura Grafana Darmowy (50 GB traces/msc) Natywna (Grafana Cloud)

Najczęstsze pytania

Czym jest OpenTelemetry i do czego służy? +
OpenTelemetry (OTel) to open-source'owy framework i standard do zbierania danych obserwacyjności (observability): traces (rozproszone śledzenie żądań), metrics (metryki) i logs. OTel definiuje wspólne API i biblioteki do instrumentacji aplikacji w różnych językach (Node.js, Python, Java, Go, PHP). Dane wysyłane są do OpenTelemetry Collector, który je przetwarza i przekazuje do backendów (Jaeger, Zipkin, Grafana Tempo, Datadog, OTLP).
Czym jest trace i span w OpenTelemetry? +
Trace to pełna ścieżka żądania przez system od początku do końca. Span to pojedyncza operacja w ramach trace — np. zapytanie SQL, wywołanie HTTP, przetwarzanie w kolejce. Każdy span ma: nazwę, czas start/end, atrybuty (klucz-wartość), status i opcjonalnie eventy. Spany są ze sobą powiązane przez parent-child relationship i propagowane między serwisami przez nagłówki HTTP (B3, W3C TraceContext). Trace ID łączy wszystkie spany jednego żądania.
Jaka jest różnica między OpenTelemetry a Datadog APM? +
OpenTelemetry to open-source standard i SDK — możesz instrumentować aplikacje raz i wysyłać dane do dowolnego backendu (Jaeger, Tempo, Datadog, New Relic). Datadog APM to zamknięta platforma SaaS z własnym agentem i własnym protokołem. Instrumentacja Datadog-specific wiąże Cię z tym dostawcą. Zaleta Datadoga to łatwiejszy setup i bogaty UI. Zaleta OTel to vendor lock-in freedom i możliwość self-hosting backendów (Jaeger, Grafana Tempo) bez płatnych SaaS.
Ile pamięci RAM potrzebuje Jaeger lub Grafana Tempo? +
Jaeger w trybie all-in-one (do testów, in-memory storage) zużywa 200-500 MB RAM. Jaeger produkcyjny z Elasticsearch/Cassandra backend wymaga 2+ GB RAM dla backendów. Grafana Tempo z lokalnym storage (bloki na dysku) działa od ok. 500 MB RAM dla małego ruchu. Dla kilkunastu mikrousług i milionów spanów dziennie zalecane jest 4-8 GB RAM na cały stos observability (Tempo + Grafana + Prometheus). Dla testów na VPS 2 GB RAM wystarczy Jaeger all-in-one.
Czy OpenTelemetry spowalnia aplikację? +
Narzut OpenTelemetry jest minimalny przy domyślnej konfiguracji. Automatic instrumentation (bez zmian w kodzie) dodaje zwykle 1-5% narzut CPU i kilkadziesiąt milisekund dla bardzo krótkich operacji. Możesz kontrolować próbkowanie (sampling) — np. śledź tylko 10% żądań (TraceIdRatioBased sampler) lub tylko wolne żądania (parent-based sampling). W produkcji typowy setup to 1-10% sampling, co redukuje narzut do poniżej 1%.

Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.