Search code examples
spring-bootloggingmicroserviceslog4j2

Disabled console logging does not write to files


I am new to log4j configuration using xmls. I want to disable the console logging i.e only logs with level Error should come on console. Rest of the logs should go to their respective files.

Here is the log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <Property name="basePath">/var/log/svc</Property>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss} %-5p [%C{1}] %M{1}:%L - %m%n</Property>
        <Property name="consoleLogPattern">[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</Property>
        <Property name="JSON_LOG_PATTERN">{"time": "%d{ISO8601}", "level": "%-5level", "service": "${env:SERVICE}",
            "class": "%-40.40logger{39}:%L", "environment": "${sys:spring.profiles.active:-defaultEnv}", "instanceId" :
            "%X{instanceId}", "requestId" : "%X{logMDCFilter.UUID}", "message": "%enc{%maxLen{%m}{204800}}{JSON}",
            "traceId": "%X{X-B3-TraceId}", "spanId": "%X{X-B3-SpanId}", "exception":
            "%enc{%maxLen{%ex}{204800}}{JSON}"}%n
        </Property>
        <Property name="EXT_API_LOG_PATTERN">%n%date{yyyy-MM-dd HH:mm:ss ZZZZ} %message%n</Property>
        <Property name="DEFAULT_API_LOG_PATTERN">%n%date{yyyy-MM-dd HH:mm:ss ZZZZ}, "traceId": "%X{X-B3-TraceId}",
            "spanId": "%X{X-B3-SpanId}", %message%n
        </Property>
    </Properties>


    <CustomLevels>
        <CustomLevel name="SERVICE_LOG" intLevel="530"/>
    </CustomLevels>

    <Appenders>

        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${consoleLogPattern}"/>
        </Console>

        <RollingFile name="errorLog" fileName="${basePath}/svc-application-error.log"
                     filePattern="${basePath}/svc-application-error-%d{yyyy-MM-dd}-%i.log.zip">
            <LevelRangeFilter minLevel="ERROR" maxLevel="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="2000KB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>

        <RollingFile name="infoLog" fileName="${basePath}/svc-application-info.log"
                     filePattern="${basePath}/svc-application-info-%d{yyyy-MM-dd}-%i.log.zip">
            <LevelRangeFilter minLevel="INFO" maxLevel="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${JSON_LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="2000KB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>

        <RollingFile name="serviceLog" fileName="${basePath}/svc-application-service.log"
                     filePattern="${basePath}/svc-application-service-%d{yyyy-MM-dd}-%i.log.zip">
            <LevelRangeFilter minLevel="SERVICE_LOG" maxLevel="SERVICE_LOG" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${DEFAULT_API_LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="20000KB"/>
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>

    </Appenders>

    <Loggers>
        <Logger name="com.application.service" additivity="true">
            <AppenderRef ref="errorLog"/>
            <AppenderRef ref="infoLog"/>
            <AppenderRef ref="Console"/>
            <AppenderRef ref="serviceLog"/>
        </Logger>

        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

If I keep log level all at the end then it prints the logs to all the files along with console. But if I change that to error then only error logs are printed to file and console. Could you please help me on the below -

  1. Logs should be written to respective files but only error logs should come to console.
  2. How to write logs with custom log levels to particular files once we achieve the first point.

Solution

  • I was able to achieve this with the below minor tweak -

     <Loggers>
            <Logger name="com.application.service" additivity="false" level="all">
                <AppenderRef ref="errorLog"/>
                <AppenderRef ref="infoLog"/>
               <-- <AppenderRef ref="Console"/>!-->
                <AppenderRef ref="serviceLog"/>
            </Logger>
    
            <Root level="error">
                <AppenderRef ref="Console"/>
            </Root>
        </Loggers>