为啥没有登录异常堆栈跟踪? [复制]

Posted

技术标签:

【中文标题】为啥没有登录异常堆栈跟踪? [复制]【英文标题】:Why is the exception stack trace not logged in? [duplicate]为什么没有登录异常堆栈跟踪? [复制] 【发布时间】:2014-02-05 13:04:45 【问题描述】:

我尝试了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);

        
    

这是输出:

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

# 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

我希望看到异常的堆栈跟踪。我在配置中遗漏了什么吗?我应该以某种方式启用异常跟踪跟踪,使用 SLF4J 或 jdk 日志记录吗?

EDIT 在“标记为重复”之后。 我的问题不是“如何打印堆栈跟踪”,而是如何使用 SLF4J 的例子来打印堆栈跟踪,我仍然没有打印出堆栈跟踪。正如我所说,我使用 log4j 作为实现而不是 java.util.logging 打印了堆栈跟踪。所以确实是java.util.logging配置错误的问题,发现后给出了答案。

【问题讨论】:

刚刚尝试使用 log4j 作为实现,我确实得到了堆栈跟踪。那么JDK logging 是否无法记录堆栈跟踪? 我认为这被错误地记录为重复。日志框架不会也不应该要求您手动将异常格式化为堆栈跟踪字符串以记录堆栈跟踪。他们有重载的方法,这些方法采用 Throwable 并且应该输出堆栈跟踪,但这并不总是发生。 【参考方案1】:

这确实是为日志记录正确配置格式化程序的问题。

和manual says一样,throwable是方法格式的第6个参数。所以我在 logging.properties 中将%6$s 添加到我的格式中:

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

这是输出,显示堆栈跟踪:

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)

【讨论】:

以上是关于为啥没有登录异常堆栈跟踪? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的异常堆栈跟踪总是指向最后一个方法行?

为啥 android logcat 不显示运行时异常的堆栈跟踪?

当客户端甚至无法连接到 WCF 服务器时,为啥会出现“服务器堆栈跟踪”异常?

DLR - 为啥我的堆栈跟踪中没有显示调试信息?

Xcode 4.2/iOS 5 下控制台中没有异常堆栈跟踪?

Javascript 异常堆栈跟踪