Java日志记录:通过jul和log4j2的slf4j [英] Java logging: slf4j over jul and log4j2

查看:84
本文介绍了Java日志记录:通过jul和log4j2的slf4j的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序无法覆盖 jul log4j2 日志记录框架,但是可以使用覆盖: log4j jcl > log4j

Application cannot overwrite jul and log4j2 logging frameworks, but can ovewrite: log4j, jcl with log4j

应用程序使用 slf4j 网桥和 logback 作为日志框架.该应用程序还依赖并调用使用不同日志记录框架的模块:

The application uses slf4j bridge with logback as a logging framework. The application also depends and invokes modules which use different logging frameworks:

  1. 七月,
  2. log4j(v1),
  3. 带有log4j的jcl
  4. log4j2.

每个模块都有自己的日志记录配置文件,具体取决于日志记录框架.该配置文件在每个模块的 resorces 中定义.

Each module has its own logging configuration file, depending on the logging framework. The config file is defined in the resorces of each module.

我尝试强制所有模块,不使用它们自己的日志记录框架和配置,而仅使用 slf4j logback 桥接.

I try to force all the modules, do not use their own logging frameworks and configuration, but only slf4j bridge with logback.

这是Java代码:

new Slf4jLoggingExample().doLog();
new JulLoggingExample().doLog();
new Log4jLoggingExample().doLog();
new Log4jV2LoggingExample().doLog();
new JclLog4jLoggingExample().doLog();

这是Maven配置没有的多个桥接库,例如log4j-over-slf4j,jul-to-slf4j,jcl-over-slf4j.请注意,工件ID只是自定义组件:在该组件中使用的jul,log4j,log4j-v2,jcl-log4j突出显示了日志记录框架:

Here is the maven configuration WITHOUT multiple bridging libraries, like log4j-over-slf4j, jul-to-slf4j, jcl-over-slf4j. Note, artifact ids are just custom components: jul, log4j,log4j-v2, jcl-log4j to highlight a logging framework, used in that component:

  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>com.savdev.example.logging</groupId>
      <artifactId>jul</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>com.savdev.example.logging</groupId>
      <artifactId>log4j</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>com.savdev.example.logging</groupId>
      <artifactId>log4j-v2</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>com.savdev.example.logging</groupId>
      <artifactId>jcl-log4j</artifactId>
      <version>1.0.0</version>
    </dependency>
  </dependencies>

这里是输出,根据选择和配置的日志记录框架,它仅显示每组日志状态菜单具有不同的格式:

Here is the output, which just shows that each set of log statemens have different format, according to the chosen and configured logging framework:

12:18:08.316 [main] INFO  c.s.e.logging.Slf4jLoggingExample - This is an info message, (originally, slf4j with logback)
12:18:08.318 [main] ERROR c.s.e.logging.Slf4jLoggingExample - This is an error message, (originally, slf4j with logback)
12:18:08.318 [main] WARN  c.s.e.logging.Slf4jLoggingExample - This is a warning message, (originally, slf4j with logback)
12:18:08.318 [main] DEBUG c.s.e.logging.Slf4jLoggingExample - Here is a debug message, (originally, slf4j with logback)
Feb 24, 2021 12:18:08 PM com.savdev.example.logging.jul.JulLoggingExample doLog
INFO: This is an info message (originally, JUL)
Feb 24, 2021 12:18:08 PM com.savdev.example.logging.jul.JulLoggingExample doLog
SEVERE: This is an error message (originally, JUL)
Feb 24, 2021 12:18:08 PM com.savdev.example.logging.jul.JulLoggingExample doLog
WARNING: This is a warning message (originally, JUL)
Feb 24, 2021 12:18:08 PM com.savdev.example.logging.jul.JulLoggingExample doLog
FINE: Here is a debug message (originally, JUL)
[main] INFO  com.savdev.example.logging.log4j.Log4jLoggingExample  - This is an info message, (originally, log4j)
[main] ERROR com.savdev.example.logging.log4j.Log4jLoggingExample  - This is an error message, (originally, log4j)
[main] WARN  com.savdev.example.logging.log4j.Log4jLoggingExample  - This is a warning message, (originally, log4j)
[main] DEBUG com.savdev.example.logging.log4j.Log4jLoggingExample  - Here is a debug message, (originally, log4j)
[INFO ] 2021-02-24 12:18:08.722 [main] Log4jV2LoggingExample - This is an info message, (originally, log4j2)
[ERROR] 2021-02-24 12:18:08.724 [main] Log4jV2LoggingExample - This is an error message, (originally, log4j2)
[WARN ] 2021-02-24 12:18:08.724 [main] Log4jV2LoggingExample - This is a warning message, (originally, log4j2)
[DEBUG] 2021-02-24 12:18:08.724 [main] Log4jV2LoggingExample - Here is a debug message, (originally, log4j2)
[main] INFO  com.savdev.example.logging.jcl.logback.JclLog4jLoggingExample  - This is an info message (originally, jcl with log4j)
[main] ERROR com.savdev.example.logging.jcl.logback.JclLog4jLoggingExample  - This is an error message (originally, jcl with log4j)
[main] WARN  com.savdev.example.logging.jcl.logback.JclLog4jLoggingExample  - This is a warning message (originally, jcl with log4j)
[main] DEBUG com.savdev.example.logging.jcl.logback.JclLog4jLoggingExample  - Here is a debug message (originally, jcl with log4j)

