I want to log asynchronously to 2 files, one for system logging, the other for user actions logging. So far I am logging to 1 file, my config file looks like this:
<configuration debug="true">
<property name="LOG_DIR" value="C:/blah" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{DD/MM/YYYY-HH:mm:ss.SSS} %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOG_DIR}/log.txt</file>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="com.logger.name" level="DEBUG" />
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<root level="warn">
<appender-ref ref="STDOUT" />
<appender-ref ref="ASYNC" />
</root>
</configuration>
And I create a logger like this:
public static final Logger LOG = LoggerFactory.getLogger("com.logger.name");
This works fine, but if I want to log to 2 separate files, do I need to write a second config file? Do I need a second Logger
object also? I would like to have one configuration and specify which file is logged to on creation of the Logger
object, is this possible? Thanks!
EDIT
Just to clarify, I want to log the user action to one file and the system logs to the other.
You can use two file appenders, one for system logging and other for user action logging. File appnder extends UnsynchronizedAppenderBase
Hence they are async. No need to create to Logger objects. Here is a example.
<appender name="fileAppender1" class="ch.qos.logback.core.FileAppender">
<file>c:/kp/kp1.log</file>
<filter class="com.kp.filters.KPFilter">
</filter>
<append>true</append>
<encoder>
<pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="fileAppender1" />
</root>
<appender name="fileAppender2" class="ch.qos.logback.core.FileAppender">
<file>c:/kp/kp2.log</file>
<append>true</append>
<encoder>
<pattern>
%d [%thread] %-5level %logger{30} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="org.kp">
<appender-ref ref="fileAppender2" />
<level value="debug"/>
</logger>
KPFilters.class
public class KPFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide(ILoggingEvent event) {
if(event.getLoggerName() !=null && event.getLoggerName().startsWith("org.kp")){
return FilterReply.DENY;
}
return FilterReply.ACCEPT;
}
}
If you want to have logs to be written to file generated by your package, you can use as given below
<logger name="com.kp">
<level value="trace" />
<appender-ref ref="fileappender2" />
</logger>
In worst scenario you can create custom appender by extend UnsynchronizedAppenderBase
and write custom code to process the error message. Based on the message type or message string you can write business logic to write to file or skip the error message.
**EDITED:**
You can initialize the log in usual way. For example if you want to log in MyClass.
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
LOG.warn("Hello");
Logback back passes the log instance to both appenders. which will be written to two different files.