如何打开 Spring WebFlux 的访问日志?

How to turn on the access log for Spring WebFlux?

对于 Netty 上的 Spring WebFlux 运行 我想像 Tomcat 那样访问日志,但我在 Spring documentation.

中找不到任何内容

有人可以帮忙吗?

这已在 Netty v0.7 中实现。9.RELEASE 在 this issue. According to the instructions posted here 之后您可以启用日志,因此:

  • 运行 您的 -Dreactor.netty.http.server.accessLogEnabled=true 系统应用程序 属性

  • 启用 reactor.netty.http.server.AccessLog
  • 的信息日志记录

请注意,目前仅支持CLF

在实施该功能之前可用的其他解决方案例如:

线路日志

正如@GreyTeardrop在评论中提到的,您可以将reactor.ipc.netty.channel.ContextHandlerreactor.ipc.netty.http.server.HttpServer的日志级别设置为DEBUG。这将以十六进制 + ASCII table 的形式生成每条消息的多行转储。生产使用不太愉快,但对调试很有用。

Spring 执行器 HTTP 跟踪

如果您的项目中有 Spring 个执行器,则支持 tracing of HTTP requests。跟踪信息被发送到 HttpTraceRepository bean。默认情况下,它是一个 InMemoryHttpTraceRepository 保存最后 100 条轨迹。

您可以通过实施您自己的 HttpTraceRepository 或装饰器来利用它来添加跟踪记录。您需要将其注册为 bean - 它将替换自动配置的 InMemoryHttpTraceRepository.

请注意,HTTP 跟踪仅包含有关请求和响应的一组有限信息,例如。您无权访问 request/response 正文或尺码。

我最终实施的解决方案如下所示:

@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 ...;
    }
}

通过这种方法,您几乎可以获得 Common Log Format 条消息。

您可能需要在 application.yml 中调整跟踪对象中包含的内容,方法是指定

management:
  trace:
    http:
      include: REQUEST_HEADERS, RESPONSE_HEADERS, PRINCIPAL, REMOTE_ADDRESS, TIME_TAKEN

默认情况下仅包含 REQUEST_HEADERS, RESPONSE_HEADERS, COOKIE_HEADERS, TIME_TAKEN

您自己的访问日志 WebFilter

Spring Boot Actuator 借助 HttpTraceWebFilter 实现了跟踪。如果您不想使用 Actuator 的解决方案,您可以从 HttpTraceWebFilter 的源代码中获取灵感并实现您自己的 WebFilter。将其公开为 Spring bean,它将自动注册到 Netty。

最新版本的 Reactor Netty 添加了对访问日志的支持。 只需将 Reactor 版本更新为 <reactor-bom.version>Bismuth-SR11</reactor-bom.version> 然后您只需要使用您正在使用的任何日志记录框架将 reactor.netty.http.server.AccessLog 记录到 access_log.log

详情请看这里:https://github.com/reactor/reactor-netty/issues/301#issuecomment-418402375

使用 Java 系统启用 netty 访问日志 属性,

-Dreactor.netty.http.server.accessLogEnabled=true

并且您可以将日志系统配置为具有单独的访问日志文件。

下面是一个 log4j2 配置示例。

 <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>

扩展 Adam Michalik 的出色答案,我只想提一下,使用 JVM 参数 -Dreactor.netty.http.server.accessLogEnabled=true 和记录器 reactor.netty.http.server.AccessLog 对我来说适用于格林威治,但不适用于芬奇利。

我正在使用 Spring Cloud Gateway v2.1.2,所以考虑到 Spring CloudRelease Trains 部分,我想这是有道理的。