# Logging mit log4j: Laufzeitfehler in Datei umleiten?



## DarthShader (18. April 2008)

Hallo,

ich habe eine Frage zum Logging mit log4j. Ich habe mir einiges an Dokumentation zu log4j durchgelesen und nun auch eine eigene XMK Konfiguration erstellt, was soweit funktionioert.

Was ich mich nun frage, ist folgendes:

Wenn das Programm irgendwann mal auf einem anderen Rechner läuft und man die Konsole nicht sieht (sondern nur die mit Swing erstellte Oberfläche), und nun passiert irgendeine Exception, z.B. eine NullPointerException, ist es möglich dann diese inkl. dem StackTrace in die Log-Datei zu schreiben?

Ich weiß natürlich, dass ich mit einem FileAppender log Meldungen in eine Datei schreiben kann, aber das mache ich bisher immer manuell mit z.B. "logger.warn(...)". Ich möchte jedoch jegliche Exceptions, die ein Programm wirft, in der Log-Datei haben, um diese ggf. bei einem unerwarteten Verhalten auswerten zu können.

Wie bekomme ich das hin?


Vielen Dank für Eure Hilfe!


----------



## Klein0r (18. April 2008)

Ich habe zwar keine Ahnung was log4j ist aber ich würde einfach den err stream in eine datei umleiten 


```
try {
PrintStream fileStream = new PrintStream(new FileOutputStream("C:\\temp\\trace.txt"));
System.setOut(fileStream);
System.setErr(fileStream);
} catch (FileNotFoundException fnfe) {
} catch (SecurityException se) {
}
```

(Code von einer anderen Seite - also keine Garantie...)


----------



## zeja (18. April 2008)

Hmm ich skizzier mal wie ich das machen würde, weil ich gerade keine Zeit hab das zum implementieren:

Mit
Logger.getRootLogger().getAllAppenders()
alle Appender holen.

Dann implementierst du dir ne eigene PrintStreamKlasse welcher du die ganzen Appender übergibst. Mit System.setError setzt du dann deine PrintStream Klasse. Immer wenn etwas auf deine Klasse geschrieben wird leitet du das an alle Appender weiter in dem du über die Liste iterierst und auf jedem Appender doAppend mit einem LoggingEvent aufrust welches du dir mit dem zu loggenden Text erstellen mußt.


----------



## DarthShader (18. April 2008)

Klein0r hat gesagt.:


> Ich habe zwar keine Ahnung was log4j ist aber ich würde einfach den err stream in eine datei umleiten



Hm ja, die Lösung ist recht trivial  Ich würde es lieber etwas gemanagter haben, eben mit log4j.



zeja hat gesagt.:


> Hmm ich skizzier mal wie ich das machen würde, weil ich gerade keine Zeit hab das zum implementieren:
> ....



Der Plan klingt doch schonmal gar nicht schlecht. Ich frage mich eben, ob das so eine komplizierte Sache ist, denn viele Programme machen es ja so. "Passiert" etwas bei Eclipse an Exceptions, landet das ja auch in dessen Log-Datei.

Was ich nur nicht möchte ist ein exklusives Schreiben in die Datei, ich will es schon noch auf der Konsole ausgegeben haben. Aber wenn ich ich den Standard-Out-Stream mit System.setErr ändere, dann müsste ich in meinem eigenen PrintStream ha die Ausgabe nicht nur an die Appender, sondern auch an der Konsole ausgeben. Aber wie schreib ich ohne "System.err" etwas auf den Standard-Fehler-Ausgabestrom?

Ich bin ein wenig verwirrt  Geht die Sache nicht einfacher?


----------



## zeja (19. April 2008)

Ich weiß nicht obs einfacher geht... habe allerdings nichts anderes gefunden. Allerdings kannst du recht einfach auch noch zusätzlich auf die Konsole schreiben: Merk dir den alten PrintStream vom System bevor du ihn überschreibst und nutze diesen weiterhin. Sofern es dann überhaupt noch Sinn macht was auf die Konsole zu schreiben?


----------



## DarthShader (19. April 2008)

zeja hat gesagt.:


> Ich weiß nicht obs einfacher geht... habe allerdings nichts anderes gefunden.



Eigentlich dürfte es ja auch nicht anders gehen. Wenn ich eine Exception nicht fange, wird sie an das Laufzeitsystem weitergegeben, welches das auf den Standardfehlerausgabestrom schreibt. Demnach kann man das ja nur mit System.setErr umleiten. Wahrscheinlich ist das Humbug und gleich kommt noch jemand rein, der mich gehörig zurechtweist 



zeja hat gesagt.:


> Allerdings kannst du recht einfach auch noch zusätzlich auf die Konsole schreiben: Merk dir den alten PrintStream vom System bevor du ihn überschreibst und nutze diesen weiterhin. Sofern es dann überhaupt noch Sinn macht was auf die Konsole zu schreiben?



Oh ja, das stimmt natürlich. Sinn für mich macht es nur deshalb, weil ich dann zwischen Debug/Entwicklersystem und Produktivsystem nicht noch unterscheiden muss. Bei Letzterem wird die Konsole nur eben nicht angezeigt.

Ich denke ich werde es auch so machen - deshalb danke für den guten Tipp!


----------

