在 Tomcat 的 Web 应用程序中记录所有抛出的异常

Posted

技术标签:

【中文标题】在 Tomcat 的 Web 应用程序中记录所有抛出的异常【英文标题】:Logging all thrown Exceptions in a web application in Tomcat 【发布时间】:2013-10-30 13:00:42 【问题描述】:

您知道任何方法来记录所有在 java 中抛出的异常(无论是否捕获和处理)?

这是我的问题:有一个应用程序,我无法更改,有时它在创建锁定文件时遇到问题(下面的相关代码)。当它调用 tryLock() 方法时,冻结 30 秒(尽管 tryLock 是非阻塞的),然后返回失败 (CANT_CREATE_LOCK)。如您所见,所有捕获层都掩盖了真正的问题,甚至没有记录它。

final File lockFile = new File(fooHomeDir, ".foo-home.lock");
try

    FileOutputStream stream = new FileOutputStream(lockFile);
    try
    
        if (stream.getChannel().tryLock() == null)
        
            return LockResult.HELD_BY_OTHERS;
        
        this.fileOutputStream = stream;
        this.lockFile = lockFile;
        return LockResult.OK;
    
    catch (OverlappingFileLockException overlappingFileLockException)
    
        return LockResult.HELD_BY_OTHERS;
    
    catch (IOException ie)
    
        return LockResult.CANT_CREATE_LOCK;
    

catch (FileNotFoundException fnfe)

    return LockResult.CANT_CREATE_LOCK;

我希望:能够看到异常的详细信息。

其他信息:

环境为 Linux、Java 1.7、Tomcat 7。 fooHomeDir 指向一个 NFS 支持的挂载点。 fooHomeDir 的权限没有改变。 fooHomeDir 的所有者没有改变。 fooHomeDir 的文件系统未满。 没有 SELinux 或其他可能干扰的东西。

基本上,它以前有效,并且“突然”和“无故”停止。所以我现在正在调查。

我正在开始对应用程序进行远程调试,但在此之前,欢迎提出建议 :-)

谢谢, 乔

更新

为了记录,问题的根本原因是 rpc.statd 守护进程死亡。 因此,本机锁定机制在 NFS 上失败了。 症状是带有以下消息的 IOException:“没有可用的锁”。

向汉斯·梅斯致敬

【问题讨论】:

【参考方案1】:

您可以创建自己的异常实现,它将记录创建的每个错误。然后使用-Xbootclasspath:bootclasspath 标志将其添加到类路径中。我不建议将其作为“最佳实践”,但至少您可以找到问题的根源。

一个非常简单的例子(还有改进的余地)

package java.lang;

public class Exception extends Throwable 

public Exception() 
    super();
    String exception = "Exception";
    logWithStack(exception);



public Exception(String message) 
    super(message);
    logWithStack(message);


public Exception(String message, Throwable cause) 
    super(message, cause);
    logWithStack(message);


public Exception(Throwable cause) 
    super(cause);
    logWithStack(cause.getMessage());


protected Exception(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) 
    super(message, cause, enableSuppression, writableStackTrace);
    logWithStack(message);


private void logWithStack(String exception) 
    System.out.println(exception);
    for (StackTraceElement ste : Thread.currentThread().getStackTrace()) 
        System.out.println(ste);
    

编译成类文件,然后将 -Xbootclasspath:/directoryWhereClassFileIsLocated/ 添加到 tomcat 选项中。

【讨论】:

我将此标记为答案,因为这有助于我找到根本原因。

以上是关于在 Tomcat 的 Web 应用程序中记录所有抛出的异常的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat记录-tomcat常用配置详解和优化方法

Tomcat会话超时时怎样记录操作日志,满足安全审计要求

servlet抛出运行时异常时如何在浏览器中显示用户友好的错误页面?

Tomcat 管理器中的 Web 应用程序版本

JavaWeb对于JavaWeb的基本了解和Tomcat配置

stop tomcat web application 优雅地关闭所有 servlet 连接