java 从外部依赖项中筛选出日志

iyr7buue  于 2023-03-16  发布在  Java
关注(0)|答案(1)|浏览(129)

tl;dr:我想从pdfbox库中过滤掉一些不需要的日志(并留下其他的)。这个库使用commons-logging facade。
加长版

我想过滤掉一些不需要的日志(并保留其他)。它有自己的依赖项commons-logging,即(据我所知)一个类似于slf4j的外观。(x 1m 5 n 1x),其也依赖于X1 M6 N1 X,尽管具有较新的版本。有一个名为jcl-over-slf4j的项目,它将来自commons-logging的日志重定向到slf4j facade。我决定将它与logback-classic一起使用。原生实现slf4j的日志记录器。我还编写了一个自定义过滤器来过滤掉不需要的日志。运行junit测试时一切正常(从IntelliJ并使用CLI -通过运行mvn clean package)但是运行包含我自己的代码和所有依赖项的最终(fat)jar会导致一条消息打印到控制台,说明我在类路径上没有任何受支持的日志记录器:

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.

这是为什么呢?看起来在测试执行期间一切都工作正常,而在使用fat jar时却无法工作。

更新

由于这看起来很重要,我将描述fat jar问题以及如何运行我的应用程序。为了创建fat jar,我使用maven shade plugin和下面看到的配置。我通过执行mvn clean package创建fat jar,并通过java -jar myapp.jar运行应用程序。

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-shade-plugin</artifactId>
   <version>3.2.4</version>
   <configuration>
      <createDependencyReducedPom>false</createDependencyReducedPom>
      <transformers>
         <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>com.github.menteith.pdfexample.Main</mainClass>
            <manifestEntries>
               <Built-By />
            </manifestEntries>
         </transformer>
      </transformers>
      <filters>
         <filter>
            <artifact>*:*</artifact>
            <excludes>
               <exclude>META-INF/**</exclude>
               <exclude>module-info.class</exclude>
            </excludes>
         </filter>
      </filters>
   </configuration>
   <executions>
      <execution>
         <phase>package</phase>
         <goals>
            <goal>shade</goal>
         </goals>
      </execution>
   </executions>
</plugin>

下面是我的自定义Logback过滤器:

class LogbackTurboFilter
    extends TurboFilter {

   @Override
   public FilterReply decide(final Marker marker, final Logger logger, final Level level,
       final String format, final Object[] params, final Throwable t) {

      System.out.println("In decide!!!"); // this is printed during tests, but not when final jar is run

      if ( !isStarted() ) {
         return FilterReply.NEUTRAL;
      }

      if ( level == Level.WARN
           && logger.getName().startsWith("org.apache.pdfbox") ) {
         return FilterReply.DENY;
      } else {
         return FilterReply.NEUTRAL;
      }
   }
}

下面是我的logback.xml

<configuration>
    <turboFilter class="com.github.menteith.pdfexample.LogbackTurboFilter"/>
    <appender name="STDOUT"
            class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%-4relative [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

pom.xml的相关部件:

<dependency>
    <artifactId>pdfbox</artifactId>
    <groupId>org.apache.pdfbox</groupId>
    <version>2.0.27</version>
    <!-- picocli has never artifact -->
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>info.picocli</groupId>
    <artifactId>picocli</artifactId>
    <version>4.7.1</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>2.0.6</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.4.5</version>
</dependency>

maven中的dependency tree

+- org.apache.pdfbox:pdfbox:jar:2.0.27:compile
|  \- org.apache.pdfbox:fontbox:jar:2.0.27:compile
+- info.picocli:picocli:jar:4.7.1:compile
+- org.slf4j:jcl-over-slf4j:jar:2.0.6:compile
|  \- org.slf4j:slf4j-api:jar:2.0.6:compile
+- ch.qos.logback:logback-classic:jar:1.4.5:compile
|  \- ch.qos.logback:logback-core:jar:1.4.5:compile
+- org.bouncycastle:bcprov-jdk15on:jar:1.70:compile
+- org.bouncycastle:bcmail-jdk15on:jar:1.70:compile
|  +- org.bouncycastle:bcutil-jdk15on:jar:1.70:compile
|  \- org.bouncycastle:bcpkix-jdk15on:jar:1.70:compile
+- com.github.jai-imageio:jai-imageio-jpeg2000:jar:1.4.0:compile
|  \- com.github.jai-imageio:jai-imageio-core:jar:1.4.0:compile
+- org.projectlombok:lombok:jar:1.18.24:provided
+- org.junit.jupiter:junit-jupiter-engine:jar:5.9.2:test
|  +- org.junit.platform:junit-platform-engine:jar:1.9.2:test
|  |  +- org.opentest4j:opentest4j:jar:1.2.0:test
|  |  \- org.junit.platform:junit-platform-commons:jar:1.9.2:test
|  +- org.junit.jupiter:junit-jupiter-api:jar:5.9.2:test
|  \- org.apiguardian:apiguardian-api:jar:1.1.2:test
\- org.assertj:assertj-core:jar:3.24.0:test
   \- net.bytebuddy:byte-buddy:jar:1.12.20:test
flmtquvp

flmtquvp1#

1.创建一个没有依赖关系的单独的“Hello World”项目
1.将fat jar添加为单个依赖项
1.从“Hello World”主类调用fat jar主类
1.在org.slf4j.LoggerFactory#bind方法中设置断点
1.调试fat jar类加载问题

相关问题