问题描述
情况:我们使用带有异步追加器的 SLF4j 和 Log4j 2 问题是我们还使用了使用 java.util.Logging 的 JSF.我看到关于使用 jul-to-slf4j 性能的各种令人发指的警告,因为你不能因为它在 JDK 中而直接丢弃 java.util.Logging 并且因为......这就是
"...因此,从 jul 到 SLF4J 的转换会严重增加禁用日志语句的成本(60 倍或 6000%)并显着影响启用日志语句的性能(总体增加 20%). 从 logback 版本 0.9.25 开始,可以在 LevelChangePropagator 的帮助下完全消除禁用日志语句的 60 倍转换开销."
请注意,无论如何,使用 SLF4J + java.util.Logging 您会遇到 20% 的性能损失,但您可以通过使用最新版本来放弃 60 倍的提升.
20% 是不可接受的.
欢迎和鼓励其他想法,但我想到的解决方案是根本不合并 java.util.Logging.相反,请使用一个单独的配置文件,该文件指向与其他所有内容相同的日志文件.有没有人知道或知道我在哪里可以找到如何做到这一点的例子,假设这样做并不意味着所有创造的结束?
如果有更好的方法,我愿意接受.
推荐答案
我认为最佳解决方案是降低 20% 的性能.如果您没有完全替换 JUL 类,则 Handler 是 LogRecord 第一次离开 JUL.您还需要编写自己的 LevelChangePropagator 版本,以便在 Log4J2 中对日志级别的更改(例如重新配置)反映在 JUL 记录器中.(否则 60 倍的命中将扼杀禁用日志语句的性能.)
您可以将 JUL 类替换为您自己的(直接使用 SLF4J 或 Log4J2),但由于 JUL 不在 Java 认可的标准覆盖机制涵盖的包列表中,因此您实际上是在谈论在替代方案上运行JVM 或在维护复杂性方面接近它.
您可以推出自定义 JSF 实现,可能是通过使用开源实现并将所有 JUL 调用替换为 SLF4J 调用.您可以避免性能受到影响,并且不会像替换 JUL 那样困难.您仍然需要维护一个 JSF 分支,尽管如果您限制您的更改,维护分支可能不会太糟糕.它也不会涵盖任何其他调用 JUL 的代码.
问题描述
Situation: We use SLF4j and Log4j 2 with asynchronous appenders Problem is we also use JSF which uses java.util.Logging. I see all kinds of heinous warnings about performance in regards to using jul-to-slf4j due to the fact that you can't just chuck out java.util.Logging because it's in the JDK and because... well here is what the documentation at http://www.slf4j.org/legacy.html says:
"...Consequently, j.u.l. to SLF4J translation can seriously increase the cost of disabled logging statements (60 fold or 6000%) and measurably impact the performance of enabled log statements (20% overall increase). As of logback version 0.9.25, it is possible to completely eliminate the 60 fold translation overhead for disabled log statements with the help of LevelChangePropagator."
Note that no matter what, with SLF4J + java.util.Logging you are stuck with 20% performance hit, but you can ditch the 60 fold increase by using a recent version.
20% is unacceptable.
Other ideas are welcomed and encouraged but the solution I have in mind is to simply not consolidate java.util.Logging. Instead, use a separate configuration file that points to the same log file as everything else. Does anyone have or know where I can find an example of how to do this, assuming doing so won't mean the end of all creation?
If there's a better way, I'm open to it.
推荐答案
I think the optimal solution is to take the 20% performance hit. If you don't completely replace the JUL classes, a Handler is the first time a LogRecord leaves JUL. You'll also need to write your own version of LevelChangePropagator so that changes to log level (e.g. reconfiguration) in Log4J2 are reflected in the JUL loggers. (Otherwise the 60x hit will murder performance of disabled log statements.)
You could replace the JUL classes, with your own (that use SLF4J or Log4J2 directly), but since JUL isn't on the list of packages covered by Java Endorsed Standards Override Mechanism, you are effectively talking about running on a alternate JVM or close to it in maintenance complexity.
You could roll a custom JSF implementation, probably by taking the open source one and replacing all the JUL calls with SLF4J calls. You'd avoid the performance hit, and it wouldn't be nearly as difficult as replacing JUL. You'd still be maintaining a JSF fork, although if you limit your changes maybe maintaining the fork wouldn't be too bad. It wouldn't cover any other piece of code that are calling JUL, either.