[英]Using slf4j + log4j with dropwizard
I have a REST java application built with Maven. 我有一个用Maven构建的REST Java应用程序。 It consists of a project with two modules:
它由一个带有两个模块的项目组成:
This is the parent POM: 这是父POM:
<?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>org.sample</groupId>
<artifactId>myapp_server</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<name>myapp_server</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<slf4j.version>1.7.25</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<url>http://repo1.maven.org/maven2</url>
</repository>
</repositories>
<modules>
<module>myapp_rest</module>
<module>myapp_logging</module>
</modules>
</project>
This is the POM for myapp_rest
(created with the java-simple archetype from dropwizard): 这是
myapp_rest
的POM(使用dropwizard中的java-simple原型创建):
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>myapp_server</artifactId>
<groupId>org.sample</groupId>
<version>0.0.1</version>
</parent>
<prerequisites>
<maven>3.0.0</maven>
</prerequisites>
<groupId>org.sample</groupId>
<artifactId>myapp_rest</artifactId>
<packaging>jar</packaging>
<name>REST layer</name>
<description>REST layer</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<dropwizard.version>1.3.5</dropwizard.version>
<mainClass>org.sample.rest.Application</mainClass>
</properties>
<dependencies>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-core</artifactId>
<version>${dropwizard.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>lo4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.sample</groupId>
<artifactId>myapp_logging</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${mainClass}</mainClass>
</transformer>
</transformers>
<!-- exclude signed Manifests -->
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0-M1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.8.1</version>
<configuration>
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
<dependencyDetailsEnabled>false</dependencyDetailsEnabled>
</configuration>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
</plugin>
</plugins>
</reporting>
</project>
This is the POM for myapp_logging
: 这是
myapp_logging
的POM:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sample</groupId>
<artifactId>myapp_server</artifactId>
<version>0.0.1</version>
</parent>
<groupId>org.sample</groupId>
<artifactId>myapp_logging</artifactId>
<name>myapp_logging</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<log4j.version>2.11.0</log4j.version>
</properties>
<dependencies>
<dependency> <!-- slf4j -> log4j bridge
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</project>
I'd like to make all logs go through slf4j
in order to use log4j
for logging. 我想使所有日志都通过
slf4j
以便使用log4j
进行日志记录。 Dropwizard uses logback internally so I'm trying to make it use slf4j instead. Dropwizard在内部使用了logback,因此我试图使其改用slf4j。
If I run this project I get this output: 如果运行此项目,则会得到以下输出:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/user/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/user/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.11.0/log4j-slf4j-impl-2.11.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
It seems that slf4j is seeing log4j from the logging module correctly, but it's also considering the binder from logback-classic
which is a dependency inside dropwizard. 看来slf4j可以正确地从日志记录模块中看到log4j了,但是它也在考虑
logback-classic
的绑定器,它是dropwizard内部的一个依赖项。
If I exclude the logback-classic
package I get this error: 如果我排除
logback-classic
的logback-classic
包, logback-classic
此错误:
Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/classic/Level
at io.dropwizard.Application.bootstrapLogLevel(Application.java:33)
at io.dropwizard.Application.bootstrapLogging(Application.java:38)
at io.dropwizard.Application.<init>(Application.java:26)
at org.sample.rest.Application.<init>(Application.java:10)
at org.sample.rest.Application.main(Application.java:15)
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.Level
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 5 more
By clicking on the class name it redirects me to the io.dropwizard.Application
class, which holds a reference to ch.qos.logback.classic.Level
, so the logback package cannot be safely removed. 通过单击类名,它会将我重定向到
io.dropwizard.Application
类,该类包含对ch.qos.logback.classic.Level
的引用,因此无法安全删除logback包。
I've seen that log4j has an "inverse bridge" that lets you proxy all calls to slf4j (log4j-over-slf4j), but there doesn't seem to be an equivalent for logback. 我已经看到log4j有一个“反向桥”,它可以让您将所有调用代理到slf4j(log4j-over-slf4j),但似乎没有等效的logback。
Is there a way to get rid of logback and use any other framework through slf4j with dropwizard? 有没有办法摆脱注销并通过带有dropwizard的slf4j使用任何其他框架?
There's actually a Dropwizard document on how to get rid of Logback: https://dropwizard.readthedocs.io/en/stable/manual/core.html#logging 实际上有一个关于如何摆脱Logback的Dropwizard文档: https ://dropwizard.readthedocs.io/en/stable/manual/core.html#logging
Read the note in yellow (right below the error levels) and it tells you what to do. 阅读黄色的注释(在错误级别的正下方),它告诉您该怎么做。 Hope it helps!
希望能帮助到你!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.