madhu
madhu

Reputation: 139

How to separate log output on method level (use different log files within one class)

I am trying to log in to two different logger from a class.I have a class and defined two methods and trying to log messages from one method to a one log file and from another method in to different log file.

Here is my code:

   private static final Logger logger = LoggerFactory.getLogger(SummaryService.class);


    public void empSalInfo(){
            logger.info("employee info.."); // this should log into SalaryLogAppender 
        }

        public void empDeptInfo(){
            logger.info("dept info"); // this should log into DeptLogAppender
        }

Here is my logback-spring file:

  <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <property name="LOGS_HOME" value="${LOG_PATH}"/>
        <!-- standard encoder pattern-->
        <property name="LOG_PATTERN" value="%d{MM/dd/yy HH:mm:ss.SSS} %-5p %t %C{0}:%L - %m%n" />

        <include resource="org/springframework/boot/logging/logback/defaults.xml" />
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>${LOG_PATTERN}</Pattern>
        </layout>
        </appender>

        <property name="EMPLOYEE_LOG_FILE" value="${LOGS_HOME}/employee.log"/>
        <appender name="FILE"   class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${EMPLOYEE_LOG_FILE}</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${EMPLOYEE_LOG_FILE}.%d{yyyy-MM-dd}</fileNamePattern>
                <maxHistory>14</maxHistory>
            </rollingPolicy>
            <encoder>
                <charset>UTF-8</charset>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
        </appender>

        <property name="EMPLOYEE_SALARY_LOG_FILE" value="${LOGS_HOME}/emp_sal.log"/>
        <appender name="SalaryLogAppender"   class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${EMPLOYEE_SALARY_LOG_FILE}</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${EMPLOYEE_SALARY_LOG_FILE}.%d{yyyy-MM-dd}</fileNamePattern>
                <maxHistory>14</maxHistory>
            </rollingPolicy>
            <encoder>
                <charset>UTF-8</charset>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
        </appender>

        <property name="EMPLOYEE_DEPT_LOG_FILE" value="${LOGS_HOME}/emp_sal.log"/>
        <appender name="DeptLogAppender"   class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${EMPLOYEE_DEPT_LOG_FILE}</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${EMPLOYEE_DEPT_LOG_FILE}.%d{yyyy-MM-dd}</fileNamePattern>
                <maxHistory>14</maxHistory>
            </rollingPolicy>
            <encoder>
                <charset>UTF-8</charset>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
        </appender>


        <logger name="com.nbt.apps.employeeInfo" level="info" additivity="false">
            <appender-ref ref="FILE" />
            <appender-ref ref="STDOUT" />
        </logger>



        <logger name="com.garmin.gh.apps.wellnessmonitor.service.EmployeeService" level="info" additivity="false">
            <appender-ref ref="DeptLogAppender" />
            <appender-ref ref="SalaryLogAppender"/>
        </logger>



        <root level="INFO">
            <appender-ref ref="FILE" />
            <appender-ref ref="STDOUT" />
        </root>

    </configuration>

How to  log from one class to two different log files based on methods?

Upvotes: 1

Views: 3138

Answers (1)

Kevin Peters
Kevin Peters

Reputation: 3474

If you want to write into different logfiles, at first you need different (file-)appenders to enable separating the outputs.

This is a simple logback-spring.xml which would provide multiple appenders and related loggers:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="application.log"/>
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>

    <appender name="oneAppender" class="ch.qos.logback.core.FileAppender">
        <file>one.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="anotherAppender" class="ch.qos.logback.core.FileAppender">
        <file>another.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="oneLogger" level="ALL" additivity="false">
        <appender-ref ref="oneAppender" />
    </logger>

    <logger name="anotherLogger" level="ALL" additivity="false">
        <appender-ref ref="anotherAppender" />
    </logger>

</configuration>

The (default) root logger forwards all common application messages into a common "application.log", e.g. application startup messages and so on.

Then, there are two explicit file appenders (oneAppender & anotherAppender) bound to different files (one.log & another.log).

At least two loggers (oneLogger & anotherLogger) bound to this appenders which can be referenced by their names to pipe the certain messages to the different logfiles.

With that configuration you can now implement your logging, the most simple way would be to create two separate Logger instances like that directly inside your business layer:

final Logger oneLogger = LoggerFactory.getLogger("oneLogger");

final Logger anotherLogger = LoggerFactory.getLogger("anotherLogger");

public void empSalInfo(){
    oneLogger.info("employee info.."); // this should log into SalaryLogAppender 
}

public void empDeptInfo(){
    anotherLogger.info("dept info"); // this should log into DeptLogAppender
}

But since that would be some kind of verbose and error-prone, maybe think about intercepting your business code (in case it's managed by Spring) with Spring AOP to keep it clean of logging concerns.

Upvotes: 3

Related Questions