问题描述
在我一直从事的每个项目中,日志文件总是变得太大的问题. 架子解决方案的快速解决方案是使用log4j RollingFileAppender并设置允许的最大尺寸. 但是,在某些情况下,在有人手动介入之前,相同的例外反复迅速达到最大尺寸.在这种情况下,由于滚动政策,您最终会失去例外情况下发生的重要事件的信息. 有人可以建议解决这个问题吗?
P.S.我能想到的是,握住Exceptions>的缓存发生了,因此,当相同的例外重新占用时,我不会记录大量的堆叠线线.我仍然认为这一定是一个众所周知的问题,我不想重新发明轮子.
推荐答案
有两个方向可以从:系统侧和开发侧.从系统端处理此问题(即部署并运行应用程序之后)已经有几个答案.但是,我想解决发展方面.
我看到的一个非常常见的模式是在每个级别上记录异常.我看到UI组件,EJB,连接器,线程,辅助类,POJOS等,记录发生的所有例外.在许多情况下,不用费心检查日志级别.这是您遇到的确切结果,并且进行调试和故障排除需要比必要的时间更多的时间,因为人们必须筛选所有错误的重复.
我的建议是在代码中执行以下操作:
-
思考.并非每个例外都是致命的,而且在许多情况下,实际上无关紧要(例如,从close()从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! } } }
其他推荐答案
使用"滚动文件appender"达到指定的大小后,请使用log4j功能来缩放日志文件.对于1MB文件,ZIPS约为85KB.
为此,指定触发策略根据尺寸划线并在滚动策略中指定zip文件.
让我知道您是否需要信息.
其他推荐答案
根据我的经验,记录被用作适当测试和调试代码的替代品.程序员对自己说:"我不能确定此代码有效,所以我会在其中撒登录消息,因此当它失败时,我可以使用日志消息来弄清楚出了什么问题."
不仅将日志记录消息撒在没有思考的情况下,而是将每个日志消息视为软件用户界面的一部分. DBA,网站管理员或系统管理员的用户界面,但仍是用户界面的一部分.每条消息都应该做一些有用的事情.该消息应刺激采取行动,或提供他们可以使用的信息.如果消息没有用,请不要记录.
给出每个消息的适当记录级别.如果消息没有描述实际问题,并且没有提供通常有用的状态信息,则该消息可能仅对调试有用,因此将其标记为调试或跟踪消息.您通常的log4j配置根本不应写那些消息.更改配置仅在调试问题时才编写它们.
您提到这些消息是由于经常发生的例外.并非所有异常都表示程序中的错误,甚至表明程序操作中的问题.您应该记录所有的异常,以指示程序中的错误,并为其记录堆栈跟踪.在许多情况下,几乎您需要解决该错误的原因.如果您担心的例外是由于错误所致,那么您将重点放在错误的问题上:您应该修复错误.如果例外没有指示程序中的错误,则不应为其记录stackTrace. StackTrace仅对试图调试问题的程序员有用.如果例外根本没有表明问题,则根本不需要记录它.
问题描述
In every project I've been working on there's always been the issue of log files becoming too large. A quick off the shelf solution was to use the Log4j RollingFileAppender and set the maximum size allowed. However there are situations when the same exception happens repeatedly reaching the maximum size very quickly, before somebody manually intervenes. In that scenario because of the rolling policy you end up losing information of important events that happened just before the exception. Can anybody suggest a fix for this issue?
P.S. Something I can think of is to hold a cache of the Exceptions happened so far, so that when the same Exception re-occurs I don't log tons of stacktrace lines. Still I think this must be a well-known issue and I don't want to reinvent the wheel.
推荐答案
There are two directions to approach this from: The System side and the development side. There are several answers already around dealing with this from the system side (i.e. after the application is deployed and running). However, I'd like to address the development side.
A very common pattern I see is to log exceptions at every level. I see UI components, EJB's, connectors, threads, helper classes, pojos, etc, etc, logging any and all exceptions that occur. In many cases, without bothering to check for the log level. This has the exact result you are encountering as well as making debugging and troubleshooting take more time than necessary as one has to sift through all of the duplication of errors.
My advice is to do the following in the code:
THINK. Not every exception is fatal, and in many cases actually irrelevant (e.g. IOException from a close() operation on a stream.) I don't want to say, "Don't log an exception," because you certainly don't want to miss any issues, so at worst, put the log statement within a conditional check for the debug level
if(logger.isDebugEnabled()){
// log exception
}Log only at the top level. I'm sure this will meet with some negativity, but my feeling is that unless the class is a top-level interface into an application or component, or the exception ceases to be passed up, then the exception should not be logged. Said another way, if an exception is rethrown, wrapped and thrown or declared to be thrown from the method, do not log it at that level.
For example, the first case is contributing to the issue of too many log statements because it's likely the caller and whatever was called will also log the exception or something statement about the error.
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); } }
Since we are throwing it, don't log it.
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); } }
However, if something halts the propagation of the exception, it should log it.
public void something(){ try{ // stuff that throws some exception }catch(SomeException e){ if(logger.isLogLevelEnabled(Log.INFO)){ logger.error(e); // DEFINITELY LOG! } } }
其他推荐答案
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.
其他推荐答案
In my experience, logging is used as a substitute for proper testing and debugging of code. Programmers say to themselves, "I can't be sure this code works, so I'll sprinkle logging messages in it, so when it fails I can use the log messages to figure out what went wrong."
Instead of just sprinkling logging messages around without thought, consider each log message as part of the user interface of your software. The user interface for the DBA, webmaster or system administrator, but part of the user interface nonetheless. Every message should do something useful. The message should be a spur for action, or provide information that they can use. If a message could not be useful, do not log it.
Give an appropriate logging level for each message. If the message is not describing an actual problem, and is not providing status information that is often useful, the message is probably useful only for debugging, so mark it as being a DEBUG or TRACING message. Your usual Log4J configuration should not write those messages at all. Change the configuration to write them only when you are debugging a problem.
You mention that the messages are due to an exception that happens often. Not all exceptions indicate a bug in the program, or even a problem in the operation of the program. You should log all exceptions that indicate a bug in your program, and log the stack trace for them. In many cases that is almost all you need to work out the cause of the bug. If the exception you are worried about is due to a bug, you are focusing on the wrong problem: you should fix the bug. If an exception does not indicate a bug in your program, you should not log a stacktrace for it. A stacktrace is useful only to programmers trying to debug a problem. If the exception does not indicate a problem at all, you need not log it at all.