I would like to configure logback to do the following.
- Log to a file
- Roll the file when it reaches 50MB
- Only keep 7 days worth of logs
- On startup always generate a new file (do a roll)
I have it all working except for the last item, startup roll. Does anyone know how to achieve that? Here's the config...
<appender name="File" class="ch.qos.logback.core.rolling.RollingFileAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg \(%file:%line\)%n</Pattern>
</layout>
<File>server.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>server.%d{yyyy-MM-dd}.log</FileNamePattern>
<!-- keep 7 days' worth of history -->
<MaxHistory>7</MaxHistory>
<TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<MaxFileSize>50MB</MaxFileSize>
</TimeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
None of the other suggestions was appropriate for my situation. I didn't want to use a size-and-time-based solution, because it requires configuring a MaxFileSize, and we are using a strictly time-based policy. Here is how I accomplished rolling the file on startup with a TimeBasedRollingPolicy:
The trick is to set the nextCheck time to 0L, so that isTriggeringEvent() will think it's time to roll the log file over. It will thus execute the code necessary to calculate the filename, as well as conveniently resetting the nextCheck time value. The subsequent call to rollover() causes the log file to be rolled. Since this only happens at startup, it is a more optimal solution than the ones that perform a comparison inside isTriggerEvent(). However small that comparison, it still degrades performance slightly when executed on every log message. This also forces the rollover to occur immediately at startup, instead of waiting for the first log event.
The @NoAutoStart annotation is important to prevent Joran from executing the start() method before all the other initialisation is complete. Otherwise, you get a NullPointerException.
Here is the config:
Hope this helps!
Overriding the isTriggeringEvent() method in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP should work nicely. Just return 'true' the first time isTriggeringEvent() method is called.
The API has changed (for example setMaxFileSize no longer exists) and a lot of the stuff above doesn't seem to work, but I have something that is working for me against logback 1.1.8 (the latest at this time).
I wanted to roll on startup and roll on size, but not time. This does it:
With this you also need a rolling policy. FixedWindowRollingPolicy would probably do, but I don't like it because I want to keep a large number of files and it is very inefficient for that. Something that numbers incrementally up (instead of sliding like FixedWindow) would work, but that doesn't exist. As long as I am writing my own I decided to use time instead of count. I wanted to extend current logback code, but for the time based stuff the rolling and triggering policies are often combined into one class, and there is logs of nesting and circular stuff and fields with no getters, so I found that rather impossible. So I had to do a lot from scratch. I keep it simple and didn't implement features like compression - I'd love to have them but I am just trying to keep it simple.
And then config looks like
if you're frustrated this is not solved natively, vote for it at
http://jira.qos.ch/browse/LOGBACK-204
http://jira.qos.ch/browse/LOGBACK-215
(it's been years, and to me this is absolutely critical functionality, although I know many other frameworks fail at it also)
I got the following to work (combining ideas from previous answers). Note I was dealing with size-based files, not time-based, but I am guessing the same solution works.
}
I found another solution for rolling the logFile once, when the application starts.
I use logback's
RollingFileAppender
with logback'sFixedWindowRollingPolicy
and my own implementation of aTriggeringPolicy<E>
.The
FixedWindowRollingPolicy
gets the fileNamePattern for the new logFile, where%1
is the new number of the file. The maxIndex stands for the maximum number of my "history". More information: FixedWindowRollingPolicyMy implementations
TriggeringPolicy
returns true for the first time, when isTriggeringEvent(...) gets called. So the WindowRollingPolicy rolls over the logfiles, when the Policy gets called the first time, and afterwards it will not roll over again.The xml-configuration for the
RollingFileAppender
:The
TriggeringPolicy
:It works for me, using the following class as timeBasedFileNamingAndTriggeringPolicy :