5组不同格式的消息.我要添加多个桥接库:

5 groups of messages with different format. I am adding multiple bridging libraries:

<!-- https://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jul-to-slf4j</artifactId>
  <version>1.7.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/log4j-over-slf4j -->
<dependency>
  <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
  <version>1.7.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j -->
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.30</version>
</dependency>

这是新的输出:

12:44:40.385 [main] INFO  c.s.e.logging.Slf4jLoggingExample - This is an info message, (originally, slf4j with logback)
12:44:40.387 [main] ERROR c.s.e.logging.Slf4jLoggingExample - This is an error message, (originally, slf4j with logback)
12:44:40.387 [main] WARN  c.s.e.logging.Slf4jLoggingExample - This is a warning message, (originally, slf4j with logback)
12:44:40.387 [main] DEBUG c.s.e.logging.Slf4jLoggingExample - Here is a debug message, (originally, slf4j with logback)
12:44:40.399 [main] INFO  c.s.e.l.log4j.Log4jLoggingExample - This is an info message, (originally, log4j)
12:44:40.400 [main] ERROR c.s.e.l.log4j.Log4jLoggingExample - This is an error message, (originally, log4j)
12:44:40.400 [main] WARN  c.s.e.l.log4j.Log4jLoggingExample - This is a warning message, (originally, log4j)
12:44:40.400 [main] DEBUG c.s.e.l.log4j.Log4jLoggingExample - Here is a debug message, (originally, log4j)
Feb 24, 2021 12:44:40 PM com.savdev.example.logging.jul.JulLoggingExample doLog
INFO: This is an info message (originally, JUL)
Feb 24, 2021 12:44:40 PM com.savdev.example.logging.jul.JulLoggingExample doLog
SEVERE: This is an error message (originally, JUL)
Feb 24, 2021 12:44:40 PM com.savdev.example.logging.jul.JulLoggingExample doLog
WARNING: This is a warning message (originally, JUL)
Feb 24, 2021 12:44:40 PM com.savdev.example.logging.jul.JulLoggingExample doLog
FINE: Here is a debug message (originally, JUL)
[INFO ] 2021-02-24 12:44:40.793 [main] Log4jV2LoggingExample - This is an info message, (originally, log4j2)
[ERROR] 2021-02-24 12:44:40.795 [main] Log4jV2LoggingExample - This is an error message, (originally, log4j2)
[WARN ] 2021-02-24 12:44:40.795 [main] Log4jV2LoggingExample - This is a warning message, (originally, log4j2)
[DEBUG] 2021-02-24 12:44:40.796 [main] Log4jV2LoggingExample - Here is a debug message, (originally, log4j2)
12:44:40.798 [main] INFO  c.s.e.l.j.l.JclLog4jLoggingExample - This is an info message (originally, jcl with log4j)
12:44:40.798 [main] ERROR c.s.e.l.j.l.JclLog4jLoggingExample - This is an error message (originally, jcl with log4j)
12:44:40.798 [main] WARN  c.s.e.l.j.l.JclLog4jLoggingExample - This is a warning message (originally, jcl with log4j)
12:44:40.798 [main] DEBUG c.s.e.l.j.l.JclLog4jLoggingExample - Here is a debug message (originally, jcl with log4j)

