关于java:为什么没有登录异常堆栈跟踪?

Why is the exception stack trace not logged in?

本问题已经有最佳答案,请猛点这里访问。

我尝试了SLF4J常见问题解答中的简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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);

        }
    }
}

以下是输出:

1
2
15:33:51,248000000 [SEVERE]simplelogger: Failed to format Hello world
15:33:51,275000000 [SEVERE]simplelogger: Without parametrized string

我使用java.util.logging作为日志记录实现,具有以下logging.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 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

我期望看到异常的stacktrace。配置中是否缺少某些内容?我应该通过slf4j或jdk日志以某种方式启用异常strack跟踪吗?

按照"标记为重复"进行编辑。我的问题不是"如何打印堆栈跟踪",而是如何使用slf4j的例子来打印堆栈跟踪,我仍然没有打印出堆栈跟踪。正如我所说,我使用log4j作为实现打印了堆栈跟踪,但不使用java.util.logging。所以这确实是java.util.logging配置错误的问题,当我发现的时候我给出了一个答案。


实际上,正确配置日志记录的格式化程序是一个问题。

正如手册所说,throwable是方法格式的第6个参数。因此,我在logging.properties中的格式中添加了%6$s

1
java.util.logging.SimpleFormatter.format=%1$tT,%1$tN [%4$s]%3$s: %5$s %6$s %n

下面是输出,显示堆栈跟踪:

1
2
3
4
5
6
7
8
9
10
11
12
13
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)


java.lang.Exception.toString()不返回堆栈跟踪信息。从文档中:

Returns a short description of this throwable

看看如何将堆栈跟踪转换为字符串?然后记录你回来的String