Configure Tomcat Logging Behind a Load Balancer

tomcat.png

Overview

When running Tomcat behind a load balancer, we want the access logs to show the client IP address and not the load balancer.  

In this article, we'll show how to configure Tomcat to log the client IP address.

Tomcat Logging

RemoteIPValve

The RemoteIpValve logging component instructs Tomcat to grab the HTTP header X-Forwarded-For and use that for access logging.

By default, it will look for localhost and the following private (RFC1918) ranges:

  • 127.0.0.0/8
  • 169.254.0.0/16
  • 10.0.0.0/8
  • 192.168.0.0/16

For public IP addresses or private range of 172.16.0.0/12, we need to add an an internalProxies attribute that lists the load balancer source IP's.

AccessLogValve

We also need to set requestAttributesEnabled to true so that AccessLogValve can log the client IP.

Configuration

Scenario 1: Load balancer IP address is in list above

<Valve className="org.apache.catalina.valves.RemoteIpValve" />

<Valve className="org.apache.catalina.valves.AccessLogValve"
  directory="logs"
  prefix="access"
  suffix=".log"
  pattern="combined"
  renameOnRotate="true"
  requestAttributesEnabled="true"
/>

Scenario 2: Load balancer IP address not in the list above

In this example, we assume that our load balancer IP addresses are 172.16.0.10 and 172.16.0.11:

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
  internalProxies="172.16.0.10|172.16.0.11" />

<Valve className="org.apache.catalina.valves.AccessLogValve"
  directory="logs"
  prefix="access"
  suffix=".log"
  pattern="combined"
  renameOnRotate="true"
  requestAttributesEnabled="true"
/>

Output

After restarting Tomcat, we can now see that the logs are showing the correct IP address:

174.229.11.41 - - [30/Nov/2017:09:58:16 -0500] "GET / HTTP/1.1" 200 816634 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.91 Safari/537.36"