OpenTelemetry OpenTelemetry

Apps ohne Code-Änderungen instrumentieren: Java, Python und Node.js

Hänge OpenTelemetry-Agents allein mit Umgebungsvariablen und Kommandozeilen-Flags an.

12 min Anfänger

Zero-Code-Instrumentierung hängt beim Start einen Agent an deine Anwendung. Der Agent patcht gängige Bibliotheken, etwa HTTP-Server und -Clients, Datenbanktreiber und Message Queues, und erzeugt Traces, Metriken und Logs, ohne den Quellcode zu ändern. Die Konfiguration sind die Standard-OTEL_*-Umgebungsvariablen plus ein paar sprachspezifische, sodass das gesamte Setup eine Dockerfile-Zeile und ein paar Variablen ist. Diese Anleitung behandelt Java, Python und Node.js.

Voraussetzung: ein Ort, an den Daten gesendet werden

Habe einen Collector, der lauscht, zum Beispiel aus der Docker-Compose-Anleitung, auf otel-collector:4318 (HTTP) oder :4317 (gRPC). Jedes Beispiel unten verweist mit OTEL_EXPORTER_OTLP_ENDPOINT darauf.

Java

Lade das Agent-JAR einmal herunter und hänge es dann mit -javaagent an:

curl -L -o opentelemetry-javaagent.jar \
  https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar

java -javaagent:./opentelemetry-javaagent.jar \
     -Dotel.service.name=checkout \
     -jar myapp.jar

Container bevorzugen meist Umgebungsvariablen, wobei JAVA_TOOL_OPTIONS das Flag trägt, damit du den Entrypoint nicht änderst:

FROM eclipse-temurin:21-jre
WORKDIR /app
COPY myapp.jar .
ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/<version>/opentelemetry-javaagent.jar /otel/opentelemetry-javaagent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:/otel/opentelemetry-javaagent.jar"
CMD ["java", "-jar", "myapp.jar"]

Pinne die Agent-Version in der Download-URL, statt latest zu nutzen, damit Builds reproduzierbar sind. Konfiguriere ihn dann zur Laufzeit:

OTEL_SERVICE_NAME=checkout \
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
OTEL_RESOURCE_ATTRIBUTES=service.version=1.4.2,deployment.environment.name=staging \
java -jar myapp.jar

Der Agent lässt sich auf drei Arten konfigurieren: Systemeigenschaften (-Dotel.service.name=...), Umgebungsvariablen oder eine Java-Properties-Datei, die mit OTEL_JAVAAGENT_CONFIGURATION_FILE=/path/to/file.properties (oder -Dotel.javaagent.configuration-file) referenziert wird. Halte die Properties-Datei in Git, wenn du viele Einstellungen hast. Zum Debuggen des Agents selbst setze OTEL_JAVAAGENT_DEBUG=true und rechne mit sehr ausführlicher Ausgabe. Der Agent unterstützt auch eine deklarative YAML-Konfigurationsdatei; siehe die Dokumentation des Java-Agents.

Python

Installiere die Distribution, den OTLP-Exporter und die Instrumentierungsbibliotheken, die zu deinen installierten Paketen passen:

pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install

opentelemetry-bootstrap -a install scannt deine Umgebung und installiert die Instrumentierung für das, was es findet, zum Beispiel die Flask-Instrumentierung, wenn Flask installiert ist. Führe opentelemetry-bootstrap ohne Argumente aus, um seine Empfehlungen zu sehen, ohne zu installieren. Starte die App über opentelemetry-instrument:

OTEL_SERVICE_NAME=checkout \
OTEL_TRACES_EXPORTER=otlp \
OTEL_METRICS_EXPORTER=otlp \
OTEL_LOGS_EXPORTER=otlp \
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
opentelemetry-instrument python myapp.py

