关于Log4J日志丢失的疑问和解决
首先说,这不是个问题,只是我的不慎,导致它成了一个问题,并困扰了我很久. 故事是这样的:
我用spring + strut2 + hibernate 开发了一个系统, 日志是使用log4j 实现的,并在log4j.xml 中配置. 本来一切工作都很正常, 突然有一天,我发现有很多的debug日志没有输出, 导致我调试非常的困难. 在log4j.xml 中我确认打开了我的包的debug级输出, 并把其他包都设置为warn级.
配置并没有错误. 但事情发生了, pak 包中有个 action包,它下面全部都是继承xwork2.ActionSupport来的Action类,例如:
pak.action.BaseAction
pak.action.UserAction
pak.action.RoleAction
pak.action......OtherAction ...
pak.utils.StrUtil
pak.utils.DateUtil
其中BaseAction是所有其他Action类的父类. pak.utils包是另外一个包. 我发现pak.utils包及其他包中的日志都能输出, 而pak.action中无法输出,只有在 warn以上的才能输出.
为什么会这样? Log4j 不稳定? 不能吧. 那这些类有什么和其他包中有什么区别呢?
仔细研究发现: 在pak.utils包和其他包中的每个类都使用下面的方法来定义log对象.
private final Log log = LogFactory.getLog(this.getClass());
而在BaseAction中则为了简化代码, 直接使用了xwork2.ActionSupport中定义的LOG:
private final Log log = ActionSupport.LOG;
明白了, 因为我在log4j.xml 中把com.opensymphony 设置为warn级,导致ActionSupport的子类中都无法输出info/debug级日志.
总结:
不知道为什么log4j是这样的, 想来应该是因为在继承中使用父类的对象,而父类又被限制所致.
解决的办法, 当然是又使用了 private final Log log = LogFactory.getLog(this.getClass()); 这个方式.肯定不能把xwork2的日志级别改为debug, 否则就死定了.
在这之前, 我也曾经考虑过让其他包分别继承并使用spring, hibernate, org.apache.commons 中已经定义的log对象, 以便让系统可以统一的控制日志输出. 现在看来,这个方法不可取. 否则你将无法控制只输出你自己的包里的日志.
