Hi auch;
Am 10.04.19 um 17:54 schrieb Konrad Rosenbaum:
a) Du hast genug Druckmittel gegenüber den Programmierern - aber auf der Negativseite hast Du dann auch eine große Fluktuation. Zumindest wenn der Rest der Arbeitsumgebung nicht absolut phantastisch ist.
b) Du hast hinreichende Mengen an Bestechungsschokolade. Und dann funktioniert das auch nur für kurze Fristen.
Carrot and sticks, glaube ich... Kekse und Schokolade schaden zumindest nie. Aber wenn im x-ten Sprint vor Release *wieder* ein kritischer Blocker in die Entwicklung eskaliert wird, Deine Planung zerschlägt, die internen Nutzer mit Fackeln vor der Bürotür stehen und Köpfe fordern (unter Umständen auch Deinen), Du *wiederkehrend* in kurzer Folge die 500er-Meldungen in den Logs des Loadbalancers siehst (jede ein unzufriedener Nutzer) und Du *überhaupt* keine Idee hast, warum das genau passiert, dann kann das auch läuternd sein.
Auf diese Weise haben wir bei uns sogar vergleichsweise verwegene Wünsche ins Logging bekommen, etwa eine Request-ID, die über Systemgrenzen hinweg mitgegeben wird, um am Ende irgendwie zusammenbekommen, *welche* Komponente an welcher Stelle denn nun in dem Prozess Ärger gemacht hat. Oder auch zipkin quer über den Stack, um bekannt problematischen Stellen zu messen, wo wieviel Zeit verbrennt. Verteiltes Profiling ist mindestens genau so wenig erfreulich wie verteiltes Logging, das war Frickelei par excellence, hat sich aber mehr als gelohnt. ;)
Wenn man diesen Koloss in eine einzige Zeile packen kann, dann gerne.
Also sowas: Logging.debug("frobnicating...",LV(size),LV(resultSize));
Die Menge an Templates, Macros und anderen unschönen Konstrukten hinter "LV" kehren wir mal ganz gekonnt unter den Teppich...
Ja. Schon. Aber (um in Java zu bleiben): Wenn ich
System.err.println("ERR: FOO failed... " + ex.getMessage());
schreibe, habe ich genau das: "FOO failed..." in einer Zeile Text, bestenfalls noch mit einem Timestamp, wenn ich gegen syslog oder via docker logge, schlimmstenfalls nichtmal das. Und ich muss den Loglevel händisch mitgeben.
Wenn ich ein Framework wie logback nutze, wird daraus etwas wie
LOG.error("FOO failed...", ex);
und in der Konsequenz auch nur eine Textnachricht, aber das Logging-Framework hat out of the box schon *deutlich* mehr Kontext, der an dieser Nachricht hängt und den ich auswerten kann (auch wenn ich das zeilenorientiert in ein Textfile wegschreibe): Klassenname, Thread des Prozesses, definierte Loglevel, Handling der 'reingestopften Exception und dergleichen mehr. Wenn ich das bei der STDOUT-Variante in jedem Aufruf mitgeben müsste, wäre das auch beizeiten nervig, würden die Entwickler wohl anfangen, sich Wrapper um STDOUT/STDERR zu bauen und damit letztlich ein eigenes Logging-Framework implementieren. Die Mühe kann man sich wohl schenken. ;)
Darüber hinaus habe ich auch "Vereinfachungen", die mir erlauben, eben Konstrukte wie die oben benannte Request-Id für einen bestimmten Scope einmal in den Logger zu packen und nicht jedes Mal wieder schreiben zu müssen. Das ist Einmal-Aufwand im Einstieg, der sich aber, glaube ich, relativ schnell lohnt.
Interessant by the way: Bei Kram, der in docker-Containern läuft, scheint es insgesamt mehr und mehr Standard zu werden, aus der Anwendung heraus auch nicht mehr in Log*files*, sondern tatsächlich nur noch nach STDOUT/STDERR zu schreiben und sich darauf verlassen, daß docker die Logs in geeigneter Weise $IRGENDWOHIN tut - im Standardfall syslog.
Du wirst mich gleich hassen: ich liebe diese Lösung! Das ist doch mal was für faule Programmierer! Ich brauche noch nicht einmal ein minimales Log-Framework lernen.
Du wirst überrascht sein, aber dort bin ich voll bei Dir. Eigentlich sollte man in 2019 über Logging als Entwickler nicht mehr diskutieren müssen. So gesehen finde ich den Weg, eine Komponente wie docker oder andere Infrastruktur für Logging-Ausgabe verantwortlich zu machen, auch gar nicht abwegig, auch in der Anbindung an so etwas wie Logstash/ElasticSearch als Alternative oder auch parallel zu lokalen Logfiles. Auch docker kann Logs in andere Systeme ausliefern und andere Formate als nur textuelle Logfiles bedienen.
Das Framework kann aber (siehe oben) dem Entwickler helfen, "schlankeren" Code zu schreiben, wenn viele Informationen geloggt werden müssen. Und am Ende des Tages ist ja auch die Frage: Ist Logfile zwingend gleich zeilenorientiertes ASCII? Man könnte ja auch JSON-Strings in lange Log-Zeilen schreiben oder (*hüstel*) kryptisches XML, wie unsere SAP MaxDB das zu tun pflegt. Wenn ich es "richtig" anstelle, dann ist aber auch nichts, womit sich der Entwickler zwingend behängen muss. Dann habe ich aber daraus auch keinen Ärger, weil es außerhalb der Einflußnahme von denen ist, die den Prozess dahinter potentiell nicht vorsätzlich, aber unbedacht kaputtmachen. Das hilft auch allen. ;)
Viele Grüße, Kristian