How to Separate Tomcat Logging Per Instance in Azure Web App

Azure web app supports multiple instances of Java application host in Tomcat. While based on Tomcat's default logging setting, all the instances' log will be archived to same file, this could bring difficulty to check what's going on in each different instance. This article is about how to separate the log files per instance.

Basically, we can identify a unique instance by build-in environment variable WEBSITE_INSTANCE_ID, it can be found in the scm portal. We will use the instance id as prefix for each log file to make sure the log file names are different between the instances.

Download Tomcat

Firstly, we need download Tomcat binary from https://tomcat.apache.org/, please choose your expected version for download. Upload the Tomcat binary folder to D:\home\site\wwwroot\bin\tomcat.

Modify server.xml

In order to run customized Tomcat in Azure web app, we need follow https://docs.microsoft.com/en-us/azure/app-service-web/web-sites-java-custom-upload to modify D:\home\site\wwwroot\bin\tomcat\conf\server.xml shown below. Here, I am just using exactly the same content of Azure virtual machine, for example D:\Program Files (x86)\apache-tomcat-8.0.23\conf\server.xml. Just copy and paste it.
Shutdown port = -1
HTTP connector port = ${port.http}
HTTP connector address = "127.0.0.1"
Comment out HTTPS and AJP connectors

Upload web.config

Then, we need create a web.config file shown below, then upload to D:\home\site\wwwroot. Notice that the Dcatalina.instance.name parameter is passing the WEBSITE_INSTANCE_ID environment variable to Tomcat. Also, Dsite.logdir is used to sepecify the log directory to archive the logs, feel free to change it as you want.

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
</handlers>
<httpPlatform processPath="%HOME%\site\wwwroot\bin\tomcat\bin\startup.bat"
arguments="">
<environmentVariables>
<environmentVariable name="CATALINA_OPTS" value="-Dport.http=%HTTP_PLATFORM_PORT% -Dcatalina.instance.name=%WEBSITE_INSTANCE_ID% -Dsite.logdir=D:\home\LogFiles\tomcat" />
<environmentVariable name="CATALINA_HOME" value="%HOME%\site\wwwroot\bin\tomcat" />
<environmentVariable name="JAVA_OPTS" value="-Djava.net.preferIPv4Stack=true" />
</environmentVariables>
</httpPlatform>
</system.webServer>
</configuration>

Modify catalina.properties

Lastly, we need revise D:\home\site\wwwroot\bin\tomcat\conf\catalina.properties a little bit to make sure Tomcat understand the Dcatalina.instance.name parameter shown below:

 

1catalina.org.apache.juli.AsyncFileHandler.level = FINE
1catalina.org.apache.juli.AsyncFileHandler.directory = ${site.logdir}
1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.${catalina.instance.name}

2localhost.org.apache.juli.AsyncFileHandler.level = FINE
2localhost.org.apache.juli.AsyncFileHandler.directory = ${site.logdir}
2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.${catalina.instance.name}

3manager.org.apache.juli.AsyncFileHandler.level = FINE
3manager.org.apache.juli.AsyncFileHandler.directory = ${site.logdir}
3manager.org.apache.juli.AsyncFileHandler.prefix = manager.${catalina.instance.name}

4host-manager.org.apache.juli.AsyncFileHandler.level = FINE
4host-manager.org.apache.juli.AsyncFileHandler.directory = ${site.logdir}
4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager.${catalina.instance.name}

Now, we can see all the logs have instance id as part of the name.