库中的 slf4j 似乎忽略了我的 log4j2 配置
slf4j in library seems to ignore my log4j2 configuration
我们在 java-ee 应用程序中使用 Log4j2。我们使用一个库,其中日志记录是针对 SLF4J 编程的。在这个库中有一个 class,它记录了很多我不想要的东西 -> 所以我想将这个 Logger 的 LogLevel 设置为 OFF。
我的 log4j2.xml 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" shutdownHook="disable">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" ignoreExceptions="false" >
<PatternLayout pattern="%d{ISO8601} %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<JDBC name="DatabaseAppender" tableName="logentry" ignoreExceptions="false" >
<ConnectionFactory class="xx.xx.xx.xx.LoggingConnectionFactory" method="getDatabaseConnection" />
<Column name="eventDate" isEventTimestamp="true" />
<Column name="level" pattern="%level" isUnicode="false"/>
<Column name="logger" pattern="%logger" isUnicode="false"/>
<Column name="message" pattern="%message" isUnicode="false"/>
<Column name="exception" pattern="%throwable{50}" isUnicode="false"/>
</JDBC>
</Appenders>
<Loggers>
<Logger name="net.rubyeye.xmemcached.transcoders.BaseSerializingTranscoder" level="off" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
</Logger>
<Root level="INFO">
<AppenderRef ref="DatabaseAppender"/>
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
但是 BaseSerializingTranscoder
仍然记录错误。
如果我做一个简单的测试并将在 BaseSerializingTranscoder 中找到的日志代码放置到测试函数中,我会看到通过 org.slf4j.Logger.LoggerFactory 检索到的记录器(库完成的)与我检索到的配置不同org.apache.logging.log4j.LogManager 上的记录器(正确应用了我的配置):
import net.rubyeye.xmemcached.transcoders.BaseSerializingTranscoder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.slf4j.LoggerFactory;
org.slf4j.Logger logger1 = LoggerFactory.getLogger(BaseSerializingTranscoder.class);
logger1.error("log test the same way as in library");
Logger logger2 = LogManager.getLogger(BaseSerializingTranscoder.class);
logger2.error("log test");
logger1 的输出是可见的,我想删除它。怎么了?
编辑
我们使用 Wildfly 10.1。我能够创建一个具有完全相同问题的最小示例。
pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-all-7.0</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</project>
log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="consoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p %c [%t] %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="blah" level="off" additivity="false">
<AppenderRef ref="consoleAppender" />
</Logger>
<Root level="info">
<AppenderRef ref="consoleAppender" />
</Root>
</Loggers>
</Configuration>
Service.java:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
@Singleton
@Startup
public class Service {
private static final Logger loggerBlah = LoggerFactory.getLogger("blah");
private static final Logger logger = LoggerFactory.getLogger(Service.class);
@PostConstruct
private void startup() {
logger.info("test1");
logger.error("test2");
loggerBlah.info("test3");
loggerBlah.error("test4");
}
}
输出:
21:13:11,641 INFO [Service] (ServerService Thread Pool -- 40) test1
21:13:11,641 ERROR [Service] (ServerService Thread Pool -- 40) test2
21:13:11,641 INFO [blah] (ServerService Thread Pool -- 40) test3
21:13:11,641 ERROR [blah] (ServerService Thread Pool -- 40) test4
test3 和 test4 不应该被记录!
怎么了?
更新#2:
在你的更新之后,我能够重现这个问题。根据我的最新评论,我能够使用 来指导我解决问题。
我在 web 项目的 META-INF 中添加了以下 jboss-deployment-structure.xml:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="org.apache.log4j" />
</exclusions>
<exclude-subsystems>
<subsystem name="logging"/>
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
我还稍微修改了 log4j2.xml 以便我可以毫无疑问地确定正在使用此文件指定的配置。我更改了 PatternLayout
以添加字符串 "MY_PATTERN" 作为每条消息的前缀:
<PatternLayout pattern="MY_PATTERN %d %p %c [%t] %m%n" />
输出:
09:30:38,074 INFO [stdout] (ServerService Thread Pool -- 137) MY_PATTERN 2017-09-24 09:30:38,073 INFO example.Service [ServerService Thread Pool -- 137] test1
09:30:38,077 INFO [stdout] (ServerService Thread Pool -- 137) MY_PATTERN 2017-09-24 09:30:38,077 ERROR example.Service [ServerService Thread Pool -- 137] test2
消息 test3 和 test4 不再记录到控制台。
上一个答案和更新:
我怀疑您的问题与您配置类路径的方式有关。我强烈建议您检查依赖层次结构,以确保您拥有所需的所有正确日志记录库。
下面是一个使用 SLF4J 和 log4j2 的 OFF 级别的简单示例:
package blah;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger log = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
log.trace("trace log");
log.debug("debug log");
log.info("info log");
log.warn("warn log");
log.error("error log");
}
}
这里是 log4j2.xml 配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="consoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p %c [%t] %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="blah" level="off" additivity="false">
<AppenderRef ref="consoleAppender" />
</Logger>
<Root level="info">
<AppenderRef ref="consoleAppender" />
</Root>
</Loggers>
</Configuration>
依赖项如下:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
当我将 "blah" 记录器的级别设置为关闭时,我在控制台上根本看不到任何日志。当我将其更改为类似 trace 的内容时,我会看到所有日志。
更新:
我能够使用 servlet API 3.1.0 组合一个简单的 Web 应用程序并使日志记录工作(我能够将级别设置为 OFF 并且看不到 ERROR 级别消息)与依赖项我在上面的例子中提到。所以这看起来肯定是某种配置问题。仅供参考,我将我的简单应用程序部署到 Tomcat 8。
我们在 java-ee 应用程序中使用 Log4j2。我们使用一个库,其中日志记录是针对 SLF4J 编程的。在这个库中有一个 class,它记录了很多我不想要的东西 -> 所以我想将这个 Logger 的 LogLevel 设置为 OFF。
我的 log4j2.xml 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" shutdownHook="disable">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT" ignoreExceptions="false" >
<PatternLayout pattern="%d{ISO8601} %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<JDBC name="DatabaseAppender" tableName="logentry" ignoreExceptions="false" >
<ConnectionFactory class="xx.xx.xx.xx.LoggingConnectionFactory" method="getDatabaseConnection" />
<Column name="eventDate" isEventTimestamp="true" />
<Column name="level" pattern="%level" isUnicode="false"/>
<Column name="logger" pattern="%logger" isUnicode="false"/>
<Column name="message" pattern="%message" isUnicode="false"/>
<Column name="exception" pattern="%throwable{50}" isUnicode="false"/>
</JDBC>
</Appenders>
<Loggers>
<Logger name="net.rubyeye.xmemcached.transcoders.BaseSerializingTranscoder" level="off" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
</Logger>
<Root level="INFO">
<AppenderRef ref="DatabaseAppender"/>
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
但是 BaseSerializingTranscoder
仍然记录错误。
如果我做一个简单的测试并将在 BaseSerializingTranscoder 中找到的日志代码放置到测试函数中,我会看到通过 org.slf4j.Logger.LoggerFactory 检索到的记录器(库完成的)与我检索到的配置不同org.apache.logging.log4j.LogManager 上的记录器(正确应用了我的配置):
import net.rubyeye.xmemcached.transcoders.BaseSerializingTranscoder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.slf4j.LoggerFactory;
org.slf4j.Logger logger1 = LoggerFactory.getLogger(BaseSerializingTranscoder.class);
logger1.error("log test the same way as in library");
Logger logger2 = LogManager.getLogger(BaseSerializingTranscoder.class);
logger2.error("log test");
logger1 的输出是可见的,我想删除它。怎么了?
编辑
我们使用 Wildfly 10.1。我能够创建一个具有完全相同问题的最小示例。
pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-all-7.0</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
</project>
log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="consoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p %c [%t] %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="blah" level="off" additivity="false">
<AppenderRef ref="consoleAppender" />
</Logger>
<Root level="info">
<AppenderRef ref="consoleAppender" />
</Root>
</Loggers>
</Configuration>
Service.java:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
@Singleton
@Startup
public class Service {
private static final Logger loggerBlah = LoggerFactory.getLogger("blah");
private static final Logger logger = LoggerFactory.getLogger(Service.class);
@PostConstruct
private void startup() {
logger.info("test1");
logger.error("test2");
loggerBlah.info("test3");
loggerBlah.error("test4");
}
}
输出:
21:13:11,641 INFO [Service] (ServerService Thread Pool -- 40) test1
21:13:11,641 ERROR [Service] (ServerService Thread Pool -- 40) test2
21:13:11,641 INFO [blah] (ServerService Thread Pool -- 40) test3
21:13:11,641 ERROR [blah] (ServerService Thread Pool -- 40) test4
test3 和 test4 不应该被记录! 怎么了?
更新#2:
在你的更新之后,我能够重现这个问题。根据我的最新评论,我能够使用
我在 web 项目的 META-INF 中添加了以下 jboss-deployment-structure.xml:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="org.apache.log4j" />
</exclusions>
<exclude-subsystems>
<subsystem name="logging"/>
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
我还稍微修改了 log4j2.xml 以便我可以毫无疑问地确定正在使用此文件指定的配置。我更改了 PatternLayout
以添加字符串 "MY_PATTERN" 作为每条消息的前缀:
<PatternLayout pattern="MY_PATTERN %d %p %c [%t] %m%n" />
输出:
09:30:38,074 INFO [stdout] (ServerService Thread Pool -- 137) MY_PATTERN 2017-09-24 09:30:38,073 INFO example.Service [ServerService Thread Pool -- 137] test1
09:30:38,077 INFO [stdout] (ServerService Thread Pool -- 137) MY_PATTERN 2017-09-24 09:30:38,077 ERROR example.Service [ServerService Thread Pool -- 137] test2
消息 test3 和 test4 不再记录到控制台。
上一个答案和更新:
我怀疑您的问题与您配置类路径的方式有关。我强烈建议您检查依赖层次结构,以确保您拥有所需的所有正确日志记录库。
下面是一个使用 SLF4J 和 log4j2 的 OFF 级别的简单示例:
package blah;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger log = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
log.trace("trace log");
log.debug("debug log");
log.info("info log");
log.warn("warn log");
log.error("error log");
}
}
这里是 log4j2.xml 配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Appenders>
<Console name="consoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p %c [%t] %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="blah" level="off" additivity="false">
<AppenderRef ref="consoleAppender" />
</Logger>
<Root level="info">
<AppenderRef ref="consoleAppender" />
</Root>
</Loggers>
</Configuration>
依赖项如下:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
当我将 "blah" 记录器的级别设置为关闭时,我在控制台上根本看不到任何日志。当我将其更改为类似 trace 的内容时,我会看到所有日志。
更新:
我能够使用 servlet API 3.1.0 组合一个简单的 Web 应用程序并使日志记录工作(我能够将级别设置为 OFF 并且看不到 ERROR 级别消息)与依赖项我在上面的例子中提到。所以这看起来肯定是某种配置问题。仅供参考,我将我的简单应用程序部署到 Tomcat 8。