log4j2 TimeBasedTriggeringPolicy not working as expected - log4j2

I have configured the log4j2.xml file in such a way that application.log file will be created and it should be rollover daily.
<?xml version="1.0" encoding="UTF-8"?>
<!-- ===================================================================== -->
<!-- Log4j2 Configuration -->
<!-- ===================================================================== -->
<Configuration status= "INFO">
<!-- Common properties used in all appenders -->
<Properties>
<Property name="logBaseDirectory">/apps/wsserver/8.5/bpm/logs/log4j/sbl</Property>
<Property name="logPattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p %c{1} %X{transaction.id} %m%n</Property>
<Property name="maxFileAge">90d</Property>
</Properties>
<!-- Define required appenders -->
<Appenders>
<!-- ============================================================================================================================================ -->
<!-- log4j 1.x to 2.x migratoin steps -->
<!-- DailyRollingFileAppender rolling file appender is no longer availble in log4j2. So we need to use RollingFile with TimeBasedTriggeringPolicy -->
<!-- Right most value in filePattern will be considered as Interval for TimeBasedTriggeringPolicy rolling -->
<!-- Orignal log file will be application.log and archive will be application-20200917.log.zip - Auto compression of file -->
<!-- Remove the all archived logs which are older than 90 days -->
<!-- ============================================================================================================================================ -->
<RollingFile name="application" fileName="${logBaseDirectory}/application.log" filePattern="${logBaseDirectory}/application-%d{yyyy-MM-dd}.log.zip">
<PatternLayout pattern="${logPattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy />
<CronTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${logBaseDirectory}" maxDepth="1">
<IfFileName glob="application-*.log.zip" />
<IfLastModified age="${maxFileAge}" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<!-- Define the list of loggers required -->
<Loggers>
<logger name="MediationServices" level="TRACE" additivity="false">
<appender-ref ref="application" />
</logger>
<root level="TRACE" additivity="false">
<appender-ref ref="application" />
</root>
</Loggers>
</Configuration>
But in JVM, applicatoin.log file is getting rollover after 10MB and if three times it is rolled, the first file is getting overwritten. That means at any point of time i am having application.log and application-2020-10-16.log.zip.
Why log4j2 (v2.13) is rolling over the files for every 10MB even though configured as daily? Any pointers identifying issue in log4j2 configuration is much apricated.

Issue has been identified. AS <SizeBasedTriggeringPolicy /> is defined in configuration file, log4j2 is considering 10MB default value as file size and getting rollover. After removing this tag, issue has been resolved.

Related

Log4j2 disable console on production

