Log4j2 logging of classes in tomcat's shared classpath - java

I have a webapp with it's own classes under its WEB-INF folder, which is using log4j2 for logging. I configured it with log4j2-web and can see logs from those classes. So far so good.
I am wrecking my brain, however, getting to see logs from libs (jars) that are defined in the common/shared classpath of tomcat. A jar (one for example) I am trying, is using log4j2 api too for logging.
Note that only when I move the jar from the common classpath to lib folder under the webapp's WEB-INF it does show logs. Meaning the configuration file is fine regarding appender and logger names...
Is there something I'm missing or this is how log4j2 works?
I am using Tomcat 7
Log4j2 2.11.0
Any help would be welcomed! Thanks.
The (simplified) log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<RollingFile name="sample.appender" fileName="server.log"
filePattern="server.log.%i.gz" bufferedIO="false" bufferSize="0">
<PatternLayout pattern="%d [%t] (%F:%L) %-5p - %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="5242880"/>
</Policies>
<DefaultRolloverStrategy max="13"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.my.server" level="DEBUG" additivity="false">
<AppenderRef ref="sample.appender"/>
</Logger>
<Logger name="com.3rd.party.sample" level="DEBUG" additivity="false">
<AppenderRef ref="sample.appender"/>
</Logger>
<Root level="FATAL"/>
</Loggers>

Related

Log4j2 Define 2 root loggers with different levels

I have 2 appenders I'm using - Console and custom appender called MyAppender which should ignore all messages with levels lower than ERROR (meaning - it should only support ERROR and FATAL). The Console should be able to support all levels.
I've tried several ways to define it but it seems that the filter doesn't work for the root level appenders. How can this be achieved? My current log4j2 definition:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="com.mysample.logging.appenders" status="DEBUG">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<MyAppender name="MyAppender">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</MyAppender>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="Console"/>
<AppenderRef ref="MyAppender" />
</Root>
</Loggers>
</Configuration>
The loggers are one hierarchy starting with the root logger.
There are no two root loggers within one working setup of Log4j.
What you want to achieve is to have different thresholds on the appenders. Check the link that Piotr suggested:
Using log4j2, is it possible to assign a specific level to a appender?

log4j2.xml config file is not being loaded

I have upgraded my log4j from 1.2.17 to 2.16.0. Therefore I had to rewrite my log4j.xml as well as to rename it to log4j2.xml. I have made the necessary changes. However it seems that my new config is not loaded. I have tried to configure log4j through both web.xml :
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>classpath:log4j2.xml</param-value>
</context-param>
and -Dlog4j2.configurationFile. Both approaches failed and I am not getting any logs in mylog.log file. However when running the application locally the Console display the logs.
This is my log4j2.xml :
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="trace">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%-5p %c{1} - %m%n"/>
</Console>
<RollingFile name="DAILY_LOG" fileName="${catalina.base}/logs/mylog.log"
filePattern="${catalina.base}/logs/mylog.log.%d{yyyy-MM-dd}">
<PatternLayout pattern="%d %-5p [%c] [%X{sid}:%X{uid}] %m%n "/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!-- Limit the org.springframework category to INFO as its DEBUG is verbose -->
<Logger name="org.springframework" level="INFO"/>
<!-- Limit the org.hibernate category to INFO as its DEBUG is verbose -->
<Logger name="org.hibernate" level="INFO"/>
<!-- Limit the org.apache category to INFO as its DEBUG is verbose -->
<Logger name="org.apache" level="INFO"/>
<Logger name="org.myproject" level="INFO"/>
<!-- Root Logger -->
<Root level="INFO">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="DAILY_LOG"/>
</Root>
</Loggers>
</Configuration>
I have tried to debug log4j configuration by using : -Dorg.apache.logging.log4j.simplelog.StatusLogger.level=trace. I have noticed that the LoggerContext instance is well created and all listed loggers are as well built.
I wonder if my config is wrongly written. Can someone please confirm or deny this to me.
I found the solution. This took me a while to figure out. The problem was due to the new syntax used by log4j 2.x to resolve system properties. Unlike log4j 1.x which used ${some.property} syntax for property substitution , log4j 2.x uses ${sys:some.property}. I had to add that sys prefix to make it work.
Source : https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution

Externalize property configuration for log4j.xml

