We are developing a new service using Spring Boot
and Spring for GraphQL
. We want to enable logback
access logs to capture both request and response headers and content. I have configured logback access logs but it's only working for the request headers and content but response content is always empty
application.yaml
logback:
access:
enabled: true
config: classpath:logback/logback-access.xml
useServerPortInsteadOfLocalPort: true
tee-filter:
enabled: true
tomcat:
enableRequestAttributes: true
logback-access.xml
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%fullRequest%n%n%fullResponse</pattern>
</encoder>
</appender>
<appender-ref ref="CONSOLE"/>
TeeFilter
config: I have tried with order range [-1,0,1,9999,-9999]
@Bean
public FilterRegistrationBean<TeeFilter> someFilterRegistration() {
FilterRegistrationBean<TeeFilter> registrationBean = new FilterRegistrationBean<>(new TeeFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("TeeFilter");
registrationBean.setOrder(-1);
return registrationBean;
}
and sample console output is
POST /graphql HTTP/1.1
accept: application/json, multipart/mixed
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,de;q=0.8
authorization: xxxx
connection: keep-alive
content-length: 253
content-type: application/json
cookie: Idea-89db1df9=f548ac74-ebc1-4a6a-b686-1517cf9a6c8b; JSESSIONID=B6F9566795FF0216864B7D37F70FF61D
{"query":"xxxx"}
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Type: application/json
Date: Thu, 12 Oct 2023 08:52:42 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
This request has graphql response content but log cannot capture it. Why log configuration only capturing request content but not response ? It's strange because exact the same configuration working for our our another Spring Boot Rest service. Is it somehow related to the Spring for Graphql
or Graphql for Java
?
After many trials and errors, I have found a solution that may be not the optimal one. I disabled
TeeFilter
and registered two filters: one forDispatcherType.ASYNC
to capture response content and another forDispatcherType.REQUEST
to capture request content.Configuration
for filter registrationand filters:
ResponseContentCaptureFilter
RequestContentCaptureFilter
This approach has a drawback as it breaks the testing integration of Spring Boot for GraphQL, causing the request execution to fail in tests.