Java日志框架,每个类都不需要LOGGER声明

时间:2016-02-24 03:56:59

标签: java logging log4j slf4j java.util.logging

我尝试了以下记录器

  • Java Logging API
  • 的Log4j
  • SLF4J

所有这些都需要在类级别进行LOGGER声明,如下面的

private final static java.util.logging.Logger.Logger LOGGER = java.util.logging.Logger.Logger.getLogger(MyClass.class.getName());
private final Logger slf4jLogger = LoggerFactory.getLogger(SLF4JHello.class);
private final static Logger log4jLogger = Logger.getLogger(Log4jHello.class);

对我来说这看起来很可怕,java中是否有一个不需要此声明的记录器框架?

我正在寻找的是,我可以拥有像

这样的全球宣言
private final static Logger Logger = Logger.getLogger(MyApp.class);

但是当我从XXX.class类调用 Logger.log(..)时,Logger应该使用XXX.class名称。

2 个答案:

答案 0 :(得分:2)

您的问题很可能不是日志框架,而是布局。

具体示例

<强> so35592962/App.java

package so35592962;
import org.apache.logging.log4j.*;
import so35592962.sub.OtherClass;
public class App {
  public static final Logger logger = LogManager.getLogger();
  public static void main(String[] args) {
    logger.error("in App.main");
    OtherClass.act();
  }
}

<强> so35592962/sub/OtherClass.java

package so35592962.sub;
import static so35592962.App.logger;

public class OtherClass {
  public static void act() {
    logger.error("OtherClass.act");
  }
}

所以你可以看到这完全是你想要的:使用单个记录器的类。非常好,Log4J2可用于此。

现在我添加了魔术文件log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %C{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

运行它将打印:

12:05:28.834 [main] ERROR so35592962.App - in App.main
12:05:28.836 [main] ERROR so35592962.sub.OtherClass - OtherClass.act

看,这里有不同的类名!然而我使用了Log4J2。

这里发生了什么?

请注意PatternLayout标记中使用的模式:

  

%d{HH:mm:ss.SSS} [%t] %-5level %C{36} - %msg%n

标准示例以及您在Internet上通常看到的内容都使用%L模式。此模式用于显示记录器名称。但是你说你不想要它。幸运的是,存在其他模式。 %C将显示类名而不是记录器名。这是此处使用的模式。

根据the PatternLayout documentation%C模式执行以下操作:

  

输出发出记录请求的调用者的完全限定类名。

重要说明,也在文档中提到:

  

生成调用者的类名(位置信息)是一项昂贵的操作,可能会影响性能。请谨慎使用。

答案 1 :(得分:1)

您可以使用Lombok将这两个更改为类注释。