Start / Seminare / Observability mit OpenTelemetry, Prometheus und Grafana
Modul
Automatische Java-Instrumentierung
4 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Automatische Java-Instrumentierung
0:00 Nach drei Modulen Theorie kommt jetzt der Teil, der überraschend schnell geht. Der erste Trace entsteht ohne eine einzige Zeile Code — Sie hängen ein JAR an Ihre Anwendung, setzen ein paar Umgebungsvariablen, und es fließen Daten. Das ist kein Marketingversprechen, das funktioniert tatsächlich so. Der zweite Satz ist allerdings genauso wichtig: Der erste nützliche Trace entsteht nicht ohne Code.
0:24 Wir schauen uns deshalb beides an — was der Agent kann, und wo seine Grenze verläuft. Die Grenze ist nämlich vorhersehbar, und das ist eine gute Nachricht.
Automatische Java-Instrumentierung
0:33 Drei Kapitel: Zuerst der Agent selbst und seine Konfiguration. Dann die Frage, was er von allein erfasst — das ist mehr, als viele erwarten, aber eben nicht alles. Und zum Schluss der Export und die Grenzen des Verfahrens. Am Ende dieses Moduls senden alle drei Pfandwerk-Dienste Telemetrie, und Sie haben eine konkrete Antwort darauf, welche Frage aus Modul eins damit beantwortet ist — und welche eben nicht.
Java Agent ohne Codeänderung
0:58 Beginnen wir mit dem Mechanismus. Ein Java-Agent ist nichts Neues und nichts Exotisches — die JVM kann seit Langem Bytecode beim Laden verändern. Was OpenTelemetry daraus macht, ist allerdings beachtlich: eine gepflegte Instrumentierung für Dutzende verbreiteter Bibliotheken, die jemand anders geschrieben, getestet und gegen die Konventionen abgeglichen hat.
1:18 Diese Arbeit müssen Sie nicht noch einmal machen — und sie ist erheblich, wenn man je versucht hat, eine einzelne Bibliothek sauber selbst zu instrumentieren. Die Zero-Code-Instrumentierung hängt ein Agent-JAR an eine Anwendung ab Java 8. Der Agent injiziert zur Laufzeit Bytecode und erfasst damit Telemetrie aus vielen verbreiteten Bibliotheken und Rahmenwerken.
1:39 Der entscheidende Halbsatz steht am Ende: ohne dass der Anwendungscode angefasst wird. Stellen Sie sich das wie einen Fahrtenschreiber vor, den man nachträglich einbaut — das Fahrzeug fährt wie vorher, protokolliert aber jetzt jede Fahrt. Für Anwendungen, die Sie nicht ändern dürfen oder nicht ändern wollen, ist das der einzige realistische Weg zu Telemetrie.
2:00 Auf diesem Aufruf kommt es nur auf zwei Dinge an. Das Erste ist der Schalter javaagent mit dem Pfad zum JAR — das ist der ganze Einbau. Das Zweite sind die Systemeigenschaften darunter: Dienstname, Protokoll und Endpunkt. Mehr braucht es für den Anfang nicht. Und beachten Sie die Fußzeile: Jede dieser Systemeigenschaften hat eine Entsprechung als Umgebungsvariable.
2:22 Das ist im Containerbetrieb der übliche Weg, weil Sie dort den Startbefehl oft gar nicht in der Hand haben. Es gibt sogar einen Weg über die Standardvariable für JVM-Optionen — damit kommt der Agent ins Image, ohne dass sich das Kommando ändert. Die Logik hinter dieser Tabelle ist eine Dreiteilung. Die erste Zeile setzt die Identität — das ist der Dienstname aus Modul vier.
2:45 Die nächsten beiden setzen das Ziel: wohin und in welcher Form. Und die letzten drei schalten die Signale einzeln. Diese Trennung ist praktisch, weil Sie damit schrittweise vorgehen können: erst Traces, dann Metriken, dann Logs. In der Praxis steht bei allen dreien otlp, aber die Möglichkeit, ein Signal gezielt abzuschalten, hilft beim Eingrenzen von Problemen.
3:07 Achten Sie auf das Zusammenspiel von Protokoll und Endpunkt — das ist die Stelle, an der es am häufigsten klemmt. Vier Argumente, warum der Agent nicht bloß eine Abkürzung ist. Erstens erfasst er die Dienstgrenzen — und genau dort entstehen Latenz und Fehler, nicht in der Mitte Ihrer Geschäftslogik. Zweitens erzeugt er konventionsgerechte Attribute; das ist die direkte Fortsetzung von Modul vier, und es bedeutet, dass fertige Dashboards ohne Anpassung funktionieren.
3:35 Drittens wirkt er auch dort, wo Sie den Quellcode nicht ändern können — bei Altsystemen oder Fremdsoftware oft der einzige Weg. Und viertens lässt er sich ohne Deployment abschalten, wenn er stört. Dieser letzte Punkt beruhigt den Betrieb mehr, als man denkt. Der erste Punkt ist die Nummer eins aller Anfängerfehler: Der Agent läuft, aber der Dienstname fehlt — und alle Dienste heißen gleich.
3:59 Der zweite ist der Klassiker aus Modul drei: Endpunkt auf dem HTTP-Port, Protokoll auf gRPC. Das erzeugt keine hilfreiche Fehlermeldung, sondern Stille. Der dritte kommt erstaunlich oft vor: Der Agent wird als Abhängigkeit eingebunden statt angehängt — das ist etwas anderes und funktioniert so nicht. Und der vierte ist ein Betriebsthema: Der Start dauert länger, weil der Agent Bytecode umschreibt. Das ist normal, sollte aber gemessen sein, bevor sich jemand wundert.
Was der Agent von allein erfasst
4:29 Kommen wir zur Frage, die für Ihre Planung entscheidend ist: Was bekommen Sie geschenkt, und was nicht? Die Antwort folgt einer klaren Regel — der Agent arbeitet an den Rändern der Anwendung. Das ist hilfreich, weil es vorhersagbar ist: Wenn Sie diese Regel einmal verstanden haben, können Sie für jede neue Anwendung vorher sagen, was der Agent liefern wird und welche fachlichen Lücken Sie selbst schließen müssen.
4:51 Schauen wir uns an, wo diese Ränder genau verlaufen. Der Agent erfasst Telemetrie an den Grenzen der Anwendung: eingehende Anfragen, ausgehende HTTP-Aufrufe, Datenbankzugriffe und Vergleichbares. Dazu kommen die Laufzeitmetriken der JVM. Der letzte Satz ist der wichtige: Was innerhalb eines Aufrufs fachlich geschieht, sieht er nicht.
5:13 Das ist keine Schwäche, sondern eine logische Folge — der Agent kennt Bibliotheken, nicht Ihr Geschäft. Er weiß, dass ein HTTP-Aufruf stattgefunden hat, aber nicht, dass dabei ein Leergut geprüft wurde. Genau diese Lücke füllen wir in Modul sechs. Diese Kette zeigt sehr anschaulich, wo der Agent Daten liefert und wo nicht. Die eingehende Anfrage: erfasst. Der Datenbankzugriff: erfasst. Der ausgehende Aufruf: erfasst.
5:40 Und in der Mitte, beim Anwendungscode, ist eine Lücke — dort läuft die Zeit weiter, aber niemand weiß, womit. In der Praxis sieht das so aus: Sie erkennen, dass eine Anfrage zwei Sekunden gedauert hat, davon dreihundert Millisekunden Datenbank und vierhundert die externe Schnittstelle. Wo die restlichen dreizehnhundert geblieben sind, beantwortet erst eigene Instrumentierung.
6:04 Machen wir es konkret. Für Pfandwerk bekommen Sie ohne eine Zeile Code: Latenz und Status je Endpunkt des Annahmedienstes, die Latenz der Girokette als externe Abhängigkeit, die Datenbankzugriffe des Bon-Dienstes inklusive langsamer Abfragen, und die JVM-Kennzahlen aller drei Dienste. Das ist bemerkenswert viel. Besonders die zweite Zeile ist wertvoll, weil die Latenz fremder Schnittstellen sonst notorisch unklar bleibt.
6:28 Die Fußzeile erwähnt noch eine Alternative: Für Spring Boot gibt es neben dem Agent auch einen eigenen Starter — sinnvoll, wenn Sie ohnehin Zugriff auf das Projekt haben. Der erste Punkt ist ein echtes Datenschutzthema: JDBC-Spans können die Abfrage mitsamt eingesetzten Werten tragen. Damit landen Kundendaten in Ihrem Trace-Backend, und zwar ohne dass jemand es entschieden hätte. In Modul neun sehen wir, wie man das entfernt.
6:54 Der zweite Punkt ist ein Mengenproblem: Health-Endpunkte erzeugen die Mehrzahl aller Spans, weil sie im Sekundentakt aufgerufen werden. Der dritte betrifft eigene Bibliotheken, die der Agent nicht kennt — die Lücke fällt oft erst spät auf. Und der vierte ist banal und verbreitet: Die JVM-Metriken werden erfasst und nie angesehen.
Export und Grenzen
7:14 Im letzten Kapitel dieses Moduls geht es um zwei Dinge, die zusammenhängen: wie Sie steuern, was der Agent erzeugt, und wo das Verfahren grundsätzlich endet. Die zweite Frage ist die wichtigere, denn sie bestimmt, wie viel Arbeit in Modul sechs auf Sie wartet. Und wer die Grenze kennt, steuert gezielt, statt alles einzuschalten und die überflüssigen Daten später mühsam wieder herauszufiltern.
7:37 Der Export läuft über OTLP an den Collector — das kennen wir aus Modul drei. Neu ist die Möglichkeit, einzelne Instrumentierungen gezielt zu unterdrücken; dafür gibt es Systemeigenschaften nach einem festen Muster. Und dann kommt der Satz, auf den es in diesem Modul ankommt: Die Grenze des Verfahrens ist inhaltlich, nicht technisch.
7:57 Der Agent kennt technische Aufrufe, aber keine fachlichen Vorgänge. Er könnte auch nicht anders — er hat keine Ahnung, was ein Rücknahmevorgang ist. Diese Grenze verschiebt sich auch nicht mit der nächsten Version. Eine einzige Zeile, aber mit einer Haltung dahinter. Das Muster lautet: otel Punkt instrumentation Punkt Name Punkt enabled auf false.
8:18 Damit schalten Sie genau eine Instrumentierung ab, ohne die anderen anzufassen. Der Hinweis in der Fußzeile ist der eigentliche Punkt: Gezielt abschalten ist besser, als später pauschal zu filtern. Denn wenn Sie im Collector filtern, sind die Daten bereits entstanden, durchs Netz gegangen und haben Rechenzeit gekostet. Was gar nicht erst entsteht, ist immer die günstigere Variante.
8:42 Diese Gegenüberstellung ist eine Entscheidungshilfe, keine Alternative. Links die automatische Instrumentierung: technische Grenzen, ohne Codeänderung, konventionsgerechte Namen, sofort verfügbar. Rechts die manuelle: fachliche Vorgänge, im Anwendungscode, mit eigenen Namensräumen, Aufwand je Vorgang. Der Fehler, den man hier machen kann, ist die Wahl.
9:04 Es gibt keine Wahl — Sie brauchen beides. Die automatische liefert das Gerüst, die manuelle die Fachlichkeit. Wer nur das eine hat, sieht entweder keine Dienstgrenzen oder keine Geschäftsvorgänge. Und das ist die gute Nachricht dieses Moduls: Sie müssen nicht raten, was fehlt. Der Agent sieht, dass ein Endpunkt langsam war, nicht welcher Schritt darin.
9:26 Er sieht keine fachlichen Fehler ohne technischen Fehlerstatus — eine abgelehnte Rücknahme ist für ihn eine erfolgreiche HTTP-Antwort. Und fachliche Kennzahlen wie abgelehnte Behälter entstehen nur manuell. Diese drei Lücken sind vorhersehbar, also planbar. Deshalb ergänzt Modul sechs genau sie — und ersetzt den Agent ausdrücklich nicht.
9:47 Der erste Punkt ist der teuerste Denkfehler: Der Agent wird abgeschaltet, sobald man anfängt, manuell zu instrumentieren. Damit verlieren Sie sämtliche Dienstgrenzen und bauen sie mühsam von Hand nach. Der zweite ist die pauschale Deaktivierung, bei der Nützliches mitverschwindet. Der dritte ist ein Betriebsthema, das man messen sollte statt zu vermuten.
10:08 Und der vierte ist eine Erwartungshaltung, die immer enttäuscht wird: dass der Agent fachliche Fragen beantwortet. Kein Werkzeug kennt Ihr Geschäft — das ist keine Lücke im Produkt, sondern eine Aufgabe für Sie.
Übung
10:21 In der Übung bringen Sie alle drei Pfandwerk-Dienste zum Senden — ohne eine Zeile Code zu ändern. Und Sie beantworten am Ende eine Frage, die für den weiteren Verlauf wichtiger ist als der Datenfluss selbst: Was fehlt noch? Achten Sie dabei weniger auf die Menge der Daten als auf ihre Zuordenbarkeit. Ein Trace, der den richtigen Dienstnamen trägt, ist mehr wert als zehn Traces ohne Herkunftsangabe — das ist die praktische Probe auf Modul vier.
10:47 Drei Erfolgskriterien. Erstens senden alle drei Dienste Traces und Metriken an den Collector. Zweitens tragen sie die Resource-Attribute aus Modul vier — das ist die Nagelprobe für den Vertrag, den Sie dort geschrieben haben. Und drittens ist eine Rücknahme als zusammenhängender Trace sichtbar. Falls dieser dritte Punkt nicht klappt: Das ist kein Fehler Ihrerseits, sondern das Thema von Modul sieben.
11:11 Notieren Sie anschließend, welche Frage aus Modul eins jetzt beantwortbar ist und welche nicht. Diese Notiz ist die Arbeitsvorlage für Modul sechs. Die fünf Schritte folgen dem Weg der Daten. Erst das Agent-JAR bereitstellen und anhängen, dann die Identität setzen — Servicename und Resource-Attribute je Dienst. Danach das Ziel: OTLP-Endpunkt und Protokoll auf den Collector richten. Dann lösen Sie eine Rücknahme aus und prüfen im Collector, was angekommen ist.
11:39 Und im fünften Schritt halten Sie fest, was offen bleibt. Dieser letzte Schritt sieht nach Formalität aus, ist aber der eigentliche Ertrag der Übung: eine konkrete Liste dessen, was manuelle Instrumentierung leisten muss. Der erste Punkt ist erwartbar und kein Grund zur Sorge — der Trace bricht zwischen zwei Diensten ab. Das ist genau das Problem, dem Modul sieben gewidmet ist.
12:02 Der zweite passiert, wenn man die Konfiguration im ersten Dienst sorgfältig macht und bei den anderen kopiert, ohne anzupassen. Der dritte ist eine Haltung, die sich durch das ganze Seminar zieht: Erfolg misst sich nicht an der Datenmenge, sondern an einer beantworteten Frage. Und der vierte ist der Health-Endpunkt, der alles überdeckt — das lässt sich schon hier abschalten, nicht erst im Collector.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →