log4j2 RollingFile with 3 policies - log4j2

I am using log4j2 version 2.7 with sprint-boot 1.5:
my configuration file (log4j2.xml) is:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="60">
<Properties>
<Property name="LOG_PATH">./log</Property>
<Property name="FILE_LOG_PATTERN">%date{yyyy-MM-dd'T'HH:mm:ss.SSSZ}{UTC}}, %5p, %X{component:-SERVICE}, %X{event:-EVENT}, ${PID:-???}, [%t], %40.40logger{40}, FCID=%X{FCID:-N/A}, %msg%n</Property>
<Property name="MAX_HISTORY">7</Property>
<Property name="MAX_FILE_SIZE">100MB</Property>
</Properties>
<Appenders>
<RollingFile name="FILE"
fileName="${LOG_PATH}/tests.log"
filePattern="${LOG_PATH}/tests.%d{yyyy-MM-dd}.%i.log.gz">
<PatternLayout>
<Pattern>${FILE_LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy/>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="${MAX_FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${MAX_HISTORY}"/>
</RollingFile>
</Appenders>
<Loggers>
<logger name="org.springframework" level="INFO"/>
<logger name="org.springframework.security.oauth2" level="INFO"/>
<logger name="org.springframework.http" level="ERROR"/>
<Logger name="org.springframework.boot" level="info"/>
<Logger name="org.springframework.boot.context.embedded.jetty" level="info"/>
<Root level="error">
<AppenderRef ref="FILE"/>
</Root>
</Loggers>
when I start the application I get this error:
ERROR Unable to invoke factory method in class class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile. java.lang.IllegalStateException: No factory method found for class org.apache.logging.log4j.core.appender.RollingFileAppender
If I remove one of the policies this error not showing. What is the problem?

Related

Server Logs not showing with log4j2

When I migrate from log4j to log4j2 Server Logs not showing.
Log4j2.xml exist in classpath.
here is my log4j2.xml file
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" packages="com.vermeg.maskpolicy.customLog" monitorInterval="5">
<Appenders>
<RollingFile name="FILE" fileName="${soliam.fo.logdir}/log/server.log" append="true"
filePattern="${soliam.fo.logdir}/log/$${date:yyyy-MM}/server-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="%d %-5p %X{userName}#%X{remoteAddress} [%c] %m%n"/>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
</RollingFile>
<Console name="CONSOLE" target="SYSTEM_OUT">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{ABSOLUTE} %-5p %X{userName}#%X{remoteAddress} [%c{1}] %m%n"/>
</Console>
<Rewrite name="rewrite">
<LogInterceptor/>
<AppenderRef ref="CONSOLE"/>
<AppenderRef ref="FILE"/>
</Rewrite>
</Appenders>
<Loggers>
<Logger name="com.bsb.soliam.fo.aspectj.AspectJLogger" level="${log4j.level}">
<AppenderRef ref="rewrite"/>
</Logger>
<Logger name="org.jgroups" level="WARN">
<AppenderRef ref="rewrite"/>
</Logger>
<Logger name="org.apache.cxf.phase.PhaseInterceptorChain" level="ERROR">
<AppenderRef ref="rewrite"/>
</Logger>
<Logger name="org.springframework.flex.servlet.MessageBrokerHandlerAdapter" level="WARN">
</Logger>
<Logger name="org.apache.commons.javaflow" level="INFO">
</Logger>
<Logger name="org.apache.commons.beanutils.locale" level="INFO">
</Logger>
<Logger name="com.bsb.soliam.fo.core.filepoller.JmsJobScheduler" additivity="false" level="${log4j.level}">
<AppenderRef ref="rewrite"/>
</Logger>
<Root level="${log4j.root.level}">
<AppenderRef ref="rewrite"/>
</Root>
</Loggers>
</Configuration>
log before migration
enter image description here
log after migration just show hibernate log.
I don't know the main cause of this problem ,
can anyone help please

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

Adding a filename to log4j2 logger

I am specifying the filename to log4j2 logger in the XML as below. All works fine but i get the error
2017-09-06 16:54:33,496 main ERROR Unknown object "RandomAccessFile" of type org.apache.logging.log4j.core.appender.RandomAccessFileAppender is ignored: try nesting it inside one of: ["Appenders", "Loggers", "Properties", "Scripts", "CustomLevels"].
<?xml version="1.0" encoding="UTF-8"?>
<Configuration package="log4j.test"
status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd/MM/yyyy HH:mm:ss} %c %m%n"/>
</Console>
</Appenders>
<RandomAccessFile name="FILE" fileName="${sys:log4j.saveDirectory}/CMSAutomation.${date:yyyy-MM-dd_hh-mm-ss}.log" append="true" immediateFlush="false">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-6p %C{1}.%t:%L >>> %m%n"/>
</RandomAccessFile >
<Loggers>
<Logger name="log4j.test.Log4jTest" level="debug">
<AppenderRef ref="Console"/>
</Logger>
<Root level="trace">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
This error is coming because RandomAccessFile appender is not defined within <Appenders> XML element.
Below is the correct way of defining any appender including RandomAccessFile appender -
<?xml version="1.0" encoding="UTF-8"?>
<Configuration package="log4j.test"
status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd/MM/yyyy HH:mm:ss} %c %m%n"/>
</Console>
<RandomAccessFile name="FILE" fileName="${sys:log4j.saveDirectory}/CMSAutomation.${date:yyyy-MM-dd_hh-mm-ss}.log" append="true" immediateFlush="false">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-6p %C{1}.%t:%L >>> %m%n"/>
</RandomAccessFile>
</Appenders>
<Loggers>
<Logger name="log4j.test.Log4jTest" level="debug">
<AppenderRef ref="Console"/>
</Logger>
<Root level="trace">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
You can check the same in log4j2 documentation here.
Additional one point, you are not using RandomAccessFile appender in any logger. If you will not define it in any logger, it wouldn't work.

