Performance-Logging (Webservices)

LimDul

Top Contributor
Ich bräuchte mal ein paar Ideen. Es geht um Enteprise-Anwendungen, Framework ist relativ egal (JavaEE und Spring-Boot wären die konkreten), halt irgendwas, was Dependency Injection kann.

Wir rufen an verschiedenen Stellen verschiedene externe System, in der Regel über Rest-Webservices (meist RestEasy als Client).

Ich würde jetzt gerne optional die Performance loggen, sprich wie lange braucht der Aufruf in das andere System. Interessiert bin ich an den Daten:
* MInimale Aufrufzeit
* Maximale Aufrufzeit
* Durchschnittliche Aufrufzeit

Das ganze würde per Schalter in irgendwo in externen properties ein/ausschaltbar sein.

Was ist da Best-Practice? Die Idee die ich jetzt hätte, wäre einfach die Zeit zu messen und dann in einer Datenbank Tabelle als Autonome Transaktion zu speichern. Problem hab ich etwas mit dem Durchschnitt. Ich will - aus denke ich nachvollziehbaren Gründen - nicht für jeden Aufruf eine Zeile schreiben, dass kann schnell viel zu viel werden. Das heißt, ich würde mir merken "durchschnitt" und "anzahlAufrufe". Dann kann natürlich damit den Durchschnitt immer fortschreiben (Neue Durchschnitt = (Anzahl Aufrufe*Alter Durchschnitt)+Neuer Aufruf)/(Anzahl Aufrufe+1). Da hätte ich aber die Sorge, dass der Durchschnitt aufgrund von Rundungen nicht mehr passt.

Werft mal Ideen in den Raum :)
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Also die Frage ist, wie hoch die Genauigkeit sein muss und wie wichtige diese Daten sind.

Idee 1: Zum einen kannst Du beim Speichern Nachkommastellen mit speichern. Also die Genauigkeit kannst Du entsprechend hoch schrauben.

Idee 2: Oder Du speicherst die Anzahl und die Summe in einem Zeitintervall. Dann hast Du pro Minute oder so nur einen Datensatz, der regelmäßig aktualisiert wird. Dann hast Du also ein Zeitintervall zu identifizieren (als long/bigint) und pro Wert hast Du Anzahl und Summe. Und zu denen addierst Du halt 1 bzw. den gemessenen Wert.

Idee 3: Wie Idee 2 aber die Datenbank bekommt die Requests nicht. Diese Intervalle sammelt das System und speichert diese periodisch, d.h. Du speicherst alle x Sekunden / Minuten. ==> Daten gehen ggf. verloren. Wenn Du z.B. nur alle 10 Minuten die Daten speicherst und der Prozess kommt nicht zum schreiben, dann sind ggf. Statistik-Daten von 10 Minuten weg!
Und dann berechnest Du immer nur für diese Abschnitte den Durchschnitt. Damit bist Du auch genauer, da Du nicht fortlaufend rechnest. Und die Anzahl der Datensätze sollte da auch nicht zu wild werden - 6 kleine Zeilen pro Stunde pro Außenverbindung wären das bei 10 Minuten ... also keine 150 Zeilen pro Tag ... im Jahr um 5000 Zeilen - da lacht eine Datenbank in der Regel zumal da ja auch nicht viele Daten stehen ... Selbst wenn pro Zeile 1KB speicherst sind das 50MB ... Also nicht wirklich eine Größenordnung.

Das wären so meine Ideen. Wobei Idee 1 einfach nur schaut, ob die Probleme mit der Genauigkeit wirklich so kommen oder ob das nur täuscht.

Idee 2 / 3 hat den Vorteil, dass Du in den Intervallen deutlich mehr speichern kannst. Min / max könnte z.B. Sinn machen.
 

LimDul

Top Contributor
Idee 2/3 gefällt mir.