Background: I have log4j.xml file configured for our spring based application, which looks like below.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="FATAL" shutdownHook="disable" packages="com.gemstone.gemfire.internal.logging.log4j">
<Properties>
<Property name="gemfire-pattern">[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} <%thread> tid=%tid %C{1.}] %message%n%throwable%n< /Property>
</Properties>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="${gemfire-pattern}"/>
</Console>
<RollingFile name="eventLogFile" fileName="/opt/data/service/logs/events.log"
filePattern="/opt/data/service/logs/events-%d{yyyy-MM-dd}-%i.log">
<PatternLayout>
<pattern>%d{dd/MMM/yyyy HH:mm:ss,SSS} %p - %c{1}: %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<DefaultRolloverStrategy max="20" fileIndex="max"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.gemstone" level="INFO" additivity="true">
<filters>
<MarkerFilter marker="GEMFIRE_VERBOSE" onMatch="DENY" onMismatch="NEUTRAL"/>
</filters>
</Logger>
<Logger name="com.app.mypackage" level="INFO" additivity="true">
<AppenderRef ref="eventLogFile"/>
</Logger>
<Root level="INFO">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Now, I want log4j to write log statements with let's say 'countryName'. And, this 'countryName' should be configured via external property file.
For e.g, the "gemfire-pattern" will have this externalised property name $${countryName}.
<Property name="gemfire-pattern">[$${countryName} %level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} <%thread> tid=%tid %C{1.}] %message%n%throwable%n< /Property>
Considering this log4j system properties, in my case, the log4j.component.properties is not being picked up by log4j.
Any thoughts on how to fetch a property value from external properties file in log4j.xml?
References:
how-to-read-property-variable-from-file-into-log4j2
log4j system properties
log4j properties substitution
Thanks in advance.
log4j.component.properties is used to add log4j specific system properties like log4j.configurationFile, org.apache.logging.log4j.level etc.
To refer to user defined properties, include the property file inside the logback configuration and refer to the keys using ${KEY}
<configuration>
<property file="country.properties" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${countryName}</file>
...
Logback also allows you to externalise parts of the configuration using File inclusion feature.
https://logback.qos.ch/manual/configuration.html#fileInclusion
<configuration>
<include file="src/main/java/chapters/configuration/includedConfig.xml"/>
...
Make sure the content in the external xml file is encolsed with <included> </included> tag
Note- System properties(-Dcountry="") and Environment variables can also be referred using ${PROPERTY_NAME} inside the logback configuration.

Log4j in tomcat8 not showing logs

This is mt Log4j:
log4j.rootLogger=ERROR, CA, FA
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.Target=System.out
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c:%L - %m%n
log4j.appender.FA=org.apache.log4j.RollingFileAppender
log4j.appender.FA.File=${catalina.base}/logs/Z2.log
log4j.appender.FA.MaxFileSize=5MB
log4j.appender.FA.MaxBackupIndex=10
log4j.appender.FA.layout=org.apache.log4j.PatternLayout
log4j.appender.FA.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] [%-5p] [%c:%L]: %m%n
log4j.logger.com.datastax.driver.core=ERROR
log4j.logger.com.dcf=DEBUG
Now i am using tomcat8, befor i was using tomcat7 it works great, and save the log file under /var/log/tomcat7/logs/Z2.log
After i uninstall tomcat7 and install tomcat8, i can't find the z1.log file.
log4j.appender.FA.File=${catalina.base}/logs/Z2.log
I don't have enough reputation to comment but is 'CATALINA_BASE' being set as an environmental property?
ie either inferred from 'CATALINA_HOME' or explicitly set?
What happens when you enable debugging for log4j?
This may show why the log file is not being created etc
What I generally do is leave the container logging as it stands but use log4j in any web / EE apps. By doing this, container logging will work with no changes and any web / EE apps are independent ie it is easier to change web / EE containers if necessary.
For Tomcat 8, the native logging library is 'JULI' which implements several key elements of the java.util.logging API.
The following configuration works for
Tomcat 8.0.30
jdk1.8.0_66
log4j 2.5
[web-app-name] / WEB-INF / lib
commons-logging-l.2.jar
log4j-api-2.5.jar
log4j-core-2.5.jar
log4j-jcl-2.5.jar
[web-app-name] / WEB-INF / classes / log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="LOG_FILE_PATH">${sys:catalina.home}/logs</Property>
<Property name="PATTERN_JBOSS" >%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %m%n</Property>
<Property name="PATTERN_TOMCAT">%d{dd-MMM-yyyy HH:mm:ss.SSS} %-5p [%t] %m%n</Property>
<Property name="PATTERN" >${PATTERN_JBOSS}</Property>
</Properties>
<Appenders>
<Console name="console">
<PatternLayout pattern="${PATTERN_TOMCAT}"/>
</Console>
<RollingFile name="daily-file" fileName ="${LOG_FILE_PATH}/globaltrax.log"
filePattern="${LOG_FILE_PATH}/globaltrax-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="${PATTERN_JBOSS}"/>
<TimeBasedTriggeringPolicy/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="console"/>
</Root>
<logger name="lpms.web.PurchaseOrderAction" level="TRACE">
<AppenderRef ref="console"/>
</logger>
<logger name="lpms.web.PurchaseOrderAction" level="TRACE">
<AppenderRef ref="daily-file"/>
</logger>
</Loggers>
</Configuration>
This defines one console logger and one daily log file logger which is typical.
Note that ‘CATALINA_HOME’ must be set as a ‘system’ environmental variable - this is used in the line:
<Property name="LOG_FILE_PATH">${sys:catalina.home}/logs</Property>

log4j2.xml is not loading in eclipse

I'm fairly new to log4j. Trying to use log4j2.xml to configure. I added the file to the build path and it worked once, but is no longer working.
This is my log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</appenders>
<loggers>
<root level="TRACE">
<appender-ref ref="Console"/>
</root>
</loggers>
</configuration>
I stripped it down, just to test it to get it working. I checked debug, and the logger config is using Default.
I also tried naming the file log4j2-test.xml.
Any ideas?
Thanks
Since you uses "servlets" as the tag, I assume you are working in a web application. You need to place your log4j.xml into a location that your web application classloader can find. For example, the WEB-INF/classes directory.

Categories