Java 不需要在每个 class 上声明 LOGGER 的日志记录框架
Java logging framework which does not require LOGGER declaration on every class
我尝试了以下记录器
- Java 日志记录 API
- Log4j
- slf4j
所有这些都需要 class 级别的 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);
但是当我从 class XXX.class 调用 Logger.log(..) 时,记录器应该使用 XXX.class 名字.
您可以使用 Lombok 将这两个更改为 class 注释。
您的问题很可能与日志框架无关,而与布局有关。
具体例子
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");
}
}
因此您可以看到这完全是您想要的:class使用单个记录器的 es。说得好,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
看,这里有不同的class名字!然而我用的是Log4J2.
这里发生了什么?
注意 PatternLayout
标签中使用的模式:
%d{HH:mm:ss.SSS} [%t] %-5level %C{36} - %msg%n
标准的例子和你平时在网上看到的都是用%L
模式。此模式用于显示记录器名称。但是你说你不想要它。幸运的是,还存在其他模式。 %C
将显示 class 名称而不是记录器名称。这是此处使用的模式。
根据 the PatternLayout
documentation,%C
模式执行以下操作:
Outputs the fully qualified class name of the caller issuing the logging request.
重要说明,文档中也提到:
Generating the class name of the caller (location information) is an expensive operation and may impact performance. Use with caution.
我尝试了以下记录器
- Java 日志记录 API
- Log4j
- slf4j
所有这些都需要 class 级别的 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);
但是当我从 class XXX.class 调用 Logger.log(..) 时,记录器应该使用 XXX.class 名字.
您可以使用 Lombok 将这两个更改为 class 注释。
您的问题很可能与日志框架无关,而与布局有关。
具体例子
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");
}
}
因此您可以看到这完全是您想要的:class使用单个记录器的 es。说得好,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
看,这里有不同的class名字!然而我用的是Log4J2.
这里发生了什么?
注意 PatternLayout
标签中使用的模式:
%d{HH:mm:ss.SSS} [%t] %-5level %C{36} - %msg%n
标准的例子和你平时在网上看到的都是用%L
模式。此模式用于显示记录器名称。但是你说你不想要它。幸运的是,还存在其他模式。 %C
将显示 class 名称而不是记录器名称。这是此处使用的模式。
根据 the PatternLayout
documentation,%C
模式执行以下操作:
Outputs the fully qualified class name of the caller issuing the logging request.
重要说明,文档中也提到:
Generating the class name of the caller (location information) is an expensive operation and may impact performance. Use with caution.