I'm developing a Web app and I'm using log4j2. In developing mode, I'm logging using RollingFile and Console appenders.
Everything is working properly, but I'd want to disable the Console appender when my project will be released and it will be in production mode.
Here's a slice of my log4j2.xml code:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="PropertiesConfig" packages="com.project.application">
<!-- PROPERTIES -->
<Properties>
<Property name="webName">Project</Property>
<Property name="logBaseDir">${sys:catalina.base}/logs/</Property>
<Property name="consolePattern">%highlight{[%-5level] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%c{1}] - %msg%n}</Property>
<Property name="rollingFilePattern">[%-5level] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%c{1}] - %msg%n</Property>
</Properties>
<!-- APPENDERS -->
<Appenders>
<!-- Console -->
<Console name="Console"
target="SYSTEM_OUT"
immediateFlush="true">
<PatternLayout>
<pattern>${consolePattern}</pattern>
</PatternLayout>
</Console>
<!-- RollingFile -->
<RollingFile name="RollingFile"
fileName="${sys:logBaseDir}${webName}/${webName}.log"
filePattern="${sys:logBaseDir}${webName}.%d{yyyy-MM-dd}.log"
immediateFlush="true">
<PatternLayout>
<pattern>${rollingFilePattern}</pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<!-- LOGGERS -->
<Loggers>
<Logger name="com.project.application" additivity="true" level="warn">
<AppenderRef ref="RollingFile" />
</Logger>
<Root level="info"> <!-- #TODO disable in production -->
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Thank you!
Use a filter, e.g. ThreadContextMapFilter:
<Console name="Console" target="SYSTEM_OUT" immediateFlush="true">
<ThreadContextMapFilter onMatch="DENY" onMismatch="NEUTRAL">
<KeyValuePair key="is-production" value="1"/><!-- skip on production -->
</ThreadContextMapFilter>
<PatternLayout>
<pattern>${consolePattern}</pattern>
</PatternLayout>
</Console>
The initialization of the ThreadContext entry can be perfomed in a ServletContextListener, e.g.:
#WebListener
public class Log4jThreadContextInitializer implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
String isProduction = isProduction() ? "1" : "0";
sce.getServletContext().log("Setting 'is-production' flag for Log4j to " + isProduction);
org.apache.logging.log4j.ThreadContext.put("is-production", isProduction);
}
private boolean isProduction() {
// TODO: production detection
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Spring-lookup made my life easier. My appender is like this:
<Appenders>
<Console name="console-local" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{2}:%L - %msg%n" />
</Console>
</Appenders>
I have added a property like this:
<Properties>
<Property name="console-appender">console-${spring:profiles.active}</Property>
</Properties>
And the logger is like this:
<Loggers>
<root level="info">
<appender-ref ref="${console-appender}"/>
</root>
</Loggers>
If my active profile is local, thus console-appender will be set to console-local, and the log will be shown in the console, as ref will find console-local.
Again, suppose, my active profile is prod, then console-appender will be set to console-prod, and the log will not be shown in the console, as ref will not find console-prod. Because Console's appender name is still console-local.
My log4j version is 2.14.1

log4j2 unlimited RollingFile

I'm using log4j2 and trying to log with log-rotation. Specifically, I want to log at the maximum size of 10MB and rotate unlimitedly. The configuration below generates 3 generations of rolling files because "DefaultRolloverStrategy max" is set to 3. Could you please, guide me how to log unlimited number of files with at the maximum size of 10MB?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="format1">%m%n</Property>
<Property name="logfile">${sys:logDirectory}/log.log</Property>
<Property name="logfile-archive">${sys:logDirectory}/log_%d{yyyy-MM-dd}.%i.log
</Property>
</Properties>
<Appenders>
<RollingFile name="logfile001" append="true" fileName="${logfile}"
filePattern="${logfile-archive}">
<PatternLayout>
<pattern>${format1}</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<DefaultRolloverStrategy max="3" />
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="logfile001" />
</Root>
</Loggers>
</Configuration>
Set an extreme value to DefaultRolloverStrategy max. E.g.
<DefaultRolloverStrategy max="1000000000" />
Update:
According to Log4j2 documentation, as of release 2.8, it can be done by setting fileIndex attribute to nomax. E.g.
<DefaultRolloverStrategy fileIndex="nomax" />

Log4j2 DefaultRolloverStrategy not working

I have rollover strategy with 2 days, but the files don't get remove. Can you please let know if this log4j2 configuration is valid for rollover strategy?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="baseDir">/log</Property>
<Property name="fileName">filelog</Property>
</Properties>
<Appenders>
<RollingFile name="LOG" fileName="${baseDir}/${fileName}.log"
filePattern="${baseDir}/${fileName}-%d{yyyy-MM-dd}.log" append="true">
<PatternLayout pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%m%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}" maxDepth="1">
<IfFileName glob="${fileName}-%d{yyyy-MM-dd}.log" />
<IfLastModified age="2d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="LOG" />
</Root>
</Loggers>
</Configuration>
Change the line of IfFileName to
<IfFileName glob="${fileName}-*.log" />
You can also use IfAccumulatedFileCount if you like
<Delete basePath="${baseDir}">
<IfFileName glob="${fileName}-*.log">
<IfAccumulatedFileCount exceeds="2"/>
</IfFileName>
</Delete>
Actually, I think the latter is better.

Log4j2 RollingFile appenders clashing

