Java 子类化org.apache.log4j.Logger而不更改%C?

Java 子类化org.apache.log4j.Logger而不更改%C?,java,log4j,Java,Log4j,使 logger.info("This is a formatted number: %.2f", number) 我决定编写一个子类org.apache.log4j.Logger。我知道,我本来可以编写一个包装器类来实现相同的结果,但是因为我在运行时向记录器添加了很多附加器,所以我更喜欢使用继承 子类如下所示: public final class FormatLogger extends Logger { private final static FormatLoggerFactory

使

logger.info("This is a formatted number: %.2f", number)
我决定编写一个子类
org.apache.log4j.Logger
。我知道,我本来可以编写一个包装器类来实现相同的结果,但是因为我在运行时向记录器添加了很多附加器,所以我更喜欢使用继承

子类如下所示:

public final class FormatLogger extends Logger {

private final static FormatLoggerFactory factory = new FormatLoggerFactory();

protected FormatLogger(String name) {
    super(name);
}

public static Logger getLogger(String name) {
    return Logger.getLogger(name, factory);
}

public void fatal(String formatter, Object... args)  {
    log(Level.FATAL, formatter, args);
}

public void log(Level level, String formatter, Object... args) {
    if (super.isEnabledFor(level)) {
        super.log(level, String.format(formatter, args));
    }
}
}
[20110525 214515] INFO  [main] org.xyz.FormatLogger: This is a formatted number: 23.23
super.log(FQCN, level, String.format(formatter, args), null);
一切都很好地工作——除了一件事:消息文本现在添加了logger子类的名称,而不是调用logger的类的名称。 作为图案布局,我使用以下格式:

[%d{yyyyMMdd HHmmss}] %-5p [%t] %C: %m%n
i、 e.事情是这样的:

public final class FormatLogger extends Logger {

private final static FormatLoggerFactory factory = new FormatLoggerFactory();

protected FormatLogger(String name) {
    super(name);
}

public static Logger getLogger(String name) {
    return Logger.getLogger(name, factory);
}

public void fatal(String formatter, Object... args)  {
    log(Level.FATAL, formatter, args);
}

public void log(Level level, String formatter, Object... args) {
    if (super.isEnabledFor(level)) {
        super.log(level, String.format(formatter, args));
    }
}
}
[20110525 214515] INFO  [main] org.xyz.FormatLogger: This is a formatted number: 23.23
super.log(FQCN, level, String.format(formatter, args), null);
而不是:

[20110525 214515] INFO  [main] org.xyz.Main: This is a formatted number: 23.23

是否有某种方法可以“正确”地执行此操作,以便“%C”继续打印原始类名?

我做了类似的操作,但最终创建了一个包装器并将类名传递给它。然后使用这个类名,我将它添加到我已经包装的所有4个日志级别的前面。这很乱,但我找不到其他的方法。现在,我的日志语句会显示记录器名称,然后是包/类名。这有点麻烦,但我宁愿有额外的信息而不是没有足够的信息。

解决方案非常简单:添加一个完全限定的类名(FQCN),即:

然后必须修改log(..)方法,如下所示:

public final class FormatLogger extends Logger {

private final static FormatLoggerFactory factory = new FormatLoggerFactory();

protected FormatLogger(String name) {
    super(name);
}

public static Logger getLogger(String name) {
    return Logger.getLogger(name, factory);
}

public void fatal(String formatter, Object... args)  {
    log(Level.FATAL, formatter, args);
}

public void log(Level level, String formatter, Object... args) {
    if (super.isEnabledFor(level)) {
        super.log(level, String.format(formatter, args));
    }
}
}
[20110525 214515] INFO  [main] org.xyz.FormatLogger: This is a formatted number: 23.23
super.log(FQCN, level, String.format(formatter, args), null);

log4j附带的示例MyLogger.java完美地展示了这一点-为了我自己的懒惰

删除FQCN字符串末尾的“.”,以便使用Log4J 1.2.16或更高版本正确登录。

您可以使用log5j,它是Log4J的包装器,提供了vararg样式的记录器接口。没有理由重新发明轮子。IHMO表示,对抛光产品的一个小小的添加并不是对轮子的重新发明。对我来说,切换到另一个库并迁移所有现有的log4j调用比添加几行代码要麻烦得多。当然,如果一个人开始一个新项目,使用log5j或logcenter是有意义的。别担心,我想我也错过了这个。我实际上做了同样的事情,但要复杂得多。感谢您指出这一点。次要补充:我可以在log4j版本1.2.15中使用此功能,但不能在版本1.2.16中使用此功能(在%C位置给我一个“?”。