How to turn on the access log for Spring WebFlux?
This has been implemented in Netty v0.7.9.RELEASE following this issue. According to the instructions posted here you can enable the log so:
- Run your application with
-Dreactor.netty.http.server.accessLogEnabled=true
system property
AND
- Enable INFO logging of
reactor.netty.http.server.AccessLog
Note that only CLF is supported for the moment.
Other solutions, available before that feature was implemented, are eg.:
Wire log
As @GreyTeardrop mentioned in the comment, you can set the log level of reactor.ipc.netty.channel.ContextHandler
and reactor.ipc.netty.http.server.HttpServer
to DEBUG
. This will produce a multi-line dump of each message as a hex + ASCII table. Not exactly pleasant fo production use, but can be useful for debugging.
Spring Actuator HTTP trace
If you have Spring Actuator in your project, is supports tracing of HTTP requests. The trace information is sent to a HttpTraceRepository
bean. By default it's a InMemoryHttpTraceRepository
that holds the last 100 traces.
You can leverage that by implementing your own HttpTraceRepository
or a decorator to it that will add logging of the traces. You need to register it as a bean - it will replace the autoconfigured InMemoryHttpTraceRepository
.
Note that the HTTP traces only have a limited set of information about the request and response, eg. you don't have access to request/response body or size.
A solution that I ended up implementing looks like this:
@Bean
public HttpTraceRepository httpTraceRepository() {
return new AccessLoggingHttpTraceRepositoryDecorator(
new InMemoryHttpTraceRepository(),
LoggerFactory.getLogger("netty.Access"),
new HttpTraceLogFormatter()
);
}
public class AccessLoggingHttpTraceRepositoryDecorator implements HttpTraceRepository {
private HttpTraceRepository delegate;
private Logger logger;
private HttpTraceLogFormatter formatter;
public AccessLoggingHttpTraceRepositoryDecorator(HttpTraceRepository delegate, Logger logger, HttpTraceLogFormatter formatter) {
this.delegate = delegate;
this.logger = logger;
this.formatter = formatter;
}
@Override
public List<HttpTrace> findAll() {
return delegate.findAll();
}
@Override
public void add(HttpTrace trace) {
if (logger.isDebugEnabled()) {
try {
logger.debug(formatter.format(trace));
} catch (Exception e) {
logger.error("Failed to log trace " + trace, e);
}
}
delegate.add(trace);
}
}
public class HttpTraceLogFormatter {
public String format(HttpTrace trace) {
// TODO implement this according to your preference
return ...;
}
}
With this approach you can get an almost Common Log Format message.
You may need to adjust in your application.yml
what is included in the trace object by specifying
management:
trace:
http:
include: REQUEST_HEADERS, RESPONSE_HEADERS, PRINCIPAL, REMOTE_ADDRESS, TIME_TAKEN
By default only REQUEST_HEADERS, RESPONSE_HEADERS, COOKIE_HEADERS, TIME_TAKEN
are included.
Your own access logging WebFilter
Spring Boot Actuator implements tracing with the help of HttpTraceWebFilter
. If you don't want to use the Actuator's solution, you may take inspiration from the source code of the HttpTraceWebFilter
and implement your own WebFilter
. Expose it as a Spring bean and it will be automatically registered with Netty.
Support for access logs has been added to the latest version of Reactor Netty.
Just update you Reactor version to <reactor-bom.version>Bismuth-SR11</reactor-bom.version>
Then you just need to enable logging of reactor.netty.http.server.AccessLog
into access_log.log
using whatever logging framework you are using.
See here for details: https://github.com/reactor/reactor-netty/issues/301#issuecomment-418402375
Enable netty access log using Java System Property,
-Dreactor.netty.http.server.accessLogEnabled=true
and you can have logging system configured to have a separate access log file.
Below is an example log4j2 configuration.
<RollingRandomAccessFile name="ACCESS_LOG" fileName="access.log"
filePattern="$${date:yyyy-MM}/access-%d{MM-dd-yyyy}-%i.log.gz"
append="true">
<PatternLayout pattern="[%t] %d{dd MM yyyy HH:mm:ss,SSS} %-5p %-15c{1} [%X]: %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="5 MB"/>
</Policies>
<DefaultRolloverStrategy max="4"/>
</RollingRandomAccessFile>
<logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
<AppenderRef ref="ACCESS_LOG"/>
</logger>