I tried the simple example from SLF4J FAQ:
package com.aed.tests.logging;
import org.slf4j.LoggerFactory;
public class TestLogging
{
public TestLogging()
{
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args)
{
String s = "Hello world";
try
{
Integer i = Integer.valueOf(s);
}
catch(NumberFormatException e)
{
LoggerFactory.getLogger("simplelogger").error("Failed to format {}", s, e);
LoggerFactory.getLogger("simplelogger").error("Without parametrized string", e);
}
}
}
Here is the output:
15:33:51,248000000 [SEVERE]simplelogger: Failed to format Hello world
15:33:51,275000000 [SEVERE]simplelogger: Without parametrized string
I use java.util.logging as the logging implementation, with the following logging.properties
# Properties file which configures the operation of the JDK
# logging facility.
# The system will look for this config file, first using
# a System property specified at startup:
#
# >java -Djava.util.logging.config.file=myLoggingConfigFilePath
#
# If this property is not specified, then the config file is
# retrieved from its default location at:
#
# JDK_HOME/jre/lib/logging.properties
# Global logging properties.
# ------------------------------------------
# The set of handlers to be loaded upon startup.
# Comma-separated list of class names.
# (? LogManager docs say no comma here, but JDK example has comma.)
handlers=java.util.logging.ConsoleHandler
# Default global logging level.
# Loggers and Handlers may override this level
.level=ALL
# Loggers
# ------------------------------------------
# Loggers are usually attached to packages.
# Here, the level for each package is specified.
# The global level is used by default, so levels
# specified here simply act as an override.
# myapp.ui.level=ALL
# myapp.business.level=CONFIG
# myapp.data.level=SEVERE
# Handlers
# -----------------------------------------
# --- ConsoleHandler ---
# Override of global logging level
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
# HH:MM:ss,nanosec
java.util.logging.SimpleFormatter.format=%1$tT,%1$tN [%4$s]%3$s: %5$s %n
I expected to see the stacktrace of the exception. Am I missing something in the configuration? Shall I enable exception strack trace somehow, with SLF4J or jdk logging?
EDIT Following the "Marked as duplicate". My question was not "how to print the stack trace" but how comes, using the very example of SLF4J which itself does the job to print out the stack trace, I still had no stack trace printed out. As I said I had the stack trace printed out using log4j as implementation but not java.util.logging. So it was indeed a matter of wrong configuration of java.util.logging, and I gave an answer when I found out.
It was indeed a matter of properly configuring the formatter for log records.
As the manual says, the throwable is the 6th parameter of the method format. So I added %6$s
to my format in logging.properties:
java.util.logging.SimpleFormatter.format=%1$tT,%1$tN [%4$s]%3$s: %5$s %6$s %n
And here is the output, showing the stack trace:
17:29:33,314000000 [SEVERE]simplelogger: Failed to format Hello world
java.lang.NumberFormatException: For input string: "Hello world"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.valueOf(Integer.java:582)
at com.aed.tests.logging.TestLogging.main(TestLogging.java:15)
17:29:33,344000000 [SEVERE]simplelogger: Without parametrized string
java.lang.NumberFormatException: For input string: "Hello world"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.valueOf(Integer.java:582)
at com.aed.tests.logging.TestLogging.main(TestLogging.java:15)