【问题标题】:Java logging framework which does not require LOGGER declaration on every classJava 日志框架,不需要在每个类上声明 LOGGER
【发布时间】:2016-06-06 04:48:34
【问题描述】:

我尝试了以下记录器

  • Java 日志记录 API
  • Lo​​g4j
  • 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 名称。

【问题讨论】:

  • 如何定义和命名记录器完全取决于您(在任何这些框架中)。您可以只为您的整个应用程序使用一个,或者在任何呼叫中拨打getLogger
  • 记录器的名称也不一定与它显示的内容相关联。这一切都可以配置。
  • 我的意思是“a)所有的日志框架呈现这种模式是一个线索,它工作得很好 b)他们不需要你遵循这个模式”
  • 现代的方式是使用依赖注入来设置依赖,比如这个模式支持的日志接口。因此,没有任何现代日志框架可能会以不同的方式做事。

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


【解决方案1】:

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

具体例子

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 模式执行以下操作:

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

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

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

【讨论】:

  • 但是如果你只有一个 Logger,你就不能再为不同的 Logger 分配不同的日志级别(或者不同的格式化程序,或者不同的 appender)了。
  • 正确,但我相信这回答了最初的问题。一个唯一的记录器,使用类名。
  • 另外,这个答案不是“是的,一定要这样做”,而是“您的请求可以完成,方法如下”。我个人不赞同这一点,但如果 ti 为 OP 工作,我很高兴我提供了帮助!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-27
    • 2022-01-08
    • 1970-01-01
    相关资源
    最近更新 更多