log4j - Separate folder per month



You may want to write your log messages into sepearate folder on monthly basis. We're creating a separate folder for each month.

To write your logging information into multiple files, you would have to use org.apache.logging.log4j.RollingFileAppender class which extends the FileAppender class and inherits all its properties.

log4j2.properties

appender.0.type = RollingFile
appender.0.name = logFile

log4j2.xml

<Appenders>
   <RollingFile name="logFile" filePattern="logs/%d{yyyy-MM}/%d{yyyy-MM-dd}.log.zip">
      <JsonTemplateLayout/>
      <DirectWriteRolloverStrategy>
         <Delete basePath="logs" maxDepth="2">            
            <IfLastModified age="P90D"/>
         </Delete>
      </DirectWriteRolloverStrategy>
      <TimeBasedTriggeringPolicy/>
   </RollingFile>
</Appenders>

RollingFileAppender Configuration

RollingFileAppender has the following configurable parameters:

Property Type Default Value Description
fileName Path   The path to the current log file If the folder containing the file does not exist, it will be created.
filePattern Path   The pattern for the archived log files. If fileName is null, the file pattern will also be used for the current file.
name String   The name of the appender.
bufferSize int 8192 The size of the ByteBuffer internally used by the appender.
bufferedTo boolean true If set to true, Log4j Core will format each log event in an internal buffer, before sending it to the underlying resource. The RandomAccessRollingFile Appender always enables the internal buffer.
ignoreExceptions boolean true If false, logging exception will be forwarded to the caller of the logging statement. Otherwise, they will be ignored.
immediateFlush boolean true If set to true, the appender will flush its internal buffer after each event.
filter String   Allows filtering log events just before they are formatted and sent.
layout Layout   Formats log events.
triggerPolicy TriggeringPolicy   Determines when to archive the current log file.
RolloverStrategy RolloverStrategy   Determines the actions performed during a rollover.
append boolean true If true, the log file will be opened in APPEND mode. On most systems this guarantees atomic writes to the end of the file, even if the file is opened by multiple applications.
bufferedIo boolean true If set to true, Log4j Core will format each log event in an internal buffer, before sending it to the underlying resource.
createOnDemand boolean false The appender creates the file on-demand. The appender only creates the file when a log event passes all filters and is routed to this appender. Defaults to false.
filePermissions PosixFilePermissions null If not null, it specifies the POSIX file permissions to apply to each created file. The permissions must be provided in the format used by PosixFilePermissions.fromString(), e.g. rw-rw----. The underlying files system shall support POSIX file attribute view.
fileOwner String null If not null, it specifies the file owner to apply to each created file. The underlying files system shall support file owner attribute view.
fileGroup String null If not null, it specifies the file group owner to apply to each created file. The underlying files system shall support POSIX file attribute view.
locking boolean false If true, Log4j will lock the log file at each log event. Note that the effects of this setting depend on the Operating System: some systems like most POSIX OSes do not offer mandatory locking, but only advisory file locking. This setting can also reduce the performance of the appender.

RollingFileAppender Configuration Examples

Following is a sample configuration file log4j2.properties for RollingFileAppender −

log4j2.properties

# Define the rolling file appender
appender.0.type = RollingFile
appender.0.name = logFile

# Set the file pattern
appender.0.filePattern = logs/%d{yyyy-MM]/%d{yyyy-MM-dd}.log.zip
appender.0.layout.type = JsonTemplateLayout

# set the roll over startegy
# we're creating a new log file every day
# and deleting 15 days old log files
appender.0.strategy.type = DirectWriteRolloverStrategy
appender.0.strategy.delete.type = Delete
appender.0.strategy.delete.basePath = logs
appender.0.strategy.delete.maxDepth = 2
appender.0.strategy.delete.0.type = IfLastModified
appender.0.strategy.delete.0.age = P15D
appender.0.policy.type = TimeBasedTriggeringPolicy

# Define the root logger with appender file
rootLogger.level = DEBUG
rootLogger.appenderRef.0.ref = logFile

If you wish to have an XML configuration file equivalent to the above log4j.properties file, then here is the content:

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="logFile" packages="">
   <Appenders>
      <RollingFile name="logFile" filePattern="logs/%d{yyyy-MM}/%d{yyyy-MM-dd}.log.zip">
         <JsonTemplateLayout/>
         <DirectWriteRolloverStrategy>
            <Delete basePath="logs" maxDepth="2">            
               <IfLastModified age="P90D"/>
            </Delete>
         </DirectWriteRolloverStrategy>
         <TimeBasedTriggeringPolicy/>
      </RollingFile>
   </Appenders>
   <Loggers>
      <Root level="debug">
         <AppenderRef ref="logFile"/>
      </Root>
   </Loggers>
</Configuration>

Example - Usage of FileAppender

Now consider the following Java Example which would generate logging information:

Log4jDemo.java

package com.tutorialspoint;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4jDemo{

   /* Get actual class name to be printed on */
   private static final Logger LOGGER = LogManager.getLogger();

   public static void main(String[] args) {
      LOGGER.debug("Hello this is an debug message");
      LOGGER.info("Hello this is an info message");
   }
}

We're using log4j2.properties file.

Output

Compile and run the above program. It would create a folder similar to 2025-09-07 folder in logs directory which contains a log file having the following log information:

{"@timestamp":"2025-09-07T03:33:26.911Z","ecs.version":"1.2.0","log.level":"DEBUG","message":"Hello this is an debug message","process.thread.name":"main","log.logger":"com.tutorialspoint.Log4jDemo"}
{"@timestamp":"2025-09-07T03:33:26.915Z","ecs.version":"1.2.0","log.level":"INFO","message":"Hello this is an info message","process.thread.name":"main","log.logger":"com.tutorialspoint.Log4jDemo"}
Advertisements