2

在我从事的每个项目中,总是存在日志文件变得太大的问题。一个快速现成的解决方案是使用 Log4jRollingFileAppender并设置允许的最大大小。但是,在某些情况下,在有人手动干预之前,相同的异常会反复发生并很快达到最大大小。在这种情况下,由于滚动策略,您最终会丢失发生在异常之前的重要事件的信息。有人可以建议解决此问题吗?

PS我能想到的是保存Exceptions到目前为止发生的缓存,这样当再次发生相同的异常时,我就不会记录大量的堆栈跟踪行。我仍然认为这一定是一个众所周知的问题,我不想重新发明轮子。

4

5 回答 5

3

有两个方向可以解决这个问题:系统端和开发端。从系统方面(即在应用程序部署和运行之后)处理这个问题已经有几个答案。但是,我想谈谈开发方面。

我看到的一个非常常见的模式是在每个级别记录异常。我看到 UI 组件、EJB、连接器、线程、帮助类、pojo 等,等等,记录所有发生的异常。在许多情况下,无需费心检查日志级别。这具有您遇到的确切结果以及使调试和故障排除花费比必要更多的时间,因为必须筛选所有重复的错误。

我的建议是在代码中执行以下操作:

  • 思考。 并非每个异常都是致命的,而且在许多情况下实际上是无关紧要的(例如IOException,来自close()流上的操作。)我不想说“不要记录异常”,因为您当然不想错过任何问题,所以在最坏的情况下,将日志语句放在调试级别的条件检查中

    if(logger.isDebugEnabled()){
     // log exception
    }

  • 仅在顶层记录。 我确信这会遇到一些负面影响,但我的感觉是,除非类是应用程序或组件的顶级接口,或者异常不再被传递,否则不应记录异常。换句话说,如果异常被重新抛出、包装并抛出或声明为从方法中抛出,则不要在该级别记录它。

例如,第一种情况是导致日志语句过多的问题,因为它可能是调用者和被调用的任何东西也会记录异常或有关错误的某些语句。

public void something() throws IllegalStateException{
      try{
         // stuff that throws some exception
      }catch(SomeException e){
         logger.error(e); // <- NO because we're throwing one
         throw new IllegalStateException("Can't do stuff.",e);
      }
 }

既然我们正在扔它,请不要记录它。

 public void something() throws IllegalStateException{
      try{
         // stuff that throws some exception
      }catch(SomeException e){
         // Whoever called Something should make the decision to log
         throw new IllegalStateException("Can't do stuff.",e);
      }
 }

但是,如果something停止异常的传播,它应该记录它。

 public void something(){
      try{
         // stuff that throws some exception
      }catch(SomeException e){
         if(logger.isLogLevelEnabled(Log.INFO)){
            logger.error(e);                      // DEFINITELY LOG! 
         }
      }
 }
于 2013-12-13T15:11:04.207 回答
3

Use Log4J feature to zip the log file after a specified size is reached using "Rolling File Appender". Zips are around 85KB for a 1MB file. For this specify the trigger policy to zip based on size and specify the zip file in the rolling policy.
Let me know if you need for info.

于 2013-12-13T14:15:44.253 回答
2

以我的经验,日志记录被用作正确测试和调试代码的替代品。程序员对自己说:“我不能确定这段代码是否有效,所以我会在其中添加日志消息,这样当它失败时,我可以使用日志消息找出问题所在。”

与其不加思索地到处散布日志消息,不如将每条日志消息视为软件用户界面的一部分。DBA、网站管理员或系统管理员的用户界面,但仍然是用户界面的一部分。每条消息都应该做一些有用的事情。该信息应该是对行动的刺激,或提供他们可以使用的信息。如果一条消息没有用,请不要记录它。

为每条消息提供适当的日志记录级别。如果消息没有描述实际问题,并且没有提供通常有用的状态信息,则该消息可能仅对调试有用,因此将其标记为 DEBUG 或 TRACING 消息。您通常的 Log4J 配置根本不应该写入这些消息。仅在调试问题时更改配置以编写它们。

您提到这些消息是由于经常发生的异常引起的。并非所有异常都表明程序存在错误,甚至程序运行存在问题。您应该记录所有表明程序中存在错误的异常,并记录它们的堆栈跟踪。在许多情况下,这几乎就是您找出错误原因所需的全部内容。如果您担心的异常是由于错误引起的,那么您关注的是错误的问题:您应该修复错误。如果异常并不表示程序中存在错误,则不应为其记录堆栈跟踪。堆栈跟踪仅对尝试调试问题的程序员有用。如果异常根本不表示问题,则根本不需要记录它。

于 2013-12-14T11:01:02.967 回答
1

购买更大的硬盘驱动器并设置批处理以定期自动压缩旧日志。

(Zip 将检测重复的异常模式并非常有效地对其进行压缩)。

于 2013-12-13T14:10:13.143 回答
0

use the strategy if reach maximum size, append to the new log file. and run scheduler like everyday to wipe the old log file

于 2013-12-13T14:15:52.583 回答