2010-11-23 3 views
3

In meiner Code-Basis ist die (sehr vereinfacht) folgende:Wie können Sysout- und Syserr-Streams vom Mischen abgehalten werden?

public static void main (String[] args) { 
    System.out.println("Starting application"); 
    try { 
     System.out.println("About to validate"); 
     validate(args); 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public static void validate(String[] args) { 
    System.out.println("Your first arg is " + args[0]); 
    if (someProblemWith(args)) { 
     System.out.println("Your args are wrong. It should be: ..."); 
     throw new BadArgsException(e); 
    } 
} 

die gut arbeitet. Beachten Sie, dass der obige Beispielcode erfunden ist und einfach dazu gedacht ist, mehrere Protokollanweisungen vor der Ausnahme und dem Stapeldruck anzuzeigen. Dies bedeutet oft, dass meine letzte Logging-Anweisung in der Mitte der Stack-Trace-Ausgabe verloren geht. Gibt es eine elegante Möglichkeit, die e.printStackTrace() Anweisung zu warten, bis die System.out ihre Arbeit beendet hat? Ich bin im Wesentlichen auf der Suche nach der Stacktrace, um die allerletzte Sache gedruckt werden, wenn ein Fehler auftritt. Hier ist ein Beispiel für die Ausgabe von meinem Programm über:

java.lang.Throwable 
.... 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
Your args are wrong. It should be: ... 
at java.lang.reflect.Method.invoke(Method.java:597) 
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56) 
+2

OMG! Du hast die Bäche überquert! Protonische Totalumkehr! –

Antwort

1

Anruf e.printStackTrace(System.out);. Oder, wenn Sie es nur zum Debuggen benötigen, können Sie die Ausgabe und den Fehler des Prozesses von der Befehlszeile trennen: .... 1>output.log 2>error.log

+0

Danke. Dies scheint die einfachste Option zu sein. –

8

Der Grund, warum Sie den Stack-Trace sehen, die zwischen den System.out.println() Aussagen gedruckt ist, weil System.out gepuffert wird, während System.err (verwendet von Stack-Trace) ungepufferte ist.

Wenn Sie möchten, dass der Text genau in der Reihenfolge angezeigt wird, in der die Dinge passieren, müssen Sie die System.out "unbuffered". Am einfachsten ist es auch, System.err dort statt System.out zu verwenden.

Ansonsten rufen Sie System.out.flush() bevor Ihre Stack-Spuren in den catch Klauseln passieren.

Option 2: Verwenden Sie die Klasse Logger.

Option 3: Implementieren Sie Ihren eigenen "Puffer". Mit anderen Worten, schreiben Sie zuerst alles in Ihren eigenen Puffer, einschließlich der Stack-Traces (mit .toString() oder wie Sie wollen) und dann in den catch eigenen Puffer spülen. (Dies ist irgendwie redundant, da Sie die System.out sowieso nur spülen können).

- == -

VON KOMMENTAR

Sicher. Die Logger Klasse kann verwendet werden, um eine viel robustere und detailliertere Protokollierungserfahrung zu erstellen. Dies wird typischerweise in Anwendungen durchgeführt. Eine Instanz der Logger-Klasse wird aus der Logger-Klasse (es ist ein Singleton) abgerufen, wobei als Parameter die Klasse verwendet wird, aus der is verwendet wird. Dann protokollieren Sie Nachrichten mit der Methode .log(). Das Schöne an der Klasse Logger ist, dass Sie Ebenen festlegen können (Beispiel DEBUG, WARN ...) und Sie können dann nur filtern/anzeigen, was Sie wollen. Die "log" Nachrichten werden dann in einer einheitlichen Art und Weise in der Konsole, in der Regel im Format angezeigt:

2010-11-23 14:45:32,032 DEBUG [MyClass] Your message

Das obige Format von log4j ist, aber Sie die Standard-Java Logger verwenden können. Die Ausgabe sollte ähnlich sein, vielleicht ein bisschen weniger. Aber ich bin sicher, dass es konfiguriert werden kann.

+0

Danke. Können Sie "Benutzer die Logger-Klasse" erweitern? –

Verwandte Themen