Sturm
Sturm

Reputation: 759

log4j how to auto-create a new log file each day without archiving old ones

We have a specific logging schema where I work. Since multiple programs need to be logged, we have them all sorted by date, rather than filename. So, for example, a log file generated by our Script Launcher program on Sept. 27, 2016 on the computer called "warrior" would be located thusly:

<root folder>/logs/warrior/2016/09 - Sep/27 - Launcher.log

It makes for finding the correct log file for a specific computer very organized, yet also very quick. If some of this logging schema needs to be changed, I do have a little bit of wiggle room to do so. If possible, though, I'd like to keep it as it is.

The problem I'm running into is that some of our users keep the program running overnight. The next day, all logging activity appears in the previous day's log file. Is there any way to have log4j (version 2.6 currently) automatically detect that a new day has occurred and change the logging file to 28 - Launcher.log, keeping the same schema as above? Also to have it auto-create a 10 - Oct/ folder when next month hits, etc.?

I don't need log4j to archive anything, since the log files will always be rolling over each day, so I don't really need a Trigger Policy (except maybe a Size-Based one, just in case a file gets really huge) on a RollingFileAppender. Here's what I have so far in the log4j2.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
  <Properties>
    <Property name="filename">logs/artdept.log</Property>
    <Property name="baseDir">/Volumes/ArtDept/ArtDept/Scripts/sky-artdept/logs</Property>
  </Properties>
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="MyFile" fileName="${filename}">
      <PatternLayout>
        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
      </PatternLayout>
    </File>
    <RollingFile name="RollFile" fileName="${baseDir}/${env:USER}/${date:yyyy}/${date:MM} - ${date:MMM}/${date:dd} - Launcher.log"
            filePattern="${baseDir}/Archives/${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <SizeBasedTriggeringPolicy size="250 MB" />
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="RollFile"/>
    </Root>
  </Loggers>
</Configuration>

I'm sure I'm missing something simple to get it to change files at Midnight, but I can't figure out what it is.

Upvotes: 1

Views: 5139

Answers (1)

Sturm
Sturm

Reputation: 759

So it turns out that using a CronTriggeringPolicy is what's needed, along with setting its schedule attribute to "0 0 0 * * ?". This is shown in a few examples in log4j's documentation, but it was broken in version 2.6.2. Although that policy is set to have the log file roll over once per day at Midnight, it would actually continually roll it over--once per second after the first trigger!

Version 2.7 was just released today (10/06/2016) and--among many other things--fixes this issue. So, yay, CronTriggeringPolicy works as expected now! Now a new problem has reared its ugly head, but I'll post about that tomorrow in a separate thread when I do some more testing.

And here's the log4j2.xml configuration file I'm using:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
  <Properties>
    <Property name="filename">logs/artdept.log</Property>
    <Property name="baseDir">/Volumes/ArtDept/ArtDept/Scripts/sky-artdept/logs</Property>
  </Properties>
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="MyFile" fileName="${filename}">
      <PatternLayout>
        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
      </PatternLayout>
    </File>
    <RollingFile name="DailyRoll" fileName="${baseDir}/${env:USER}/${date:yyyy}/${date:MM} - ${date:MMM}/Launcher.log"
            filePattern="${baseDir}/${env:USER}/${date:yyyy}/${date:MM} - ${date:MMM}/%d{dd} - Launcher-%i.log">
      <PatternLayout>
        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <CronTriggeringPolicy schedule="0 0 0 * * ?" />
        <SizeBasedTriggeringPolicy size="250 MB" />
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="DailyRoll"/>
    </Root>
  </Loggers>
</Configuration>

I hope this helps out others!

Upvotes: 2

Related Questions