Log4j2 - Seperate logs for different levels - How do I print just the INFO levels?

How do I print just the INFO levels?
My current log is printing all INFO, WARN, ERROR and FATAL levels to console - I understand why this is happening. (because they are all above INFO)
Is there a way to just specify that just and only just, INFO levels get sent to the console appender and not everything above it?
Currently have the following log4j2 xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="App" packages="">
<Appenders>
<File name="logFile" fileName="C:\Users\user\workspace\logs\log.out">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.App" level="info" additivity="false">
<AppenderRef ref="logFile" level="error"/>
<AppenderRef ref="Console" level="info"/>
</Logger>
<Root level="error">
<AppenderRef ref="logFile" />
</Root>
</Loggers>
Need to use a ThresholdFilter;
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT" />
This blocks the WARN level and everything above it. So now it only accepts info.

Two patterns in same log file is not working in log4j2

I'd like to configure log4j 2 with two different patterns in same appender. i.e., Whenever there is an error, a specific pattern should be present in the log file. I am not trying two different log files, but two different pattern in same log file. Whenever there is an error, I would see "MYDOMAINDOTCOM_SUPPORT_NEEDED" and this string will trigger an automatic email to support team.
I have the below configuration which prints error message in "RollingFile" appender only and "RollingFileError" appender is ignored. What am I missing ?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Properties>
<Property name="log-path">/documents/log</Property>
</Properties>
<Appenders>
<RollingFile name="RollingFile" fileName="${log-path}/myexample.log"
filePattern="${log-path}/$${date:yyyy-MM}/myexample-%d{yyyy-MM-dd}-%i.log"
immediateFlush="true">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %X{packetRefId} - %msg%n</pattern>
<!-- %d{dd/MMM/yyyy HH:mm:ss,SSS}- %c{1}: %m%n -->
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="100 KB" />
</Policies>
<DefaultRolloverStrategy max="4" />
</RollingFile>
<RollingFile name="RollingFileError" fileName="${log-path}/myexample.log"
filePattern="${log-path}/$${date:yyyy-MM}/myexample-%d{yyyy-MM-dd}-%i.log"
immediateFlush="true">
<param name="threshold" value="error" />
<PatternLayout>
<pattern>MYDOMAINDOTCOM_SUPPORT_NEEDED %d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %X{packetRefId} - %msg%n</pattern>
<!-- %d{dd/MMM/yyyy HH:mm:ss,SSS}- %c{1}: %m%n -->
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="100 KB" />
</Policies>
<DefaultRolloverStrategy max="4" />
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.springframework.beans.factory" level="info" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Logger name="root" level="debug" additivity="false">
<appender-ref ref="RollingFile" level="debug" />
<appender-ref ref="RollingFileError" level="error" />
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="RollingFile" />
</Root>
</Loggers>
</Configuration>
You should never configure two appenders to write to the same file. Having two rolling file appenders that both use the same file and roll over to the same file pattern is never going to work correctly.
Also, your configuration would end up with all error messages being logged twice; once with the RollingFile appender due to its debug level, and once on the RollingFileError appender due to its error level.
Instead, you should have a single rolling file appender and use a PatternSelector to decide which pattern to use. See http://logging.apache.org/log4j/2.x/manual/layouts.html#Pattern_Selectors for documentation on pattern selectors.

Resources