Beachte die abschließenden Backslashes: Jede Variable muss in derselben logischen Kommandozeile wie opentelemetry-instrument stehen, sonst erreicht sie den Prozess nicht. Bei Servern wie Gunicorn oder Uvicorn umhülle den Server-Befehl: opentelemetry-instrument gunicorn app:app. Manche Setups mit dem Paketmanager uv brauchen für den Bootstrap-Schritt einen Workaround, den die Python-Troubleshooting-Seite beschreibt. Der Log-Export ist in Python Opt-in, prüfe also den Logging-Abschnitt der Python-Dokumentation, wenn Logs nicht erscheinen.

Ein Dockerfile-Muster:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt \
 && pip install opentelemetry-distro opentelemetry-exporter-otlp \
 && opentelemetry-bootstrap -a install
COPY . .
CMD ["opentelemetry-instrument", "python", "myapp.py"]

Node.js

Installiere die API und das Auto-Instrumentierungs-Bundle:

npm install --save @opentelemetry/api
npm install --save @opentelemetry/auto-instrumentations-node

Lade es vor deiner App mit --require oder über NODE_OPTIONS:

export OTEL_SERVICE_NAME=checkout
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
export OTEL_NODE_RESOURCE_DETECTORS=env,host,os
export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
node app.js

OTEL_NODE_RESOURCE_DETECTORS begrenzt, welche Resource-Detektoren laufen (standardmäßig sind alle aktiviert). OTEL_NODE_ENABLED_INSTRUMENTATIONS begrenzt, welche Instrumentierungen geladen werden; siehe die Seite zur Modulkonfiguration. OTEL_LOG_LEVEL akzeptiert none, error, warn, info, debug, verbose und all, mit info als Standard. Halte es in der Produktion auf info, da Debug-Ausgabe die Performance beeinträchtigt. Anwendungen mit ES-Modulen brauchen womöglich eine zusätzliche Loader-Option; folge der Node.js-Dokumentation für dein Modulsystem.

.NET, Go und andere

.NET hat einen Zero-Code-Agent, der auf dieselbe Weise konfiguriert wird (Umgebungsvariablen plus ein Startskript). Go nutzt einen eBPF-basierten Agent, der als privilegierter Sidecar läuft und den Pfad der Ziel-Executable braucht, wird also meist über den Operator genutzt. Prüfe den Zero-Code-Abschnitt der Dokumentation für jede.

Was du bekommst und was nicht

Du bekommst Spans für eingehendes und ausgehendes HTTP, Datenbankaufrufe und gängige Messaging-Bibliotheken sowie in einigen Sprachen Laufzeit-Metriken. Du bekommst keine Spans auf Geschäftsebene wie „Rabatt berechnen“, weil der Agent davon nichts wissen kann. Füge mit der OpenTelemetry-API ein paar manuelle Spans oder Attribute hinzu, wo sich das zusätzliche Detail auszahlt, und nutze den Agent für alles andere.

Prüfen, dass es funktioniert

  1. Starte die App mit aktiviertem debug-Exporter des Collectors.
  2. Sende eine Anfrage: curl http://localhost:8080/.
  3. Suche im Collector-Log nach Spans mit deinem service.name:
docker compose logs otel-collector | grep -i 'service.name'

Kommt nichts an, prüfe in dieser Reihenfolge: Endpunkt und Port passen zum Protokoll, die Collector-Pipeline für das Signal führt den Receiver otlp auf, die App kann den Hostnamen des Collectors auflösen und OTEL_SDK_DISABLED ist nicht gesetzt. Die Troubleshooting-Anleitung vertieft jeden Punkt.

Hinweise für die Produktion

  • Pinne Agent- und Distributionsversionen und aktualisiere sie bewusst.
  • Setze service.name, service.version und deployment.environment.name bei jedem Service, da Dashboards davon abhängen.
  • Beginne mit einem Sampling-Verhältnis, statt alles zu behalten (siehe die Sampling-Anleitung).
  • Nutze auf Kubernetes den Operator, um den Agent per Annotation zu injizieren, statt jedes Dockerfile zu bearbeiten.

Beliebte Anleitungen