In a standalone Spring Boot web application (executable jar), how do you tell Spring Boot that we want the embedded Tomcat instance's HTTP access logs to be sent to stdout?
If you use Logback, you can use logback-access for this.
Add dependency ch.qos.logback:logback-access
Optional Javaconfig to add TeeFilter (request & response logging):
@Bean(name = "TeeFilter")
public Filter teeFilter() {
return new ch.qos.logback.access.servlet.TeeFilter();
}
Javaconfig for embedded tomcat:
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
// put logback-access.xml in src/main/resources/conf
tomcat.addContextValves(new LogbackValve());
return tomcat;
}
Contents for logback-access.xml
(save in 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>
TomcatEmbeddedServletContainerFactory
bean config. Great answer! –
Emiliaemiliaromagna logback-access.xml
file under src/main/resources/conf
. From the docs: By default, LogbackValve looks for a configuration file called logback-access.xml, in the same folder where server.xml is located, that is in $TOMCAT_HOME/conf/. –
Decrescendo Update 2019.02.11:
These inks should be useful to map which properties you should set in application.properties
:
@acohen answer is slightly correct. If you provide the empty double quotes it won't work. I will extend his answer because I think it's important for people who don't want to mess with adding dependencies or modifying code:
config/application.properties
# 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=
Notes
- If you set
file-date-format
andsuffix
to be double quotes, you will have this error:
java.io.FileNotFoundException: /dev/stdout"""" (Permission denied)
- If you don't include them in the config file, you will then be using defaults values and this error:
java.io.FileNotFoundException: /dev/stdout.2019-02-07.log (Permission denied)
- If you leave them empty, then it will work.
dir
(because method is getDir()
) instead of directory
. It's just a guess, tell me how did that went :) –
Aron management_
is being prefixed. Sounds like a logger configuration. Do you have a working example? –
Aron TomcatServletWebServerFactory
instead) works on all platforms. –
Emiliaemiliaromagna <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/dev" prefix="stdout" suffix="" pattern="%h %l %u %t "%r" %s %b" buffered="false" fileDateFormat=""/>
This is xml equivalent to this answer. –
Chemoreceptor If you use Logback, you can use logback-access for this.
Add dependency ch.qos.logback:logback-access
Optional Javaconfig to add TeeFilter (request & response logging):
@Bean(name = "TeeFilter")
public Filter teeFilter() {
return new ch.qos.logback.access.servlet.TeeFilter();
}
Javaconfig for embedded tomcat:
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
// put logback-access.xml in src/main/resources/conf
tomcat.addContextValves(new LogbackValve());
return tomcat;
}
Contents for logback-access.xml
(save in 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>
TomcatEmbeddedServletContainerFactory
bean config. Great answer! –
Emiliaemiliaromagna logback-access.xml
file under src/main/resources/conf
. From the docs: By default, LogbackValve looks for a configuration file called logback-access.xml, in the same folder where server.xml is located, that is in $TOMCAT_HOME/conf/. –
Decrescendo This did it for me on Spring Boot 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=""
application.yml
: https://mcmap.net/q/382278/-spring-boot-enable-http-requests-logging-access-logs –
Teaching Here's the followup up on the great answer from JohanB, for Spring Boot 2.0.0+.
In Spring Boot 2.0.0, the EmbeddedServletContainerFactory
was replaced with TomcatServletWebServerFactory
. All other aspects of JohanB's answer still works correctly the factory bean creation just needs to be modified:
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
// put logback-access.xml in src/main/resources/conf
tomcat.addContextValves(new LogbackValve());
return tomcat;
}
JohanB's solution works, but if you don't want to write code, someone did it better and wrapped Server access logs in a nice Spring Boot starter. It covers Tomcat, Jetty and Undertow.
Just add the dependency:
<dependency>
<groupId>net.rakugakibox.spring.boot</groupId>
<artifactId>logback-access-spring-boot-starter</artifactId>
<version>2.7.1</version>
</dependency>
And a logback-access.xml file at the classpath root:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>common</pattern>
</encoder>
</appender>
<appender-ref ref="CONSOLE" />
</configuration>
and the access logs are printed to stdout:
127.0.0.1 - - [08/févr./2019:11:23:30 +0100] "GET /password HTTP/1.1" 200 32
At this point you will need to create the TeeFilter
Bean on your own if you want to print the full HTTP request & response for debugging.
© 2022 - 2024 — McMap. All rights reserved.