My application has lots of EJBs. The current bespoke Logger implementation creates a logger like this;
private static Logger logger = Logger.getInstance("SERVICE_NAME");
, and the logging will go into a file;
(path)/SERVICE_NAME/SERVICE_NAME.log
I want to replicate this behaviour with logback, but having real trouble grabbing the 'logger' name in the logback.xml configuration. It can be seen in the log encoder.pattern, i.e. "%d %-5level %logger{35} - %msg %n".
Any ideas how I can get this into a property/variable and then use it in the element?
I have a partial solution. If I create my own Discriminator, I can then use the Discriminator in the logback.xml to implement seperate-log-files-per-EJB.
Discriminator;
public class LoggerNameBasedDiscriminator implements Discriminator<ILoggingEvent> {
private static final String KEY = "loggerName";
private boolean started;
@Override
public String getDiscriminatingValue(ILoggingEvent iLoggingEvent) {
return iLoggingEvent.getLoggerName();
}
@Override
public String getKey() {
return KEY;
}
public void start() {
started = true;
}
public void stop() {
started = false;
}
public boolean isStarted() {
return started;
}
}
Then my logback.xml;
<configuration debug="true" scan="true" scanPeriod="30 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg</pattern>
</encoder>
</appender>
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator class="package.to.LoggerNameBasedDiscriminator"/>
<sift>
<appender name="FILE-${loggerName}" class="ch.qos.logback.core.FileAppender">
<FILE>path/to/logs/${loggerName}/${loggerName}.log</FILE>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-50(%level %logger{35}) %msg%n</pattern>
</encoder>
</appender>
</sift>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="SIFT" />
</root>
</configuration>
This solution seems to work, but now I have no time or size based log rotation!
Thanks to your example I implemented a solution for a loggername-based discriminator which routes different logger output to different files. Although the documentation of logback is so verbose, I couldn't find this essential information. You've surely found the solution mentioned by yayitswei already.
logback.xml:
[...]
<timestamp key="startTimestamp" datePattern="yyyy-MM-dd"/>
<timestamp key="folderTimestamp" datePattern="MM-yyyy"/>
<property name="LOGDIR" value="/var/log/spock" />
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator class="com.enterprise.spock.LoggerNameBasedDiscriminator" />
<sift>
<appender name="FILE-${loggerName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGDIR}/${loggerName}-${startTimestamp}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOGDIR}/${folderTimestamp}/${loggerName}-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
<maxFileSize>500KB</maxFileSize>
<maxHistory>100</maxHistory>
<totalSizeCap>50MB</totalSizeCap>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%level %date{HH:mm:ss.SSS}: %msg %n</pattern>
</encoder>
</appender>
</sift>
</appender>
[...]
Edit:
I replaced TimeBasedRollingPolicy with SizeAndTimeBasedRollingPolicy as proposed here. You'll need at least logback 1.1.7 for that.
What you get with this, is a logfile for each Logger created.
Every logfile will look like this: /var/log/loggername-2017-08-03.log.
When about 500KB was written to the file, it will be archived as a gz-zipfile into /var/log/loggername/08-2017/loggername-2017-08-03-0.log.gz.
The 0 at the end of the gz-zipfile-name is the %i
from the <fileNamePattern>
above. Without the %i
it won't work. Remember to use <configuration debug=true>
in logback.xml if something won't work.