1. 概述
HTTP API请求已成为现代应用的标配组件。Logbook是一个可扩展的Java库,能为不同客户端和服务端技术提供完整的请求/响应日志记录功能。它允许开发者记录应用接收或发送的任何HTTP流量,可用于日志分析、审计或流量问题排查。
本文将介绍如何将Logbook库集成到Spring Boot应用中。
2. 依赖配置
在Spring Boot中使用Logbook库,需添加以下依赖:
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>3.9.0</version>
</dependency>
最新版本可在Maven中央仓库获取。
3. 基础配置
Logbook与Spring Boot中的logback日志系统协同工作。我们需要在logback-spring.xml和application.properties文件中添加配置。
添加Logbook依赖后,Spring Boot会自动配置Logbook。首先在application.properties中设置日志级别:
logging.level.org.zalando.logbook.Logbook=TRACE
TRACE
级别会启用HTTP请求和响应的日志记录。
接着在logback-spring.xml中添加Logbook配置:
<logger name="org.zalando.logbook" level="INFO" additivity="false">
<appender-ref ref="RollingFile"/>
</logger>
完成配置后启动应用并发起HTTP请求。每次HTTP调用后,Logbook会将请求和响应记录到logback-spring.xml中指定的日志文件:
11:08:14.737 [http-nio-8083-exec-10] TRACE org.zalando.logbook.Logbook - Incoming Request: eac2321df47c4414
Remote: 0:0:0:0:0:0:0:1
GET http://localhost:8083/api/hello?name=James HTTP/1.1
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
accept-encoding: gzip, deflate, br, zstd
...
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
11:08:14.741 [http-nio-8083-exec-10] TRACE org.zalando.logbook.Logbook - Outgoing Response: eac2321df47c4414
Duration: 4 ms
HTTP/1.1 200 OK
...
Date: Tue, 18 Jun 2024 05:38:14 GMT
Keep-Alive: timeout=60
Hello, James!
以上展示了Logbook与Spring Boot的最小化集成。但这只是基础的请求/响应日志,接下来我们探讨更高级的配置。
4. 过滤与格式化
4.1 过滤配置
我们可以声明Logbook的配置Bean:
@Bean
public Logbook logbook() {
return Logbook.builder()
.condition(Conditions.exclude(Conditions.requestTo("/api/welcome"),
Conditions.contentType("application/octet-stream"),
Conditions.header("X-Secret", "true")))
.sink(new DefaultSink(new DefaultHttpLogFormatter(), new DefaultHttpLogWriter()))
.build();
}
上述代码中,我们声明了Logbook
Bean供Spring Boot加载配置。
在构建Logbook
Bean时,我们指定了过滤条件。**exclude()
方法中指定的请求映射会被排除在日志记录之外**。例如,路径为/api/welcome
的API请求/响应不会被记录。同样,我们通过contentType()
和header()
方法对请求内容类型和请求头进行了过滤。
需要记录的HTTP API应在include()
方法中指定。如果不使用include()
,Logbook会记录所有请求(exclude()
中指定的除外)。
要使过滤配置生效,需在application.properties中设置:
logbook.filter.enabled=true
4.2 日志格式化
Logbook默认使用sl4j logger记录日志,类别为org.zalando.logbook.Logbook
,日志级别为trace
:
sink(new DefaultSink(
new DefaultHttpLogFormatter(),
new DefaultHttpLogWriter()
))
要改变日志格式,需修改logback-spring.xml中appender的encoder。Logstash encoder启用LogstashLogbackSink
:
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
...
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
然后声明LogstashLogbackSink
并添加到Logbook
构建器:
HttpLogFormatter formatter = new JsonHttpLogFormatter();
LogstashLogbackSink logstashsink = new LogstashLogbackSink(formatter);
Logbook logbook = Logbook.builder()
.sink(logstashsink)
.build();
这里使用JsonHttpLogFormatter
与LogstashLogbackSink
组合,将日志输出为JSON格式:
{
"@timestamp": "2024-06-07T16:46:24.5673233+05:30",
"@version": "1",
"message": "200 OK GET http://localhost:8083/api/hello?name=john",
"logger_name": "org.zalando.logbook.Logbook",
"thread_name": "http-nio-8083-exec-6",
"level": "TRACE",
"http": {
...
"Content-Length": [
"12"
],
...
"body": "Hello, john!"
}
}
⚠️ JSON日志实际输出为单行,此处为便于阅读进行了格式化。
声明LogstashLogbackSink
时可修改日志级别:
LogstashLogbackSink logstashsink = new LogstashLogbackSink(formatter, Level.INFO);
也可使用SplunkHttpLogFormatter
输出键值对格式:
origin=remote ... method=GET uri=http://localhost:8083/api/hello?name=John host=localhost path=/api/hello ...
4.3 组合Sink
通过组合多个Sink可形成CompositeSink
:
CompositeSink compsink = new CompositeSink(Arrays.asList(logstashsink, new CommonsLogFormatSink(new DefaultHttpLogWriter())));
Logbook logbook = Logbook.builder()
.sink(compsink)
.build();
此配置会使用组合Sink中的所有Sink记录请求详情。示例中Logbook通过两个Sink记录请求:
... "message":"GET http://localhost:8083/api/hello?name=John",... uri":"http://localhost:8083/api/hello?name=John",...
... "message":"200 OK GET http://localhost:8083/api/hello?name=John",.."headers":{"Connection":["keep-alive"],...
5. 总结
本文介绍了如何通过最小化配置将Logbook库集成到Spring Boot应用,以及如何使用exclude()
和include()
方法过滤请求路径。还展示了如何通过LogstashLogbackSink
等Sink实现配合JsonHttpLogFormatter
等格式化器自定义日志格式。
完整源码示例可在GitHub获取。