我想在Log4j记录器中添加一些简单的方法,以便在我的应用程序中使用。
尝试这样做:
public class Logger extends org.apache.log4j.Logger
{
public Logger(Class type)
{
super(type.getName());
}
public void info(String format, Object... o)
{
info(String.format(format, o));
}
public void debug(String format, Object... o)
{
debug(String.format(format, o));
}
public void warn(String format, Object... o)
{
warn(String.format(format, o));
}
public void error(String format, Object... o)
{
error(String.format(format, o));
}
}
想象我应该能够像这样使用它:
public class TmpTest
{
public static void main(String[] args) throws Exception
{
// Note I'm not even using the special methods here
new Logger(TmpTest.class).warn("Test");
}
}
但我得到了NullPointerException
。
Exception in thread "main" java.lang.NullPointerException
at org.apache.log4j.Category.warn(Category.java:1004)
at no.nwn.productconfigurator.TmpTest.main(TmpTest.java:16)
我不能这样做吗?是否只有在我使用getLogger
类的Logger
工厂方法时才会执行一些缺少的初始化?
如果我无法扩展Logger类,我应该怎么做?
可能是关于log4j.xml的吗?以前从未使用过它,也没有自己写过。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="true">
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<appender name="ProductConfigurator" class="org.apache.log4j.DailyRollingFileAppender">
<!--
<param name="File" value="logs/ProductConfigurator.log" />
-->
<param name="File" value="/var/tomcat/logs/ProductConfigurator.log" />
<param name="Append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MMM-dd HH:mm:ss,SSS}. %5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<logger name="org.hibernate" additivity="false">
<level value="warn" />
<appender-ref ref="ProductConfigurator"/>
</logger>
<logger name="org.hibernate.type" additivity="false">
<level value="warn" />
<appender-ref ref="ProductConfigurator"/>
</logger>
<logger name="org.hibernate.SQL" additivity="false">
<level value="warn" />
<appender-ref ref="ProductConfigurator"/>
</logger>
<root>
<!-- all|trace|debug|info|warn|error|fatal|no -->
<priority value="info" />
<appender-ref ref="ProductConfigurator"/>
</root>
</log4j:configuration>
答案 0 :(得分:3)
category.repository
字段为null
。看一下源代码:
public void warn(Object message) {
if(repository.isDisabled( Level.WARN_INT))
return;
if(Level.WARN.isGreaterOrEqual(this.getEffectiveLevel()))
forcedLog(FQCN, Level.WARN, message, null);
}
要正确初始化Logger
,您应该使用LogManager
:
public static void main(String[] args) throws Exception
{
LogManager.getLogger(TmpTest.class.getName(), new LoggerFactory() {
@Override
public Logger makeNewLoggerInstance(String name) {
return new Logger(name);
}
}).warn("Test");
}
我使用自定义工厂实现来实例化您的记录器。并非创建记录器(Logger.getLogger(Class clazz)
)的经典方法使用LogManager
:
static public Logger getLogger(Class clazz) {
return LogManager.getLogger(clazz.getName());
}
如果您的项目中没有特定的约束,我建议您使用slf4j。它提供了您期望的方法:
logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
答案 1 :(得分:-1)
只需在所有对info,warn等的电话前添加super.
在以下代码中:
public void info(String format, Object... o) {
info(String.format(format, o));
}
当你调用info(String.format(format, o))
时,你以递归的方式调用同一个方法:第一个参数是格式化的字符串,第二个参数(var-args)是空的,所以当String.format
时再次调用,你得到一个NullPointerException。
因此你应该写这个:
public void info(String format, Object... o) {
super.info(String.format(format, o));
}