Ich benutze log4j mit Tomcat. Wenn ich Ausnahmen in meinen JSPs protokolliere, werden Servlets:
private Logger _log = Logger.getLogger(this.getClass());
...
try{...} catch (Exception e) {
_log.error("Error refreshing all prices", e);
}
Ich bekomme nur die erste Zeile der Ausnahme ohne Stacktrace.
17-Feb 17:37:45 ERROR AutoContrib: 175 - Ausnahme beim Veröffentlichen der CSV-Datei: java.lang.ArrayIndexOutOfBoundsException
Überhaupt nicht sehr hilfreich!
Meine Datei log4j.properties (/tomcat/common/classes/log4j.properties) sieht folgendermaßen aus:
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{dd-MMM HH:mm:ss} %5p %c{1}:%L - %m%n
log4j.appender.stdout.threshold=info
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.maxFileSize=5000KB
log4j.appender.file.maxBackupIndex=10
log4j.appender.file.File=${catalina.home}/logs/web.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{dd-MMM HH:mm:ss} %5p %c{1}:%L - %m%n
log4j.appender.file.threshold=info
log4j.rootLogger=debug, stdout, file
Antworten:
Eigentlich liegt es wahrscheinlich an einer Hotspot-Optimierung: Nachdem eine bestimmte Anzahl derselben Ausnahme ausgelöst wurde, wird der Ausdruck der Ablaufverfolgung beendet. Dies kann mit einem VM-Argument deaktiviert werden, siehe:
Von http://www.oracle.com/technetwork/java/javase/relnotes-139183.html :
Mehr hier:
http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/
quelle
Was Sie gepostet haben, sollte den Stack-Trace anzeigen, wie im Javadoc angegeben .
Beachten Sie, dass
logger.error(ex)
der Stack-Trace nicht protokolliert wird , wenn Sie keine Nachricht einfügen (und nur aufrufen ).quelle
Es gibt zwei überladene Methoden für die Fehlermethode.
logger.error(ex);
logger.error("some oops string ", ex);
Wenn Sie die erste Methode verwenden, wird nur der Name der Ausnahme gedruckt. Wenn Sie die 2. Methode verwenden, wird eine Meldung zusammen mit einer Ausnahme angezeigt, die eine vollständige Stapelverfolgung ähnlich der
e.printStackTrace()
Methode druckt .quelle
Wie oben von @Luhar beantwortet, kämpfte ich mit der gleichen Sache und schließlich funktionierte dies für mich; Das Gute an diesem Ansatz ist, dass wir nicht an Einstellungen auf Systemebene wie JVM oder Log4J basteln müssen, da wir nie wissen, dass dies zu neuen unerwarteten Überraschungen führen kann!
try { ... .. } catch (Exception er) { ByteArrayOutputStream os = new ByteArrayOutputStream(); er.printStackTrace(new PrintStream(os)); LOGGER.error(new String(os.toByteArray())); //LOGGER.error(er); }
quelle
Ich sehe nichts falsches an Ihrer Konfiguration. Versuchen Sie daher,
log4j
auf eine neuere (nicht unbedingt die neueste) Version zu aktualisieren .Obwohl dies in diesem Fall nicht das Problem ist, sollten Sie Ihre Logger erstellen
private static final
quelle
Ich habe den fillStackTrace-Aufruf nicht verwendet, daher kann ich nicht kommentieren, ob dies funktioniert. Ein anderer Ansatz besteht darin, eine kleine Methode zu verwenden, die den formatierten Text aus einer Ausnahme zurückgibt.
public static String getStackTrace(Exception e) { StringWriter sWriter = new StringWriter(); PrintWriter pWriter = new PrintWriter(sWriter); e.printStackTrace(pWriter); return sWriter.toString(); }
In Ihren Protokollcode könnten Sie schreiben:
logger.error("An exception occurred: " + Utils.getStackTrace(e));
quelle
Sie können diese Codezeilen in Ihren catch-Block einfügen.
catch (SQLException e) { CharArrayWriter cw = new CharArrayWriter(); PrintWriter w = new PrintWriter(cw); e.printStackTrace(w); w.close(); String trace = cw.toString(); log.error("This is complete stacktrace", trace); }
quelle
Verwenden Sie Ihr Codebeispiel:
private static final Logger _log = Logger.getLogger(MyClass.class); ... try{...} catch (Exception e) { //Change //_log.error("Error refreshing all prices", e); //To _log.error("Error refreshing all prices", e.fillInStackTrace()); }
Sie sehen alle Stapelverfolgung angezeigt.
PS. Machen Sie Logger zu einem Singleton ... (überprüfen Sie meine Erklärung) kurz nach der Erklärung
public class MyClass {
quelle