Log4j2 RollingFile appenders clashing
Below is a simplified debug version of our log4j2 configuration file (We rollover nightly not every minute!).This configuration, instead of it creating a Rollover file each minute (as per theTimeBasedTriggeringPolicy) will create one rollover file (non-tarred), containing JSON formatted logging, which will be overwritten every 20KB(although it will end up being slightly greater than 20KB (See Screenshot).We also get the following errors (abbreviated with "..."):-
2016-10-07 08:47:34,433 default-workqueue-4 ERROR Unable to copy file /.../logs/logFile-2016-10-07-08:47:11.log to /.../logs/logFile-2016-10-07-08:47:11.log: java.nio.file.NoSuchFileException /.../logs/logFile-2016-10-07-08:47:11.log
If we switch the order of the timeBasedRollingFileJsonLayout appender and the sizeBasedRollingFilePatternLayoutWithZippedArchive appender then no rollover occurs at all.
If we remove the sizeBasedRollingFilePatternLayoutWithZippedArchive appender then the timeBasedRollingFileJsonLayout appender works as expected.
We have the two different appenders for different environments, where the logs may or may not be hooked up to ELK.In our real log4j2 config file we use properties to select the appropriate appender for the environment.I have removed the properties from this file for clarity and to rule them out as a possible cause of the problem.
We are using log4j 2.6.2.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %logger{36} - %msg %n" />
</Console>
<RollingFile name="timeBasedRollingFileJsonLayout" append="true" fileName="logs/logFile.log" filePattern="logs/logFile-%d{yyyy-MM-dd-HH:mm}.log">
<JSONLayout properties="true" compact="true" eventEol="true" />
<Policies>
<TimeBasedTriggeringPolicy />
</Policies>
</RollingFile>
<RollingFile name="sizeBasedRollingFilePatternLayoutWithZippedArchive" append="true" fileName="logs/logFile.log" filePattern="logs/logFile-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %logger{36} - %msg %n" />
<Policies>
<SizeBasedTriggeringPolicy size="20KB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<logger name="logger.one" level="info" additivity="false">
<AppenderRef ref="timeBasedRollingFileJsonLayout" />
</logger>
<Logger name="logger.two" level="info" additivity="false">
<AppenderRef ref="timeBasedRollingFileJsonLayout" />
</Logger>
<Logger name="logger.three" level="info" additivity="false">
<AppenderRef ref="timeBasedRollingFileJsonLayout" />
</Logger>
<Root level="info">
<AppenderRef ref="timeBasedRollingFileJsonLayout" level="all" />
</Root>
</Loggers>
</Configuration>
I am at a loss to understand why you think this should work. You have two appenders trying to write to the same file trying to rollover based on different criteria and rollover to files with different names. It is no surprise that you are getting the file is in use error since two things have it open at once.

netbeans glassfish hibernate log4j2

I have a simple Netbeans 7.1.2 (NON MAVEN) project that use glassfish 3.1 server for testing.
I created a log4j2.xml file and placed it on the classpath
here it is
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="debug"/>
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} [%t] %-5p %c{1} - %m%n"/>
</layout>
</appender>
<appender name="rolling-file" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="c:\tmp\Program-Name.log"/>
<param name="MaxFileSize" value="500KB"/>
<param name="MaxBackupIndex" value="4"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %l - %m%n"/>
</layout>
</appender>
<logger name="org.hibernate">
<level value="info" />
</logger>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
<appender-ref ref="rolling-file" />
</root>
</log4j:configuration>
the project uses hibernate to store data from a web service to a database.
However I am not able to log anything. I can see the logs of hibernate into the Netbeans IDE but I cannot see the created on the filesystem file.
I have this error when calling the web service
SEVERE: ERROR StatusLogger Unknown object "logger" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored
SEVERE: ERROR StatusLogger root contains an invalid element or attribute "priority"
SEVERE: ERROR StatusLogger Unknown object "root" of type org.apache.logging.log4j.core.config.LoggerConfig is ignored
could someone pls help or give some advice I googled and stackoverflowed but without chance.
Paolo
I think that your log4j2.xml file is mixed with the old log4j style xml.
I'm having the same trouble as you when it comes to appending hibernate log to my application's log file. But I think that I can help with the logger error.
Try this file instead (and note the changes that I made):
<?xml version="1.0" encoding="UTF-8" ?>
<configuration name="SOME_PROJ_NAME" status="OFF">
<appenders>
<RollingFile name="rolling-file" fileName="c:/tmp/Program-Name.log" filePattern="c:/tmp/$${date:yyyy-MM}/Program-Name-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<pattern>%d{ABSOLUTE} [%t] %-5p %c{1} - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</appenders>
<loggers>
<root level="info"
<appender-ref ref="rolling-file"/>
</root>
<logger name="org.hibernate level="info">
<appender-ref ref="rolling-file"/>
</logger>
</loggers>
</configuration>
It is quite similar to the one that I'm using. Note that this file should be on classpath for log4j2 auto configuration to kick in.
The most important thing you should do when using the net to configure log4j2 is that you're looking at log4j2 and not log4j style configuration.
I suggest that you look in http://logging.apache.org/log4j/2.x/ for further info. They have a good downloadable pdf that you can check out.
In addition, check out my question about a similar problem.

Resources