环境:Spring2.7.18
1. 简介
记录HTTP API请求响应日志对于监控、调试和性能优化至关重要。它帮助开发者追踪API的使用情况,包括请求来源、参数、响应状态码及耗时等,从而快速定位问题、分析用户行为及评估系统性能。在生产环境中,合理的日志记录策略能及时发现并预警潜在问题,减少故障影响。
在本篇文章中 我将介绍一款非常强大的Logbook库,它可为不同的客户端和服务器端技术提供完整的请求和响应日志。它允许开发人员记录应用程序接收或发送的任何 HTTP 流量。这可用于日志分析、审计或调查流量问题。
Logbook实用非常的简单,它针对spring boot提供了starter,根据你当前spring boot使用的版本引入不同版本的Logbook即可。
依赖管理
<properties><!--如果你使用的springboot2.x版本请引入2.16.0版本--><logbook.version>2.16.0</java.version><!--如果你使用的springboot3.x版本请引入3.9.0版本--><logbook.version>3.9.0</java.version></properties><dependency><groupId>org.zalando</groupId><artifactId>logbook-spring-boot-starter</artifactId><version>${logbook.version}</version></dependency>
注意:上面使用的版本说明;接下来进入实战案例。
2. 实战案例
根据上面,引入了相关的依赖后,还需要进行如下的配置
logging::: TRACE
调整Logbook日志级别为TRACE。
2.1 基本用法
根据上面配置的日志级别,接下来你可以不用做任何的配置,随意访问一个接口就能在控制台看到非常详细的信息
// 接口@GetMapping("/query")public Object query(String name, Integer id) {return String.format("name = %s, id = %d", name, id) ;}
访问上面的接口,控制台输出如下:

这里看到了详细的请求/响应信息。再来个POST接口
public Book save( Book book) {return book ;}
输出日志信息

同样请求/响应输出了详细的信息。
输出格式配置
以上日志是以HTTP格式输出,它还支持:curl,json,splunk格式。通过如下配置:
logbook:format:: json
输出格式如下

日志输出策略
在上面的示例中,日志中包括了完整的请求信息,header+body,你可以通过如下进行配置:
logbook:strategy: without-body
如上配置后,日志输出将不会有body信息。
排除URL
默认情况下会对所有的请求进行日志的记录,你可以通过如下配置自定义:
logbook:exclude:/users/*/products/*
当请求匹配上面2个url模式时,将不会记录日志信息。
2.2 结合Logback
你还可以与Logback结合使用,将日志信息记录到文件当中,你只需要进行如下的配置即可。
在logback-spring.xml文件中如下配置:
<appender name="RequestLogger" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>logs/log_api_info.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${LOG_PATH}/log-api_info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>20MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy></appender><logger name="org.zalando.logbook" level="TRACE" additivity="false"><appender-ref ref="RequestLogger"/></logger>
有了上面的配置后,日志不会输出到控制台,而是记录到文件中,如下:

日志信息记录在该文件当中
2.3 自定义核心类Logbook
该库中最为核心的类是Logbook,几乎所有的配置都可以通过该类完成
public Logbook logbook() {Logbook logbook = Logbook.builder().condition(Conditions.exclude(Conditions.requestTo("/users/*")Conditions.contentType("application/json"))).sink(new DefaultSink(new DefaultHttpLogFormatter(), new DefaultHttpLogWriter())).build();}
在该配置中,我们设定了/users/*请求的路径不会记录日志,请求的contentType必须是application/json类型。而这里的sink用来指定日志的格式及如何进行写入。
Logbook还有很多其它的配置项,具体请查看相应的API。
2.4 自定义日志输出Sink
直接实现 Sink 接口可以实现更复杂的用例,例如将请求/响应写入结构化的持久存储(如数据库)。
Logbook 提供了一些具有常用日志格式的 Sink 实现,即 CommonsLogFormatSink 和 ExtendedLogFormatSink。ChunkingSink 会将长信息分割成较小的块,并单独写入。
自定义Sink
Logbook logbook() {Logbook logbook = Logbook.builder().condition(Conditions.exclude(Conditions.requestTo("/users/*").sink(new Sink() {public void write(Correlation correlation, HttpRequest request, HttpResponse response) throws IOException {System.err.println("==============================") ;System.err.println("request header:\t" + request.getHeaders()) ;System.err.println("request body:\t" + request.getBodyAsString()) ;System.out.println() ;System.err.println("response header:\t" + response.getHeaders()) ;System.err.println("response body:\t" + response.getBodyAsString()) ;System.err.println("==============================") ;}}).build() ;return logbook ;}
上面实现了一个非常简单的Sink,通过System直接将请求/响应内容输出到控制

2.5 与RestTemplate集成
默认Logbook提供了ClientHttpRequestInterceptor实现,并且注册为了bean。在创建RestTemplate对象时,我们只需要将其添加到RestTemplate中即可。如下示例:
RestTemplate logbookRestTemplate(LogbookClientHttpRequestInterceptor interceptor) {RestTemplate restTemplate = new RestTemplate() ;restTemplate.setInterceptors(Arrays.asList(interceptor)) ;return restTemplate ;}
如上将logbook的拦截器添加到RestTemplate中,接下来在请求中,也会详细的记录日志。
public Object remote() {return this.logbookRestTemplate.getForObject("http://localhost:8010/books/666", Map.class) ;}
请求日志输出如下

以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏
推荐文章
我给Spring提交一个Bug,已在最新版修复!请这样修复!
SpringBoot错误使用拦截器导致系统奔溃,发生OOM错误



