你如何告诉 Spring Boot 将嵌入式 Tomcat 的访问日志发送到标准输出?

How do you tell Spring Boot to send the embedded Tomcat's access logs to stdout?

在独立的 Spring Boot web 应用程序(可执行 jar)中,您如何告诉 Spring Boot 我们希望将嵌入式 Tomcat 实例的 HTTP 访问日志发送到标准输出?

如果你使用 Logback,你可以使用 logback-access

添加依赖ch.qos.logback:logback-access

用于添加 TeeFilter(请求和响应日志记录)的可选 Javaconfig:

@Bean(name = "TeeFilter")
public Filter teeFilter() {
    return new ch.qos.logback.access.servlet.TeeFilter();
}

用于嵌入式的 Javaconfig tomcat:

@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();

    // put logback-access.xml in src/main/resources/conf
    tomcat.addContextValves(new LogbackValve());

    return tomcat;
}

logback-access.xml 的内容(保存在 src/main/resources/conf 中)

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <Pattern>combined</Pattern>
      <Pattern>%fullRequest%n%n%fullResponse</Pattern>
    </encoder>
  </appender>

  <appender-ref ref="STDOUT" />

</configuration>

这是 JohanB 对 Spring Boot 2.0.0+ 的精彩回答的跟进。

在 Spring Boot 2.0.0 中,EmbeddedServletContainerFactory 被替换为 TomcatServletWebServerFactory。 JohanB 答案的所有其他方面仍然可以正常工作,只需要修改工厂 bean 的创建:

@Bean
public TomcatServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    // put logback-access.xml in src/main/resources/conf
    tomcat.addContextValves(new LogbackValve());
    return tomcat;
}

这是在 Spring 启动时为我完成的 2.x:

server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.directory=/dev
server.tomcat.accesslog.prefix=stdout
server.tomcat.accesslog.buffered=false
server.tomcat.accesslog.suffix=""
server.tomcat.accesslog.file-date-format=""

2019.02.11更新:

这些墨水应该有助于映射您应该在 application.properties 中设置的属性:


@acohen 回答稍微正确。如果您提供空的双引号,它将不起作用。我将扩展他的答案,因为我认为这对于不想添加依赖项或修改代码的人来说很重要:

config/application.属性

# here we say that we want to enable accesslog
server.tomcat.accesslog.enabled=true

# it is important to understand what the options means:
# 'directory/prefix + suffix + file-date-format' will be
# the file that tomcat will try to open.
# /dev/stdout is standard output, so we want tomcat
# to write to that fd. Then, we need to play with
# directory, prefix, suffix and file-date-format to match our desired path.
server.tomcat.accesslog.directory=/dev
server.tomcat.accesslog.prefix=stdout
server.tomcat.accesslog.buffered=false

# Don't use empty double quotes, see below
server.tomcat.accesslog.suffix=
server.tomcat.accesslog.file-date-format=

备注

  1. 如果你把file-date-formatsuffix设置成双引号,就会出现这个错误:
java.io.FileNotFoundException: /dev/stdout"""" (Permission denied)

  1. 如果您不将它们包含在配置文件中,您将使用默认值并出现此错误:
java.io.FileNotFoundException: /dev/stdout.2019-02-07.log (Permission denied)
  1. 如果您将它们留空,那么它将起作用。

JohanB 的解决方案有效,但如果您不想编写代码,有人做得更好并包装 Server access logs in a nice Spring Boot starter。它涵盖 Tomcat、Jetty 和 Undertow。

只需添加依赖项:

<dependency>
    <groupId>net.rakugakibox.spring.boot</groupId>
    <artifactId>logback-access-spring-boot-starter</artifactId>
    <version>2.7.1</version>
</dependency>

和类路径根目录中的 logback-access.xml 文件:

<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>common</pattern>
        </encoder>
    </appender>
    <appender-ref ref="CONSOLE" />
</configuration>

访问日志打印到标准输出:

127.0.0.1 - - [08/févr./2019:11:23:30 +0100] "GET /password HTTP/1.1" 200 32

此时如果您想打印完整的 HTTP 请求和响应以进行调试,您将需要 create the TeeFilter Bean on your own