我是否可以控制 jsvc stderr 输出中显示的 java 日志的日志格式



我正在使用logback来记录Java Web服务应用程序,使用嵌入式Jetty。 日志记录根据 logback.xml 文件按预期工作...除了一些源自 Java 的日志,但显示在 stderr 的 jsvc 输出中

我想特别查看我所有 Java 生成的日志,其时间戳为毫秒,以匹配我的其他日志,而出现在 jsvc stderr 输出中的日志仅降至秒。

jsvc stdout 日志主要从泽西岛生成,我看到我自己的代码被引用,因为对象被 Guice 注册,这给了我希望它可以通过 logback 来控制。 我不明白是什么原因导致这些日志显示在 jsvc 的 stderr 输出中,而不是显示在 logback catchall 中。 有没有人在使用 jsvc 时解决过他们的代码或配置中的类似问题?

该解决方案需要在几个地方进行更改,并且主要是 slf4j 配置问题。 我的应用有许多依赖项,它们引入了各种日志记录实现。 Slf4j被设计成将它们聚集在一起,这个过程通常只是一个简单的罐子,但java.util.logging需要更多的努力。

slf4j 桥接遗留 API 页面(主要)描述了如何连接 Jersey 引入的 JUL 依赖项。 我已经包含了jul-to-slf4j.jar,但它没有正确连接。 我需要在应用程序的初始化中执行SLF4JBridgeHandler.install()。 此外,该页面警告负面性能影响,除非我还在 logback.xml 文件中包含以下内容:

<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
    <resetJUL>true</resetJUL>
</contextListener>

这让我大部分时间都在那里,但引入了日志事件的重复 - 一个转到slf4j,另一个继续stderr。 Google将我引向了Claus Neilsen博客中的一篇文章,"桥接java.util.logging到SLF4J"。 这包含一个有用的代码片段:

// Jersey uses java.util.logging - bridge to slf4
java.util.logging.Logger rootLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = rootLogger.getHandlers();
for (int i = 0; i < handlers.length; i++) {
    rootLogger.removeHandler(handlers[i]);
}
SLF4JBridgeHandler.install();

有了这个,出现在我的jsvc stderr输出中的泽西岛日志现在与我的其余日志一起显示,格式很好,按照logback.xml的指示。

据我了解,jsvc是一个用 C 编写的守护进程,用于管理 Java 应用程序。 它并没有真正在 Java 本身中运行,并且它的日志记录仅限于 stdoutstderr . 您可以将jsvc输出重定向到命名管道,并让一些进程读取它们并为您提供毫秒时间戳。 由您想在解决方案中付出多少努力。

根据客户端或容器过滤器javadoc,Jersey使用JDK日志记录API生成其日志行以默认System.out

因此,您必须参考 Java 日志记录指南来设置LogManager,以便按类或级别对其进行过滤,甚至将日志行从System.out转移到您自己的文件。

自己的代码使用slf4j,你必须配置logback以FileAppender替换ConsoleAppender

相关内容