1.11. 使用其他日志记录 API
Quarkus 依赖于 JBoss Logging 库来满足所有日志记录要求。
假设您使用依赖于其他日志记录库的库,如 Apache Commons Logging、Log4j 或 SLF4J。在这种情况下,从依赖项中排除它们,并使用其中一个 JBoss Logging 适配器。
这在构建原生可执行文件时尤为重要,因为在编译原生可执行文件时可能会遇到类似如下的问题:
Caused by java.lang.ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl
日志记录实施不包括在原生可执行文件中,但您可以使用 JBoss Logging 适配器解决这个问题。
这些适配器可用于流行的开源日志记录组件,如下一章节中所述。
1.11.1. 在应用程序中添加日志适配器
对于不是 jboss-logging
的每个日志记录 API:
添加日志记录适配器库,以确保通过这些 API 记录的消息被路由到 JBoss Log Manager 后端。
注意对于作为 Quarkus 扩展依赖项的库,这个步骤不需要扩展自动处理它。
Apache Commons Logging:
使用 Maven:
<dependency> <groupId>org.jboss.logging</groupId> <artifactId>commons-logging-jboss-logging</artifactId> </dependency>
使用 Gradle :
implementation("org.jboss.logging:commons-logging-jboss-logging")
Log4j:
使用 Maven:
<dependency> <groupId>org.jboss.logmanager</groupId> <artifactId>log4j-jboss-logmanager</artifactId> </dependency>
使用 Gradle :
implementation("org.jboss.logmanager:log4j-jboss-logmanager")
Log4j 2:
使用 Maven:
<dependency> <groupId>org.jboss.logmanager</groupId> <artifactId>log4j2-jboss-logmanager</artifactId> </dependency>
使用 Gradle :
implementation("org.jboss.logmanager:log4j2-jboss-logmanager")
注意不要包含任何 Log4j 依赖项,因为
log4j2-jboss-logmanager
库包含使用 Log4j 作为日志实施所需的所有操作。
SLF4J:
使用 Maven:
<dependency> <groupId>org.jboss.slf4j</groupId> <artifactId>slf4j-jboss-logmanager</artifactId> </dependency>
使用 Gradle :
implementation("org.jboss.slf4j:slf4j-jboss-logmanager")
- 验证添加的库生成的日志是否遵循与其他 Quarkus 日志相同的格式。
1.11.2. 使用 MDC 添加上下文日志信息
Quarkus 覆盖了日志记录映射的诊断上下文(MDC),以提高其重新活跃内核的兼容性。
1.11.2.1. 添加和读取 MDC 数据
在 MDC 中添加数据并将其提取到日志输出中:
-
使用
MDC
类来设置数据。 -
自定义日志格式以使用
%X{mdc-key}
。
让我们考虑以下代码:
使用 JBoss Logging 和 io.quarkus.logging.Log
的示例
package me.sample; import io.quarkus.logging.Log; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import org.jboss.logmanager.MDC; import java.util.UUID; @Path("/hello/jboss") public class GreetingResourceJbossLogging { @GET @Path("/test") public String greeting() { MDC.put("request.id", UUID.randomUUID().toString()); MDC.put("request.path", "/hello/test"); Log.info("request received"); return "hello world!"; } }
如果您使用以下行配置日志格式:
quarkus.log.console.format=%d{HH:mm:ss} %-5p request.id=%X{request.id} request.path=%X{request.path} [%c{2.}] (%t) %s%n
您会收到包含 MDC 数据的消息:
08:48:13 INFO request.id=c37a3a36-b7f6-4492-83a1-de41dbc26fe2 request.path=/hello/test [me.sa.GreetingResourceJbossLogging] (executor-thread-1) request received
1.11.2.2. MDC 和支持的日志记录 API
根据您使用的 API,MDC 类略有不同。但是,API 非常相似:
-
Log4j 1 -
org.apache.log4j.MDC.put (key, value)
-
Log4j 2 -
org.apache.logging.log4j.ThreadContext.put(key, value)
-
SLF4J -
org.slf4j.MDC.put(key, value)
1.11.2.3. MDC propagation
在 Quarkus 中,MDC 供应商具有处理被动上下文的特定实现,可确保在被动和异步处理过程中传播 MDC 数据。
因此,您仍可在各种情况下访问 MDC 数据:
- 异步调用后,例如当 REST 客户端返回 Uni 时。
-
在提交至
org.eclipse.microprofile.context.ManagedExecutor
的代码中。 -
在使用
vertx.executeBlocking ()
执行的代码中。
如果适用,MDC 数据存储在 重复的上下文中,这是处理单个任务(请求)的隔离上下文。