Generic Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

Spring Boot comes with an embedded Tomcat server, which is super-handy. However, we can't see Tomcat's logs by default.

In this tutorial, we'll learn how to configure Spring Boot to show Tomcat's internal and access logs via a toy application.

2. Sample Application

First of all, let's create a REST API. We'll define a GreetingsController to greet the user:

@GetMapping("/greetings/{username}")
public String getGreetings(@PathVariable("username") String userName) {
    return "Hello " + userName + ", Good day...!!!";
}

3. Tomcat Log Types

Embedded Tomcat stores two types of logs:

  • Access logs
  • Internal server logs

The access logs keep the records of all the requests processed by the application. These logs can be used to track things like page hit counts and user session activity. In contrast, internal server logs will help us to troubleshoot any issues in our running application.

4. Access Logs

By default, the access logs aren't enabled.

We can easily enable them, though, by adding a property to application.properties:

server.tomcat.accesslog.enabled=true

Similarly, we can use VM arguments to enable the access logs:

java -jar -Dserver.tomcat.basedir=tomcat -Dserver.tomcat.accesslog.enabled=true app.jar

These log files will be created in a temporary directory. For example, on Windows, the directory for access logs will look something like AppData\Local\Temp\tomcat.2142886552084850151.40123\logs

4.1. Format

So, with this property enabled, we'd see something like the following in our running application:

0:0:0:0:0:0:0:1 - - [13/May/2019:23:14:51 +0530] "GET /greetings/Harry HTTP/1.1" 200 27
0:0:0:0:0:0:0:1 - - [13/May/2019:23:17:23 +0530] "GET /greetings/Harry HTTP/1.1" 200 27

These are the access logs, and they have the format:

%h %l %u %t \"%r\" %>s %b

Which we can interpret as:

%h – the client IP which has sent the request, 0:0:0:0:0:0:0:1 in this case
%l – the identity of the user
%u – the user name determined by HTTP authentication
%t – the time the request was received
%r – the request line from the client, GET /greetings/Harry HTTP/1.1 in this case
%>s – the status code sent from the server to the client, like 200 here
%b – the size of the response to the client, or 27 for these requests

Since this request didn't have an authenticated user, %l and %u printed dashes.

In fact, if any information is missing, Tomcat will print a dash for that slot.

4.2. Customizing Access Logs

We can override the default Spring Boot configuration by adding few properties in application.properties. 

Firstly, to change the default log file name:

server.tomcat.accesslog.suffix=.log
server.tomcat.accesslog.prefix=access_log
server.tomcat.accesslog.file-date-format=.yyyy-MM-dd

Also, we can change the location of the log files:

server.tomcat.basedir=tomcat
server.tomcat.accesslog.directory=logs

Finally, we can override the way logs are written in the log file:

server.tomcat.accesslog.pattern=common

There are a few more configurable properties in Spring Boot, too.

5. Internal Logs

Tomcat server's internal logs are very helpful to solve any server-side issues.

To view these logs, we have to add below logging configuration in application.properties:

logging.level.org.apache.tomcat=DEBUG
logging.level.org.apache.catalina=DEBUG

And then we'll see something like:

2019-05-17 15:41:07.261 DEBUG 31160 --- [0124-Acceptor-0] o.apache.tomcat.util.threads.LimitLatch  : Counting up[http-nio-40124-Acceptor-0] latch=1
2019-05-17 15:41:07.262 DEBUG 31160 --- [0124-Acceptor-0] o.apache.tomcat.util.threads.LimitLatch  : Counting up[http-nio-40124-Acceptor-0] latch=2
2019-05-17 15:41:07.278 DEBUG 31160 --- [io-40124-exec-1] org.apache.tomcat.util.modeler.Registry  : Managed= Tomcat:type=RequestProcessor,worker="http-nio-40124",name=HttpRequest1
...
2019-05-17 15:41:07.279 DEBUG 31160 --- [io-40124-exec-1] m.m.MbeansDescriptorsIntrospectionSource : Introspected attribute virtualHost public java.lang.String org.apache.coyote.RequestInfo.getVirtualHost() null
...
2019-05-17 15:41:07.280 DEBUG 31160 --- [io-40124-exec-1] o.a.tomcat.util.modeler.BaseModelMBean   : preRegister [email protected] Tomcat:type=RequestProcessor,worker="http-nio-40124",name=HttpRequest1
2019-05-17 15:41:07.292 DEBUG 31160 --- [io-40124-exec-1] org.apache.tomcat.util.http.Parameters   : Set query string encoding to UTF-8
2019-05-17 15:41:07.294 DEBUG 31160 --- [io-40124-exec-1] o.a.t.util.http.Rfc6265CookieProcessor   : Cookies: Parsing b[]: jenkins-timestamper-offset=-19800000
2019-05-17 15:41:07.296 DEBUG 31160 --- [io-40124-exec-1] o.a.c.authenticator.AuthenticatorBase    : Security checking request GET /greetings/Harry
2019-05-17 15:41:07.296 DEBUG 31160 --- [io-40124-exec-1] org.apache.catalina.realm.RealmBase      :   No applicable constraints defined

6. Conclusion

In this quick article, we've learned the difference between Tomcat's internal and access logs. Then, we saw how to enable and customize them.

Make sure to check out the sample over on GitHub.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!