Logging configuration
了解 Quarkus 中日志 API 的用法、如何配置日志输出,以及如何使用日志适配器统一来自其他日志 API 的输出。 Quarkus 使用 JBoss Log Manager 日志后端发布应用程序和框架日志。Quarkus 支持 JBoss Logging API 和多个其他日志 API,它们无缝集成到 JBoss Log Manager 中。您可以使用以下任何 following APIs:
- Use JBoss Logging for application logging
- Get an application logger
- Use log levels
- Configure the log level, category, and format
- Logging format
- Log handlers
- Add a logging filter to your log handler
- Examples of logging configurations
- Centralized log management
- Configure logging for
@QuarkusTest
- Use other logging APIs
- Logging configuration reference
Use JBoss Logging for application logging
如果使用 JBoss 日志记录 API,应用程序无需其他依赖项,因为 Quarkus 会自动提供该 API。
import org.jboss.logging.Logger;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class ExampleResource {
private static final Logger LOG = Logger.getLogger(ExampleResource.class);
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
LOG.info("Hello");
return "hello";
}
}
虽然 JBoss 日志记录会直接将日志消息路由到 JBoss 日志管理器,但某个库有时可能依赖的其他日志记录 API。在这种情况下,需要使用 logging adapter 确保其日志消息也可以路由到 JBoss 日志管理器。 |
Get an application logger
在 Quarkus 中,获取应用程序记录器的最常见方式有:
Declaring a logger field
这种经典方法是使用特定 API 获取记录器实例,将其存储在类的静态字段中,然后针对此实例调用日志记录操作。
使用任何 supported logging APIs 也可以使用相同流程。
package com.example;
import org.jboss.logging.Logger;
public class MyService {
private static final Logger log = Logger.getLogger(MyService.class); 1
public void doSomething() {
log.info("It works!"); 2
}
}
1 | Define the logger field. |
2 | 在 log 对象中调用所需的日志记录方法。 |
Simplified logging
Quarkus 会自动为使用 io.quarkus.logging.Log
的类添加记录器字段,从而简化日志记录。这样可以省去重复的样板代码,增强日志记录设置的便捷性。
package com.example;
import io.quarkus.logging.Log; (1)
class MyService { (2)
public void doSomething() {
Log.info("Simple!"); (3)
}
}
1 | io.quarkus.logging.Log 类包含与 JBoss 日志记录相同的方法,只是这些方法是 static 的。 |
2 | 请注意,该类不会声明记录器字段。这是因为在应用程序构建期间,会在使用 Log API 的每个类中自动创建一个 private static final org.jboss.logging.Logger 字段。调用 Log 方法的类的完全限定名称用作记录器名称。在此示例中,记录器名称将为 com.example.MyService 。 |
3 | 最后,在应用程序构建期间,对 Log 方法的所有调用都重写为记录器字段上的常规 JBoss 日志记录调用。 |
仅在应用程序类中使用 Log
API,不要在外部依赖项中使用。在构建时未由 Quarkus 处理的 Log
方法调用将引发异常。
Injecting a configured logger
注入带有 @Inject
注解的已配置 org.jboss.logging.Logger
记录器实例是添加应用程序记录器的另一种方法,但仅适用于 CDI Bean。
可以使用 @Inject Logger log
,记录器的名字以注入到的类的名字来命名,也可以使用 @Inject @LoggerName("…") Logger log
,记录器将接收指定的名字。注入后,可以使用 log
对象调用日志记录方法。
package com.example;
import org.jboss.logging.Logger;
@ApplicationScoped
class SimpleBean {
@Inject
Logger log; 1
@LoggerName("foo")
Logger fooLog; 2
public void ping() {
log.info("Simple!");
fooLog.info("Goes to _foo_ logger!");
}
}
1 | 使用声明类的 FQCN 作为记录器名称,例如,将使用 org.jboss.logging.Logger.getLogger(SimpleBean.class) 。 |
2 | 这种情况下,名字 foo 用作记录器名称,例如,将使用 org.jboss.logging.Logger.getLogger("foo") 。 |
记录器实例在内部缓存。因此,当记录器被注入(例如,注入到 |
Use log levels
Quarkus 提供不同的日志级别,这有助于开发人员根据事件的严重程度控制记录的信息量。
OFF |
A special level to use in configuration in order to turn off logging. |
FATAL |
A critical service failure or complete inability to service requests of any kind. |
ERROR |
A significant disruption in a request or the inability to service a request. |
WARN |
A non-critical service error or problem that may not require immediate correction. |
INFO |
Service lifecycle events or important related very low-frequency information. |
DEBUG |
Messages that convey extra information regarding lifecycle or non-request-bound events, useful for debugging. |
TRACE |
Messages that convey extra per-request debugging information that may be very high frequency. |
ALL |
A special level to use in configuration to turn on logging for all messages, including custom levels. |
还可以为使用 java.util.logging
的应用程序和库配置以下级别:
SEVERE |
Same as ERROR. |
WARNING |
Same as WARN. |
CONFIG |
Service configuration information. |
FINE |
Same as DEBUG. |
FINER |
Same as TRACE. |
FINEST |
Increased debug output compared to |
Numerical level value | Standard level name | 等效的 java.util.logging (JUL) 级别名称 |
---|---|---|
1100 |
FATAL |
Not applicable |
1000 |
ERROR |
SEVERE |
900 |
WARN |
WARNING |
800 |
INFO |
INFO |
700 |
Not applicable |
CONFIG |
500 |
DEBUG |
FINE |
400 |
TRACE |
FINER |
300 |
Not applicable |
FINEST |
Configure the log level, category, and format
JBoss 日志记录集成到 Quarkus 中,可通过一个设置所有可用扩展的配置文件为所有 supported logging APIs 提供一个统一配置。要调整运行时日志记录,请修改 application.properties
文件。
INFO
logging and include Hibernate DEBUG
logs:quarkus.log.level=INFO
quarkus.log.category."org.hibernate".level=DEBUG
在将日志级别设置为低于 DEBUG
时,你还必须调整最小日志级别。此设置可以是全局的,使用 quarkus.log.min-level
配置属性,或者按类别设置:
quarkus.log.category."org.hibernate".min-level=TRACE
这为 Quarkus 需要生成支持代码设置了最低层级。必须在构建时设置最低日志级别,以便 Quarkus 为优化机会敞开大门,在不可用级别上进行日志记录可以简化。
将 INFO
设置为最低日志级别会将较低级别的检查(如 isTraceEnabled
)设置为 false
。这会识别永远不会执行的代码,如 if(logger.isDebug()) callMethod();
,并将其标记为“死点”。
如果你在命令行中添加这些属性,请确保正确转义 "
字符:
-Dquarkus.log.category.\"org.hibernate\".level=TRACE
所有潜在属性都列在 logging configuration reference 部分。
Logging categories
日志记录按类别配置,每个类别独立配置。除非有更具体的子类别配置,否则类别配置会递归地应用于所有子类别。
所有日志记录类别的父级称为“根类别”。作为最终父级,此类别可能包含全局应用于所有其他类别的配置。这包括全局配置的处理程序和格式化程序。
quarkus.log.handlers=console,mylog
在此示例中,根类别配置为使用两个处理程序:console
和 mylog
。
quarkus.log.category."org.apache.kafka.clients".level=INFO
quarkus.log.category."org.apache.kafka.common.utils".level=INFO
此示例演示了如何配置类别 org.apache.kafka.clients
和 org.apache.kafka.common.utils
的最小日志级别。
有关更多信息,请参见 Logging configuration reference。
如果你想为特定类别配置其他内容,请创建一个命名处理程序(如 quarkus.log.handler.[console|file|syslog].<your-handler-name>.*
),并使用 quarkus.log.category.<my-category>.handlers
为该类别设置此处理程序。
一个示例用例可能希望对保存到文件的日志消息使用不同的时间戳格式,而不是用于其他处理程序的格式。
有关进一步说明,请参见 Attaching named handlers to a category 示例的输出。
Property Name | Default | Description |
---|---|---|
|
|
用于配置名为 |
|
|
用于配置名为 |
|
|
指定此记录器是否应将其输出发送到其父记录器。 |
|
|
要附加到特定类别的处理程序的名称。 |
|
Root logger configuration
根记录器类别单独处理,并使用以下属性进行配置:
Property Name | Default | Description |
---|---|---|
|
|
每个日志类别的默认日志级别。 |
|
|
每个日志类别的默认最低日志级别。 |
-
如果给定的记录器类别不存在级别配置,则会检查父类别。
-
如果未为类别及其任何父类别提供特定配置,则使用根记录器配置。
尽管根记录器的处理程序通常通过 |
Logging format
Quarkus 默认使用基于模式的日志记录格式设置程序生成可读文本日志,但您也可以使用专用属性为每个日志处理程序配置格式。
对于控制台处理程序,该属性是 quarkus.log.console.format
。
日志记录格式字符串支持以下符号:
Symbol | Summary | Description |
---|---|---|
|
|
呈现一个简单的 |
|
Category |
Renders the category name. |
|
Source class |
呈现源类名称。[Format sequences which examine caller information may affect performance] |
|
Date |
使用 |
|
Exception |
呈现抛出的异常(如果存在)。 |
|
Source file |
呈现源文件名。[Format sequences which examine caller information may affect performance] |
|
Host name |
呈现系统的简单主机名。 |
|
Qualified host name |
呈现系统的完全限定主机名,根据操作系统配置,它可能与简单主机名相同。 |
|
Process ID |
呈现当前进程的 PID。 |
|
Source location |
呈现源代码位置的信息,包括源文件名、行号、类名和方法名。[Format sequences which examine caller information may affect performance] |
|
Source line |
呈现源代码行号。[Format sequences which examine caller information may affect performance] |
|
Full Message |
呈现日志消息以及异常(如果有异常)。 |
|
Source method |
呈现源代码方法名。[Format sequences which examine caller information may affect performance] |
|
Newline |
呈现与平台特定的行分隔符字符串。 |
|
Process name |
呈现当前进程的名称。 |
|
Level |
呈现消息的日志级别。 |
|
Relative time |
呈现自应用程序日志开始以来经过的(以毫秒计)的时间。 |
|
Simple message |
只呈现日志消息,不呈现异常的跟踪。 |
|
Thread name |
Render the thread name. |
|
Thread ID |
Render the thread ID. |
|
Time zone |
将输出的时区设置成 |
|
Mapped Diagnostic Context Value |
呈现映射诊断上下文中的值。 |
|
Mapped Diagnostic Context Values |
以 |
|
Nested Diagnostics context values |
以 |
Alternative console logging formats
更改控制台日志格式很有用,例如,当 Quarkus 应用程序的控制台输出被某个服务捕获,该服务处理并存储日志信息以备日后分析的时候。
JSON logging format
可以采用 quarkus-logging-json
扩展来添加对 JSON 日志格式及其相关配置的支持。
-
将此扩展添加到构建文件中,如下面的代码片段所示:[source, xml] .pom.xml
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-logging-json</artifactId> </dependency>
implementation("io.quarkus:quarkus-logging-json")
默认情况下,此扩展的存在会替换控制台配置的输出格式配置,并将格式字符串和颜色设置(如果有)忽略。其他控制台配置项(包括控制异步日志和日志级别的选项)将继续应用。 对于某些情况来说,在开发模式下使用人类可读的(非结构化)日志,在生产模式下使用 JSON 日志(结构化)是有意义的。这可以使用不同的配置文件来实现,如下面的配置所示。 . 在 dev 和 test 模式下,禁用 application.properties 中的 JSON 记录:[source, properties]
%dev.quarkus.log.console.json=false %test.quarkus.log.console.json=false
Log handlers
日志处理程序是一个负责向接收方发送日志事件的日志记录组件。Quarkus 包含几个不同的日志处理程序: console、file*和 *syslog。
特色示例使用 `com.example`作为日志记录类别。
Console log handler
控制台日志处理程序默认启用,并且它将所有日志事件定向到应用程序控制台,通常是系统的 stdout
。
-
A global configuration example:[source, properties]
quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c] (%t) %s%e%n
-
A per-category configuration example:[source, properties]
quarkus.log.handler.console.my-console-handler.format=%d{yyyy-MM-dd HH:mm:ss} [com.example] %s%e%n quarkus.log.category."com.example".handlers=my-console-handler quarkus.log.category."com.example".use-parent-handlers=false
有关其配置的详细信息,请参阅 console logging configuration参考。
File log handler
若要将事件记录到应用程序主机上的文件,请使用 Quarkus 文件日志处理程序。文件日志处理程序默认禁用,因此您必须先启用它。
Quarkus 文件日志处理程序支持日志文件轮换。
日志文件轮换通过维护指定数量的备份日志文件,同时保持主日志文件为最新并易于管理,从而确保有效的日志文件管理。
-
A global configuration example:[source, properties]
quarkus.log.file.enable=true quarkus.log.file.path=application.log quarkus.log.file.format=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c] (%t) %s%e%n
-
A per-category configuration example:[source, properties]
quarkus.log.handler.file.my-file-handler.enable=true quarkus.log.handler.file.my-file-handler.path=application.log quarkus.log.handler.file.my-file-handler.format=%d{yyyy-MM-dd HH:mm:ss} [com.example] %s%e%n quarkus.log.category."com.example".handlers=my-file-handler quarkus.log.category."com.example".use-parent-handlers=false
有关其配置的详细信息,请参阅 file logging configuration参考。
Syslog log handler
默认情况下,禁用 syslog 处理程序。启用后,它会将所有日志事件发送到 syslog 服务器,通常是应用程序的本地 syslog 服务器。
-
A global configuration example:[source, properties]
quarkus.log.syslog.enable=true quarkus.log.syslog.app-name=my-application quarkus.log.syslog.format=%d{yyyy-MM-dd HH:mm:ss} %-5p [%c] (%t) %s%e%n
-
A per-category configuration example:[source, properties]
quarkus.log.handler.syslog.my-syslog-handler.enable=true quarkus.log.handler.syslog.my-syslog-handler.app-name=my-application quarkus.log.handler.syslog.my-syslog-handler.format=%d{yyyy-MM-dd HH:mm:ss} [com.example] %s%e%n quarkus.log.category."com.example".handlers=my-syslog-handler quarkus.log.category."com.example".use-parent-handlers=false
有关其配置的详细信息,请参阅 Syslog logging configuration参考。
Add a logging filter to your log handler
日志处理程序(例如控制台日志处理程序)可以与 filter链接,以确定是否应记录日志记录。
若要注册日志记录筛选器:
-
使用 `@io.quarkus.logging.LoggingFilter`对实现 `java.util.logging.Filter`的 `final`类加上注释,并设置 `name`属性:[source, java] .An example of writing a filter:
package com.example; import io.quarkus.logging.LoggingFilter; import java.util.logging.Filter; import java.util.logging.LogRecord; @LoggingFilter(name = "my-filter") public final class TestFilter implements Filter { private final String part; public TestFilter(@ConfigProperty(name = "my-filter.part") String part) { this.part = part; } @Override public boolean isLoggable(LogRecord record) { return !record.getMessage().contains(part); } }
在这个示例中,我们将包含特定文本的日志记录从控制台日志中排除。对于特定文本进行筛选不会进行硬编码;相反,它从 my-filter.part
配置属性中读取。
application.properties
:my-filter.part=TEST
-
使用位于
application.properties
的filter
配置属性将筛选器附加到对应的处理程序中:[source, properties]
quarkus.log.console.filter=my-filter
Examples of logging configurations
以下示例显示了一些可以在 Quarkus 中配置日志记录的方法:
quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n
quarkus.log.console.level=DEBUG
quarkus.console.color=false
quarkus.log.category."io.quarkus".level=INFO
如果在命令行中添加这些属性,请确保 |
quarkus.log.file.enable=true
# Send output to a trace.log file under the /tmp directory
quarkus.log.file.path=/tmp/trace.log
quarkus.log.file.level=TRACE
quarkus.log.file.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n
# Set 2 categories (io.quarkus.smallrye.jwt, io.undertow.request.security) to TRACE level
quarkus.log.min-level=TRACE
quarkus.log.category."io.quarkus.smallrye.jwt".level=TRACE
quarkus.log.category."io.undertow.request.security".level=TRACE
由于我们不会更改根记录器,控制台日志只将包含 |
# Send output to a trace.log file under the /tmp directory
quarkus.log.file.path=/tmp/trace.log
quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n
# Configure a named handler that logs to console
quarkus.log.handler.console."STRUCTURED_LOGGING".format=%e%n
# Configure a named handler that logs to file
quarkus.log.handler.file."STRUCTURED_LOGGING_FILE".enable=true
quarkus.log.handler.file."STRUCTURED_LOGGING_FILE".format=%e%n
# Configure the category and link the two named handlers to it
quarkus.log.category."io.quarkus.category".level=INFO
quarkus.log.category."io.quarkus.category".handlers=STRUCTURED_LOGGING,STRUCTURED_LOGGING_FILE
# configure a named file handler that sends the output to 'quarkus.log'
quarkus.log.handler.file.CONSOLE_MIRROR.enable=true
quarkus.log.handler.file.CONSOLE_MIRROR.path=quarkus.log
# attach the handler to the root logger
quarkus.log.handlers=CONSOLE_MIRROR
Centralized log management
使用集中式位置有效地收集、存储和分析来自应用程序的各种组件和实例的日志数据。
要将日志发送到 Graylog、Logstash 或 Fluentd 这样的集中式工具,请参阅 Quarkus Centralized log management 指南。
Configure logging for @QuarkusTest
通过将 java.util.logging.manager
系统属性设置为 org.jboss.logmanager.LogManager
,为 @QuarkusTest
启用适当的日志记录。
系统属性必须在早期设置才能生效,因此建议在构建系统中配置它。
java.util.logging.manager
system property in the Maven Surefire plugin configuration<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> 1
<quarkus.log.level>DEBUG</quarkus.log.level> 2
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
1 | 确保使用 org.jboss.logmanager.LogManager 。 |
2 | 为所有日志记录类别启用调试日志记录。 |
对于 Gradle,请将以下配置添加到 build.gradle
文件:
test {
systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
}
Use other logging APIs
Quarkus 依赖 JBoss Logging 库来满足所有日志要求。
假如你使用依赖于其他日志记录库(如 Apache Commons Logging、Log4j 或 SLF4J)的库,在这种情况下,将它们排除在依赖项之外,并使用 JBoss Logging 适配器之一。
在生成本机可执行文件时,这一点尤其重要,因为在编译本机可执行文件时,你可能会遇到类似于以下的问题:
Caused by java.lang.ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl
日志记录实现未包含在本地可执行文件中,但你可以使用 JBoss Logging 适配器解决此问题。
正如在下一章中所解释的,这些适配器适用于常用的开源日志记录组件。
Add a logging adapter to your application
对于每个并非 jboss-logging
的日志记录 API:
-
添加日志记录适配器库以确保通过这些 API 记录的消息被发送到 JBoss 日志管理器后端。
Quarkus 扩展项依赖库的这一步骤并不必要,其中扩展项会自动处理它。
-
Apache Commons Logging:[source, xml] .pom.xml
<dependency> <groupId>org.jboss.logging</groupId> <artifactId>commons-logging-jboss-logging</artifactId> </dependency>
implementation("org.jboss.logging:commons-logging-jboss-logging")
-
Log4j:[source, xml] .pom.xml
<dependency> <groupId>org.jboss.logmanager</groupId> <artifactId>log4j-jboss-logmanager</artifactId> </dependency>
implementation("org.jboss.logmanager:log4j-jboss-logmanager")
-
Log4j 2:[source, xml] .pom.xml
<dependency> <groupId>org.jboss.logmanager</groupId> <artifactId>log4j2-jboss-logmanager</artifactId> </dependency>
implementation("org.jboss.logmanager:log4j2-jboss-logmanager")
不要包含任何 Log4j 依赖项,因为 |
-
SLF4J:[source, xml] .pom.xml
<dependency> <groupId>org.jboss.slf4j</groupId> <artifactId>slf4j-jboss-logmanager</artifactId> </dependency>
implementation("org.jboss.slf4j:slf4j-jboss-logmanager")
-
验证所添加库生成的日志是否符合与其他 Quarkus 日志相同的格式。
Use MDC to add contextual log information
Quarkus 覆盖日志映射诊断上下文 (MDC) 以提高与它的反应核心的兼容性。
Add and read MDC data
要在 MDC 中添加数据并将其提取到日志输出中,请执行以下操作:
-
使用
MDC
类设置数据。 -
自定义日志格式以使用
%X{mdc-key}
。
让我们考虑以下代码:
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