Wichtig sind die Daten aktuell nicht. Aber ich glaube nicht das wir hier vernünftige Last- und Performance-Tests haben werden und die gesamte Anwendungslandschaft um uns ist auch in Bewegung. Ich würde drauf wetten, dass irgendwann die Meldung kommt "Das System ist zu langsam". Und dann würde ich gerne die Chance haben einfach einen Schalter umzulegen und dann eine belastbare Grundlage für eine Analyse zu haben. Zudem kämpfen wir auf den Testumgebungen mit nicht zur Verfügung stehenden Umsystemen, jeder Deployet wann er will (überspitzt formuliert) so dass bei Fehlern nicht klar ist - wirklich ein Fehler oder mal wieder die Umgebung instabil. Deswegen find ich Idee 2/3 auch so charmant - weil dann hab ich direkt eine Zeitraumbezogene Auswertung und sehe ob z.B. zwischen 9 und 10 Uhr immer Probleme mit einem System auftreten.
 

LimDul

Top Contributor
So mal als Idee in den Raum geworfen, die ich mir jetzt vorstelle:

Eine (In JEE) ApplicationScoped Bean, die folgende Signatur anbietet

Java:
puplic void protokolliereLaufzeit(String identifier, long laufzeitMs);
// Alternativ
puplic void protokolliereLaufzeit(String identifier, long startZeitMs, long endZeitMs);

Innendrin werden die sauber getrennt nach System protokolliert. Und alle X Minuten läuft ein scheduled Job, der die letzten X Minuten aggegriert pro System und dann wegschreibt in die Datenbank und/oder Logfile.

Ist das Feature deaktiviert, macht die Bean einfach nix. Hat für mich den Charme, dass ich überall wo ich über längere Zeit Laufzeiten messen will, nur die Bean injecten muss und Start & Endzeit messen muss.

Ich kann dann jederzeit in der Bean entscheiden:
* Wie granular protokolliere ich
* Was protokolliere ich
* Wohin protokolliere ich
 

LimDul

Top Contributor
Wir wärs mit Microprofile Metrics?
Ein klares Hmmmmm. :)

Ich muss mich da mal reinlesen, der erste Blick sagt mir:
- Es tut viele coole Dinge
- Es tut viel mehr als ich im ersten Schritt will (was positiv oder negativ sein)
- Ich hab keine Ahnung, was ich tun muss, damit das bei uns im Monolithen sauber läuft :)

Von daher definitiv danke, das ist auf jeden Fall einen Blick wert, auch wenn ich befürchte, dass der Aufwand dafür höher ist, als ich im Projekt vertreten kann. Aber mal gucken, vielleicht gibt es hier im Haus eh schon sowas wo man sich dran orientieren kann.
 

LimDul

Top Contributor
Nachdem ich jetzt erfahren habe, dass der Wunsch wäre das über einen Rest Service zur Verfügung zu stellen, sieht das immer mehr nach einer guten Lösung aus. Ich bin halt erstmal nur über die Doku geflogen, aber es scheint tatsächlich relativ einfach sein - ein paar Annotationen dran und fertig. (Mal gucken wie es in Praxis aussieht :D).

Ich muss mir jetzt eh erstmal das "GO" holen wie viel Zeit ich da rein versenken darf. Vielen Dank auf jeden Fall schon mal dafür.
 

mrBrown

Super-Moderator
Mitarbeiter
MicroProfile Metrics kann man dann noch mit MicroProfile OpenTracing kombinieren, je nach Art der beteiligen externen Systeme :)

Mal gucken wie es in Praxis aussieht :D
In der Praxis sieht das genauso aus, mehr als die entsprechende Annotation dran hängen ist's nicht. (Solange man einen unterstützen Application-Server nutzt, mit Wildfly klappt's auf jeden Fall problemlos).

Man muss halt zusätzlich wahrscheinlich noch irgendein externes Monitoring-System nutzen, aber das wird man ja bei jeder Variante brauchen. (Außer der Server bietet von Haus aus schon was entsprechendes.)
 

LimDul

Top Contributor
Jo, hier im Haus ist tatsächlich ein Monitoring System im Einsatz. Wildfly (bzw. JBoss EAP - aber ist ja im Endeffekt das gleiche) nutzen wir auch. Für Spring Boot würden wir das im zweiten Schritt auch nutzen wollen, aber da würde ich sogar noch eher erwarten, dass ich da nur die Dependency eintrage und Annotationen dran machen. Mal gucken ob es stimmt :)

Wird sich allerdings was hinziehen, weil so die höchste Priorität wird das Thema nicht haben - aber ich find es wichtig und würde es ungerne unter den Tisch fallen lassen.
 

Ähnliche Java Themen

Neue Themen


Oben