SLF4J2 和 Log4J1 到 Log4J2

问题描述 投票:0回答:1

我一直在为记录器依赖项摸不着头脑。我希望我自己的代码使用 SLF4J 2 API,并在测试和运行时使用 Log4J2 作为提供程序。但是,我依赖于使用 Log4J1 的 OpenLr 二进制包。此外,我想设置遥测并导出我的日志。

我找到了这些文档:

看起来正确的依赖关系是:

<dependencyManagement>
        <dependencies>
            <!-- Set SLF4J 2 API version -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <!-- Set Log4J 2 API version -->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>${log4j.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
...
        <!-- Use SLF4J API so logging framework is code independent. -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- Redirect dependencies using Log4j 1 to Log4j 2 instead. -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!-- Add logging framework. -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j2-impl</artifactId>
            <version>${log4j.version}</version>
            <!-- includes log4j-api of same version -->
        </dependency>
        <!-- OpenTelemetry to produce metrics and logs -->
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-api</artifactId>
            <version>${opentelemetry.version}</version>
        </dependency>
        <!-- Dependencies needed for Geneva export with OTLP agent on docker -->
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
            <version>${opentelemetry.version}</version>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp</artifactId>
            <version>${opentelemetry.version}</version>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-log4j-appender-2.17</artifactId>
            <version>${opentelemetry.version}-alpha</version>
            <scope>runtime</scope>
        </dependency>

在另一个没有 opentelemetry 的模块中,这些设置似乎有效,但在主项目 SLF4J 中找不到绑定。一位队友告诉我,以下方法(设置日志记录以使用 log4j-reload)有效:

        <!-- Use SLF4J API so logging framework is code independent. -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- Add logging framework. -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-reload4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

我只是不确定为什么 log4j 2 提供程序无法工作。与 OpenTelemetry 是否不兼容?请帮我理解。

java maven log4j2 open-telemetry
1个回答
0
投票

最终我们开始更深入地研究,并意识到还有其他日志框架和其他子项目导致了一些问题。我们确保通过依赖管理设置所需的版本,并最终得到以下日志桥:

<!-- Use SLF4J API so logging framework is code independent -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>provided</scope>
        </dependency>
        <!-- Use Log4j 2 as logging provider -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j2-impl</artifactId>
            <version>${log4j.version}</version>
            <scope>test</scope>
            <!-- Includes log4j-api of same version -->
        </dependency>
        <!-- Redirect dependencies using Log4j 1 to Log4j 2 instead -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>${log4j.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- Redirect dependencies using JCL to Log4j 2 instead. -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>${log4j.version}</version>
            <scope>test</scope>
        </dependency>

为了确保日志记录在本地执行中正常工作,我们在对象的惰性 val(单例)初始化时覆盖一次配置,如下所示:

    val loggerContext = LogManager.getContext(false).asInstanceOf[LoggerContext]
    // load our custom configuration
    val customLog4j2Config = new XmlConfigurationFactory().getConfiguration(
      loggerContext,
      this.getClass.getName,
      log4j2ConfigFile
    )
    customLog4j2Config.initialize()

    // transfer missing appenders to our config
    loggerContext.getConfiguration
      .getAppenders
      .values()
      .forEach(
        appender => {
          if (
            !customLog4j2Config
              .getAppenders
              .containsKey(appender.getName)
          ) {
            customLog4j2Config.addAppender(appender)
          }
        }
      )

    // transfer missing loggers to our config
    loggerContext.getConfiguration
      .getLoggers
      .values()
      .forEach(
        loggerConfig => {
          if (
            !customLog4j2Config
              .getLoggers
              .containsKey(loggerConfig.getName)
          ) {
            customLog4j2Config.addLogger(loggerConfig.getName, loggerConfig)
          }
        }
      )

    // update the context to use our custom config
    loggerContext.reconfigure(customLog4j2Config)
    loggerContext.updateLoggers()
  }
© www.soinside.com 2019 - 2024. All rights reserved.