Christoph
Christoph

Reputation: 762

How-To: Configure Tomcat 9 to log via Log4j2

How can you redirect Tomcat 9's internal logging (catalina and localhost) to Log4j2?

While there are many guides available for older versions of Tomcat and Log4j, I couldn't find anything "complete" regarding Tomcat 9 and Log4j2; the Apache Tomcat 9 documentation points to "the instructions provided by the alternative logging framework", and the Apache Log4j documentation states (jar names in 2. corrected):

Log4j may be used as the logging framework for Apache Tomcat. This support is implemented automatically by including the log4j-api, log4j-core, and log4j-appserver jars in the boot classpath. A file named log4j2-tomcat.xml, log4j2-tomcat.json, log4j2-tomcat.yaml, log4j2-tomcat.yml, or log4j2-tomcat.properties must also be placed in the boot classpath. This is most easily done by:

  1. Creating a set of directories in catalina home named log4j2/lib and log4j2/conf.
  2. Placing log4j-api-2.12.0.jar, log4j-core-2.12.0.jar, and log4j-appserver-2.12.0.jar in the log4j2/lib directory.
  3. Creating a file named log4j2-tomcat.xml, log4j2-tomcat.json, log4j2-tomcat.yaml, log4j2-tomcat.yml, or log4j2-tomcat.properties in the log4j2/conf directory.
  4. Create or modify setenv.sh in the tomcat bin directory to include CLASSPATH=$CATALINA_HOME/log4j2/lib/*:$CATALINA_HOME/log4j2/conf

But what to put in that log4j2-tomcat.* config file?

Upvotes: 6

Views: 27903

Answers (2)

Cristian Florescu
Cristian Florescu

Reputation: 1816

In order to work Tomcat 9.0.54+ setup with log4j2 please complete following:

  1. Activate JDK JUL bridge - https://logging.apache.org/log4j/2.x/log4j-jul/

To use the JDK Logging Adapter, you must set the system property java.util.logging.manager to org.apache.logging.log4j.jul.LogManager This must be done either through the command line (i.e., using the -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager argument) or by using System.setProperty() before any calls are made to LogManager or Logger.

  1. Copy all necessary log4j2 jars into classpath or /lib
  2. Configure -Dlog4j.configurationFile=/your/path/logger.xml like below example
<?xml version="1.0" encoding="utf-8"?>
<!-- ================================================ -->
<!--               Tomcat log4j2 logger               -->
<!-- ================================================ -->
<Configuration status="INFO" monitorInterval="60">
    <Properties>
        <Property name="logsdir">${sys:catalina.base}/logs</Property>
        <Property name="layout">[%d][%p][%c:%L:%M] - %m%n</Property>
    </Properties>
    <Appenders>
        <Console name="DEFAULT" target="SYSTEM_OUT">
            <PatternLayout pattern="${layout}"/>
        </Console>
        <Async name="ASYNC-DEFAULT" includeLocation="true">
            <AppenderRef ref="DEFAULT"/>
            <AppenderRef ref="INTOFILE"/>
        </Async>
        <RollingFile name="INTOFILE"
                     fileName="${logsdir}/worker.log"
                     filePattern="${logsdir}/catalina.%d{yyyy-MM-dd}-%i.log">
            <PatternLayout pattern="${layout}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="10 MB"/>
            </Policies>
            <DefaultRolloverStrategy max="100"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <!-- OFF -->

        <!-- ERROR -->

        <!-- WARN -->

        <!-- INFO -->
        <logger name="org.apache.catalina" level="INFO"/>
        <logger name="org.apache.catalina.core" level="INFO"/>
        <logger name="org.apache.tomcat" level="INFO"/>
        <logger name="org.apache.coyote" level="INFO"/>
        <logger name="org.apache.jasper" level="INFO"/>

        <!-- DEBUG -->
        <logger name="org.apache.catalina.startup" level="DEBUG"/>
        <logger name="org.apache.tomcat1" level="DEBUG"/>


        <Root level="TRACE">
            <AppenderRef ref="ASYNC-DEFAULT"/>
        </Root>
    </Loggers>
</Configuration>

Upvotes: 0

Christoph
Christoph

Reputation: 762

I found a sample properties file in the Apache Tomcat 7 documentation, but since this is meant for use with Log4j 1.x, I had to adapt it to the Log4j2 properties file syntax. This is the result:

# 'status' refers to log messages from Log4j2 itself
monitorInterval = 30
status = warn

property.loglevel.catalina = info
property.loglevel.localhost = info

property.layoutPattern.catalina = %d %-5p [%t] %-22.22c{1} %m%n
property.layoutPattern.localhost = %d %-5p [%t] %-30.30c{1} %m%n

# Roll-over the logs once per month using CronTriggerPolicy.

property.fileDatePattern.catalina = %d{yyyy-MM}
property.fileDatePattern.localhost = %d{yyyy-MM}

property.cronTriggerSchedule.catalina = 0 0 0 1 * ?
property.cronTriggerSchedule.localhost = 0 0 0 1 * ?

## Appenders

# N.B.: - No need to specify 'appenders = CATALINA, LOCALHOST, CONSOLE'
#         since these identifiers do not contain '.' characters.
#       - The sub-component identifiers 'policies' and 'cron' are arbitrarily
#         chosen; the actual type is specified via the 'type' attribute.
#       - 'DirectWriteRolloverStrategy' is used automatically since no 'fileName' specified.

appender.CATALINA.type = RollingFile
appender.CATALINA.name = RollingFile-CATALINA
appender.CATALINA.filePattern = ${sys:catalina.base}/logs/catalina.${fileDatePattern.catalina}.log
appender.CATALINA.layout.type = PatternLayout
appender.CATALINA.layout.pattern = ${layoutPattern.catalina}
appender.CATALINA.policies.type = Policies
appender.CATALINA.policies.cron.type = CronTriggeringPolicy
appender.CATALINA.policies.cron.schedule = ${cronTriggerSchedule.catalina}
appender.CATALINA.policies.cron.evaluateOnStartup = true
appender.CATALINA.filePermissions = rw-r-----
appender.CATALINA.fileOwner = tomcat
appender.CATALINA.fileGroup = adm

appender.LOCALHOST.type = RollingFile
appender.LOCALHOST.name = RollingFile-LOCALHOST
appender.LOCALHOST.filePattern = ${sys:catalina.base}/logs/localhost.${fileDatePattern.localhost}.log
appender.LOCALHOST.layout.type = PatternLayout
appender.LOCALHOST.layout.pattern = ${layoutPattern.localhost}
appender.LOCALHOST.policies.type = Policies
appender.LOCALHOST.policies.cron.type = CronTriggeringPolicy
appender.LOCALHOST.policies.cron.schedule = ${cronTriggerSchedule.localhost}
appender.LOCALHOST.policies.cron.evaluateOnStartup = true
appender.LOCALHOST.filePermissions = rw-r-----
appender.LOCALHOST.fileOwner = tomcat
appender.LOCALHOST.fileGroup = adm

# Uncomment if you want to keep logging to catalina.out after Log4j2 takes over.

#appender.CONSOLE.type = Console
#appender.CONSOLE.name = STDOUT
#appender.CONSOLE.layout.type = PatternLayout

## Configure which loggers log to which appenders

rootLogger.level = ${loglevel.catalina}
rootLogger.appenderRef.CATALINA.ref = RollingFile-CATALINA
#rootLogger.appenderRef.stdout.ref = STDOUT

# Here, the identifier does contain '.' characters, so we must specify the list.
loggers = org.apache.catalina.core.ContainerBase.[Catalina].[localhost]

logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].name = LOCALHOST
logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = ${loglevel.localhost}
logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].appenderRef.LOCALHOST.ref = RollingFile-LOCALHOST

The main reason for me to use Log4j2 was to be able get monthly log rotation, but you can easily adjust everything how you like, even without restarting Tomcat.

Upvotes: 5

Related Questions