在不改变%C的情况下对org.apache.log4j.Logger进行子类化?

pru*_*mme 6 java log4j

启用类似的东西

logger.info("This is a formatted number: %.2f", number)
Run Code Online (Sandbox Code Playgroud)

我决定写一个子类org.apache.log4j.Logger.我知道,我本可以编写一个包装类来实现相同的结果但是因为我在运行时向记录器中添加了很多appender,所以我更喜欢使用继承.

子类看起来像这样:

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));
    }
}
}
Run Code Online (Sandbox Code Playgroud)

一切都很好 - 除了一件事之外:消息文本现在添加了记录器子类的名称,而不是调用记录器的类的名称.作为模式布局,我使用以下格式:

[%d{yyyyMMdd HHmmss}] %-5p [%t] %C: %m%n
Run Code Online (Sandbox Code Playgroud)

即事情看起来像这样:

[20110525 214515] INFO  [main] org.xyz.FormatLogger: This is a formatted number: 23.23
Run Code Online (Sandbox Code Playgroud)

代替:

[20110525 214515] INFO  [main] org.xyz.Main: This is a formatted number: 23.23
Run Code Online (Sandbox Code Playgroud)

有没有办法"正确"做这样的事情,以便"%C"继续打印原始的类名?

pru*_*mme 1

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

static String FQCN = FormatLogger.class.getName() + ".";
Run Code Online (Sandbox Code Playgroud)

然后必须像这样修改 log(..) 方法:

super.log(FQCN, level, String.format(formatter, args), null);
Run Code Online (Sandbox Code Playgroud)

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