我在 Undertow 开发小组中提出了这个问题,但没有收到回复。
我使用 Java 17 编写了一个示例测试应用程序。我过去使用过嵌入式 Tomcat,但我读到了 Undertow 的好评,所以我想尝试一下。我不需要 Java/Jakarta EE servlet;我只需要使用路径模板响应请求。
我成功启动了 Undertow 服务器,到目前为止它按预期工作。但没有记录。我在
Undertow.start()
中看到我应该看到“正在启动服务器:……”,但我没有。
public synchronized void start() {
UndertowLogger.ROOT_LOGGER.infof("starting server: %s", Version.getFullVersionString());
我正在使用
io.undertow:undertow-core:2.3.10.Final
。对于日志记录,我使用 SLF4J 2.0.9 和 Logback 1.4.11。我的 Logback 文件配置为使用 INFO
级别日志记录:
<configuration>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
我什至尝试(经过一些研究)在启动服务器之前强制 JBoss Logging 使用 SLF4J:
System.setProperty("org.jboss.logging.provider", "slf4j");
仍然没有来自 Undertow 的日志
我单步执行了代码。 Undertow 的
Slf4jLocationAwareLogger
正在调用 LOG_METHOD.invoke(logger, null, className, Integer.valueOf(level), text, EMPTY, thrown)
,其中 level
的值为 20
。使用反射调用 Logback 的 Logger.filterAndLog_0_Or3Plus(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params, final Throwable t)
方法,if (effectiveLevelInt > level.levelInt)
检查失败,因为 effectiveLevelInt
是 10000
并且 level.levelInt
是 20000
,因此该方法返回而不记录日志(即不调用 buildLoggingEventAndAppend(localFQCN, marker, level, msg, params, t)
)。
首先,为什么我没有收到任何日志?
其次,为什么Undertow要直接调用Logback? SLF4J 的重点是提供跨记录器的通用抽象层。如何让 Undertow 直接调用 SLF4J? (事实上,最新的 SLF4J 允许系统属性指定实际的日志记录实现;请参阅SLF4J-450。如果 Undertow 绕过 SLF4J 并需要 Logback,或者尝试猜测日志记录实现并直接访问它,那就违背了整个目的SLF4J 的并且会损坏。)
Undertow 看起来确实很有前途,而且它运行良好,足以让我在最近的 Java 用户组会议上进行演示。但我希望我可以通过 SLF4J 进行 Undertow 日志记录,因为这对于任何嵌入式服务器都至关重要。
就其价值而言,Undertow 不使用 SLF4J,它使用 jboss-logging,这是一个类似于 SLF4J 的外观。
问题是您的
logback.xml
文件。您需要定义 STDOUT
附加器。比如:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
如果没有定义
STDOUT
附加程序,则没有可供参考的附加程序,因此不会记录任何内容。