Why my log will be redirected into catalina.out?

macking_liu picture macking_liu · Jun 3, 2014 · Viewed 8.2k times · Source

In my application, I use log4j2 to output log.

<!-- log4j2 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.0-beta9</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.0-beta9</version>
</dependency>

And the app hosts in Tomcat7.

Firstly I use the default way to output Catalina.out, but I found my app log will be redirected into Catalina.out. So I follow the Tomcat's documents. http://tomcat.apache.org/tomcat-7.0-doc/logging.html

Then change it with log4j's way. But finally, it runs as default.

log4j.rootLogger = INFO, CATALINA

# Define all the appenders
log4j.appender.CATALINA = org.apache.log4j.DailyRollingFileAppender
log4j.appender.CATALINA.File = ${catalina.base}/logs/catalina
log4j.appender.CATALINA.Append = true
log4j.appender.CATALINA.Encoding = UTF-8
# Roll-over the log once per day
log4j.appender.CATALINA.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.CATALINA.layout = org.apache.log4j.PatternLayout
log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c- %m%n

log4j.appender.LOCALHOST = org.apache.log4j.DailyRollingFileAppender
log4j.appender.LOCALHOST.File = ${catalina.base}/logs/localhost
log4j.appender.LOCALHOST.Append = true
log4j.appender.LOCALHOST.Encoding = UTF-8
log4j.appender.LOCALHOST.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.LOCALHOST.layout = org.apache.log4j.PatternLayout
log4j.appender.LOCALHOST.layout.ConversionPattern = %d [%t] %-5p %c- %m%n

log4j.appender.MANAGER = org.apache.log4j.DailyRollingFileAppender
log4j.appender.MANAGER.File = ${catalina.base}/logs/manager

Any one meet such kind of problem, can show me the solution to avoid this?

PS: The logger module design as:

import java.io.BufferedWriter;
import java.util.Date;

public class Logger {

    private static org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger(Logger.class
            .getName());

    public static void error(String proj, String opera, String param, String msg) {
        logger.error(log("Error", proj, opera, param, msg));
    }

    public static void debug(String proj, String opera, String param, String msg) {
        logger.debug(log("Debug", proj, opera, param, msg));
    }

    public static void warn(String proj, String opera, String param, String msg) {
        logger.warn(log("Warn", proj, opera, param, msg));
    }

    public static void info(String proj, String opera, String param, String msg) {
        logger.info(log("Info", proj, opera, param, msg));
    }

    private static String log(String type, String proj, String opera, String param, String msg) {
        // Build log content with JSON
        StringBuilder sb = new StringBuilder();
        sb.append("{\"time\": \"");
        sb.append(DateUtil.formatMilliSecond(new Date()));
        sb.append("\", \"level\": ");
        sb.append("\"" + type + "\", \"module\": ");
        sb.append("\"" + proj + "\", \"operation\": ");
        sb.append("\"" + opera + "\"");

        if (!StringUtil.isEmpty(param)) {
            sb.append(", \"parameter\": \"" + param + "\"");
        }

        if (!StringUtil.isEmpty(msg)) {
            sb.append(", \"message\": \"" + msg + "\"");
        }
        sb.append("}");
        writeLog(sb.toString());
        return sb.toString();
    }


    public static void setLog(String module) {
        logger = org.apache.logging.log4j.LogManager.getLogger(module);
    }

}

And the log4j2 configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
    <appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%msg%n"/>
        </Console>
        <RollingFile name="MinerLog" fileName="/local/logs/miners.log"
                     filePattern="/local/logs/$${date:yyyy-MM}/miners-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
            </Policies>
        </RollingFile>
        <RollingFile name="CaptainLog" fileName="/local/logs/captain.log"
                     filePattern="/local/logs/$${date:yyyy-MM}/captain-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
            </Policies>
        </RollingFile>
        <RollingFile name="DataProviderLog" fileName="/local/logs/das_dataprovider.log"
                     filePattern="/local/logs/$${date:yyyy-MM}/dataprovider-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
            </Policies>
        </RollingFile>
    </appenders>
    <loggers>
        <root level="debug">
            <appender-ref ref="Console"/>
        </root>
        <logger name="miner" level="debug">
            <appender-ref ref="MinerLog" level="info"/>
            <appender-ref ref="Console"/>
        </logger>
        <logger name="captain" level="debug">
            <appender-ref ref="CaptainLog" level="info"/>
            <appender-ref ref="Console"/>
        </logger>
        <logger name="dataprovider" level="debug">
            <appender-ref ref="DataProviderLog" level="info"/>
            <appender-ref ref="Console"/>
        </logger>
    </loggers>
</configuration>

Answer

Arun Gopalpuri picture Arun Gopalpuri · Jan 29, 2016

It's being redirected to catalina.out because you have console log defined as an appender and these get redirected to catalina.out.

However, we do need console logs for local development but don't want them to show in other environments. You can use ThresholdFilter along with configuration properties to console log only in local and not in other environments with the below sample code:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="300">
    <Properties>
        <Property name="consoleLogLevel">error</Property>
    </Properties>
    <Appenders>
        <RollingFile name="FileOut" fileName="/dev/pref-api.log"
                     filePattern="/dev/pref-api-%d{yyyy-MM-dd}.gz">
            <PatternLayout pattern="%date{yyyy/MM/dd HH:mm:ss.SSS} %-5level [%t] [%logger{36}] %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>

        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%date{yyyy/MM/dd HH:mm:ss.SSS} %-5level [%t] [%logger{36}] %msg%n"/>
            <Filters>
                <ThresholdFilter level="${sys:consoleLogLevel}"  onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="warn" additivity="false">
            <AppenderRef ref="FileOut"/>
            <AppenderRef ref="Console"/>
        </Root>

        <Logger name="com.github.api" level="debug" additivity="false">
            <AppenderRef ref="FileOut"/>
            <AppenderRef ref="Console"/>
        </Logger>
    </Loggers>
</Configuration>

If you pass a -DconsoleLogLevel=debug in local you will see all logs from com.github.api being logged to console but in other environments if you don't pass any value it takes default of error and only shows error stack in catalina out.