我看到的是,只有具有log4j的组件和具有log4j的jcl组件更改了日志记录格式,并且现在按预期使用了主应用程序的日志记录格式.

What I can see, only the components with log4j and jcl with log4j changed their logging format and now use as expected the logging format of the main application.

但是log4j2和jul-仍使用其自己的日志记录格式,不受此设置的影响.

But log4j2 and jul - still use their own logging format and are not affected by this setup.

我已阅读但从JUL到SLF4J Bridge 并没有帮助.这是所有模块的完整代码:记录github存储库

I have read but JUL to SLF4J Bridge it did not help. Here is the full code of all modules: logging github repo

我想念什么,请您帮忙.

What do I miss, can you please help.

推荐答案

Log4j 2仍使用其自身配置的原因是因为您仅使用SLF4J的 log4j-over-slf4j Log4j 1 (尽管没有明确记录).对于Log4j 2到SLF4J,您必须添加 Log4j2到SLF4J适配器(依赖性信息).

The reason why Log4j 2 is still using its own configuration is because you are only using SLF4J's log4j-over-slf4j which is for Log4j 1 (despite not being that clearly documented). For Log4j 2 to SLF4J, you will have to add Log4j 2 to SLF4J Adapter (dependency information) as well.

对于 jul-to-slf4j ,您必须遵循

For jul-to-slf4j you have to follow the steps described in the SLF4JBridgeHandler documentation:

  • 在您的JRE的 logging.properties 文件中进行指定.尽管如果您无法控制应用程序正在运行的环境,那么这可能不是一个选择.
  • 或以编程方式安装它:
  • Either specify it in the logging.properties file of your JRE. Though if you have no control over the environment your application is running, this is likely not an option.
  • Or programmatically install it:
static {
  // Verify that it is not installed yet; other dependency might have already
  // installed it which would cause duplicate handler
  // Unfortunately SLF4J provides no built-in method for this procedure, so
  // race condition between different classes could happen
  if (!SLF4JBridgeHandler.isInstalled()) {
    // Remove default handler logging to System.err
    SLF4JBridgeHandler.removeHandlersForRootLogger();
    // Install the SLF4J handler
    SLF4JBridgeHandler.install();
  }
}

此外,您还应该配置 LevelChangePropagator 用于Logback.否则,由于SLF4J类只是一个处理程序,因此降低SLF4J日志级别(例如,用于调试)将不会影响 java.util.logging .

Additionally you should configure the LevelChangePropagator for Logback. Otherwise, because the SLF4J class is only a handler, lowering the SLF4J log level (e.g. for debugging) would have no effect on java.util.logging.

但是请注意,通常重定向 java.util.logging 会很麻烦,尤其是在您的项目有多个入口点的情况下.您将必须在每个这些入口点中执行SLF4J桥初始化检查.

Note however, that redirecting java.util.logging in general is a pain, especially if your project has multiple entry points. You will have to perform the SLF4J bridge initialization check in every one of these entry points.

作为旁注: java.util.logging 到Log4j 2桥的情况(

As a side note: The situation for the java.util.logging to Log4j 2 bridge (Log4j JDK Logging Adapter) it is not much better. That library instead implements LogManager which therefore integrates more tightly into java.util.logging, but has the disadvantage that it has to be specified using a System property (or the logging.properties file) and must be specified before java.util.logging.LogManager is loaded (which might not be in your control), afterwards a custom LogManager implementation cannot be specified anymore.
There is also a JUL Handler class called Log4jBridgeHandler, but that only exists on the not yet released 3.0.0 branch and has not been backported yet, see backport pull request.

这篇关于Java日志记录:通过jul和log4j2的slf4j的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