Using Log4j2 in WebApps - java

I'm currently writing a web app using Servlet 3.1. According to the Log4j2 website
Log4j 2 "just works" in Servlet 3.0 and newer web applications.. But whenever I start the server (Tomcat 8.0.5), I get an error Error processing element RandomAccessFileAppender: CLASS_NOT_FOUND. When I lookup the class using eclipses "Open Type", I see that this class exists and is in the package org.apache.logging.log4j.core.appender.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="off" packages="org.apache.logging.log4j.core.appender">
<Appenders>
<RandomAccessFileAppender name="DEFLOG" ignoreExceptions="false" fileName="${web:rootDir}/log/log.log">
<PatternLayout pattern="%d %p %C{1.} [%t] %m%n" />
</RandomAccessFileAppender>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="DEFLOG"/>
</Root>
</Loggers>
</Configuration>
This log4j2.xml file is located under src/log4j2.xml, the Log4j2-jars "log4j-api-2.0-rc1.jar" and "log4j-core-2.0-rc1.jar" are located under WEB-INF/lib/.

Related

How to fix javax.xml.parsers.ParserConfigurationException after switching to log4j2? [duplicate]

This question already has an answer here:
ParserConfigurationException while using log4j2 with junit
(1 answer)
Closed 10 months ago.
Switched from log4j1 to log4j2 (1.2.17 to 2.12).
I have 5 projects that use the new log4j2. I removed the old jar for log4j1, and all the references and paths now refer to the new added jar for log4j2.
I am using log4j2.xml to set the configuration for log4j2.
4 out of 5 other projects are running perfectly with the new log4j2, logging to the right file, with the correct pattern described in the log4j2.xml file.
One project - let's call it "ProjectX" - is returning an error when trying to access the same logger:
ERROR StatusLogger Caught javax.xml.parsers.ParserConfigurationException
The following are used when running the project:
jdk1.7.0_79
oracle.jdbc_11.1.1\ojdbc6dms.jar;
oracle.nlsrtl_11.1.0\orai18n.jar;
oracle.odl_11.1.1\ojdl.jar;
oracle.dms_11.1.1\dms.jar;
oracle.xdk_11.1.0\xmlparserv2.jar;
oracle.xdk_11.1.0\xml.jar;
com.oracle.toplink_1.0.0.0_11-1-1-5-0.jar;
org.eclipse.persistence_1.1.0.0_2-1.jar;
com.bea.core.antlr.runtime_2.7.7.jar;
javax.persistence_1.0.0.0_2-0-0.jar;
wlserver_10.3\server\lib\weblogic.jar;
commons-io-2.4.jar;
log4j-api-2.12.0.jar;
log4j-core-2.12.0.jar;
wlserver_10.3\server\lib\weblogic.jar
The log4j2.xml I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<!-- Path to the log files -->
<Property name="log-path">C:/logs</Property>
</Properties>
<Appenders>
<!-- Logger that prints to the Console window -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout>
<pattern>%-6p%d{DATE} - %C{1}.%M:%L - %m%n</pattern>
</PatternLayout>
</Console>
<!-- Logger that prints to the log file specified in the fileName -->
<RollingFile name="LoggerFile" fileName="${log-path}/App.log" filePattern="${log-path}/App-%d{yyyy-MM-dd}-%i.log" immediateFlush="true" append="true">
<PatternLayout>
<pattern>%-6p%d{DATE} - %C{1}.%M:%L - %m%n</pattern>
</PatternLayout>
<!-- The maximum size of a log file -->
<Policies>
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<!-- Number of log files before starting to roll over -->
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="RollingFileLogger" level="DEBUG">
<AppenderRef ref="LoggerFile"/>
</Logger>
<Root level="DEBUG">
<AppenderRef ref="LoggerFile"/>
</Root>
</Loggers>
</Configuration>
Any idea what causes the error ERROR StatusLogger Caught javax.xml.parsers.ParserConfigurationException?
Could it be oracle.xdk_11.1.0\xmlparserv2.jar or xml.jar?
I tried xmlparserv2.jar version 12.2, and it fixed the error.
To download version 12.2 of xmpparserv2.jar:
https://maven.oracle.com/com/oracle/jdbc/xmlparserv2/12.2.0.1/xmlparserv2-12.2.0.1.jar
I upgraded the xmlparser jar from version 11.1 to version 12.2: xmlparserv2-12.2.0.1.jar.
I added it to the project and it fixed the problem.

Log4j2 Servlet 3.0 not logging

I have a JAX-RS 2.0 application running on a Tomcat 7 server, and I'm using log4j2 along with SLF4J to record the server logs to a file.
I can't seem to get any logs to show up properly in my log file when running the server in production, although when I run my integration tests, logs are output correctly.
In production, the logs are merely redirected to the console instead.
My log4j2.xml file is located in the WEB-INF/classes folder, and I've included all the necessary dependencies as well.
My configuration file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="file" fileName="log/trace.log" append="true" filePattern="log/trace.%i.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %X %logger{36} - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="my.package" level="TRACE" additivity="false">
<AppenderRef ref="file"/>
</Logger>
<Root level="WARN">
<AppenderRef ref="file"/>
</Root>
</Loggers>
</Configuration>
The web.xml needs no configuration (I'm following the documentation found on the log4j2 website).
EDIT
I've tried setting the Root level to TRACE but everything still gets redirected to console. The file log/trace.log itself is created, it's just never written to. I also tried setting immediateFlush=true but that didn't have any impact either.
I noticed you have status logging (log4j internal logging) set to TRACE. This will dump log4j internal initialization messages to the console. It this what you mean?
Otherwise, the config you provide shows there is no logger that has an appender-ref pointing to the ConsoleAppender.
So, if you are also seeing your application logs being output to the console (in addition to log4j's status log messages), I suspect there is another log4j2.xml (or log4j2-test.xml) config file in the classpath somewhere.
Fortunately log4j's status logs should also show the location of the log4j config file, so you can confirm which config file is actually being loaded.
You can switch off status logging by setting <Configuration status="WARN"> after confirming all works correctly.
I figured it out!
Turns out I was using the gretty plug-in with gradle, which contains it's own logging package (the logback library).
It used it's own internal logback.xml which was redirecting to console. I fixed this by overwriting the internal logback.xml with my own (using logback's configuration) and now everything works as expected!

log4j2 to chainsaw not working - nothing shows up in the 'Zeroconf' tab of Chainsaw

I am trying to to use Chainsaw to view my application's logger events but there is nothing showing up under the 'Zeroconf' tab in chansaw.
I've followed Scott's guide in log4j2 to chainsaw hello world not working… what am I doing wrong? - but no luck. I was going to comment on that question asking how teryet got it working in the end, but as my reputation is below 50, the site didn't allow me.
Environment
OS: OSX Mavericks
IDE: Netbeans 8.0 (Build 201403101706)
Java: 1.7.0_45; Java HotSpot(TM) 64-Bit Server VM 24.45-b08
log4j: 2.0rc1
Chainsaw: downloaded the latest DMG from http://people.apache.org/~sdeboy/
Things I've made sure
- included jmdns.jar in the classpath of my application
- Used PatternLayout in my config log4j.xml
- Ensure advertiser URL has three slashes
My log4j.xml config file
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF" advertiser="multicastdns">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%date{ABSOLUTE} [%thread] %logger{3}.%style{%method}{Blue}%style{(line%line)}{Red}%X %highlight{%-5level} - %msg%n%xEx"/>
</Console>
<RollingFile name="RollingFile" fileName="../logs/POS.log" filePattern="../logs/$${date:yyyy-MM}/POS-%d{yyyyMMdd-HHmmss}.log">
<PatternLayout pattern="%date{ABSOLUTE} [%thread] %logger{3}.%style{%method}{Blue}%style{(line%line)}{Red}%X %highlight{%-5level} - %msg%n%xEx"/>
<Policies>
<OnStartupTriggeringPolicy/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
<File name="testFile" fileName="../logs/POS2.log" bufferedIO="false" advertiseURI="file:///localhost/Users/arthurhsieh/Documents/NetBeansProjects/AES/logs/POS2.log" advertise="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%n"/>
</File>
</appenders>
<loggers>
<root level="all"> <!-- <root level="trace"> -->
<appender-ref ref="Console"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="testFile" />
</root>
</loggers>
</configuration>
I can see logger events in the POS2.log file though.
Thanks in advance for any help/guidances. Cheers.
My issue went away after I restarted my system, i.e., Chainsaw is working and i can view my logs by connecting through the Zeroconf tab.
My guess is this is an Apple OS issue rather than Chainsaw itself.

Log4J2 and Tomee Plus 7.0.47 not working

According to here, Log4j2 should work with Tomcat7.0.47. I'm using TomEE Plus 7.0.47.
I have a webapplication deployed with a log4j2.xml in my web-inf/classes folder. This is the config:
<?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] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="File" fileName="${sys:catalina.home}/logs/testapp.log">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="org.alex" level="TRACE" additivity="false">
<AppenderRef ref="File"/>
</Logger>
<Root level="INFO">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
I have a logger declared in a class with name org.alex.util.JSON:
private static final Logger LOG = LoggerFactory.getLogger(JSON.class);
I'm using slf4j-api 1.7.5, and have the following libs added to the tomcat lib:
slf4j-api-1.7.5.jar
log4j-api-2.0-rc1.jar
log4j-core-2.0-rc1.jar
log4j-slf4j-impl-2.0-rc1.jar
If I change the Configuration status to TRACE, I can see my configuration file being picked up and configuration happens as expected. Also I can see the MBeans being added.
However, there's not one logging statement ending up in my logfile. I debugged into the log4j2 Logger, and see that the isEnabled(...) method returns false because the logger (com.alex.util.JSON) has the level "ERROR" set, while the configuration set the package org.alex to TRACE.
Further investigation shows it uses a DefaultConfiguration configured for level=ERROR, and only root is configured. I'm thinking of a classloader issue, but I can't seem to figure out what the cause is and how to solve it.
Does anyone know what I'm doing wrong?
This should work on trunk
Btw saw log4j2 has hacks for tomcat and since tomee wraps classloaders not sure they work as expected...
This is very strange. Please raise a ticket for this in the Log4j2 issue tracker so the Log4j team can take a look.
The problem may go away if you put the jar files you mentioned inside WEB-INF/lib instead of in Tomcat's lib folder.
To be comple log4j2 relies on servletcontainerinitializer which are called after ejb and app scanning so ejbs can be loaded too early. Doing the same with a tomcat context listener would make it working better

Setting to, from, subject values from properties at Runtime in log4j2 SMTPAppender

I'm using log4j 2.0-beta9. I have a question about the SMTP appender. I need to configure the subject, from and to values from properties. I'm logging a MapMessage and my config is as below -
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="DEBUG">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t] %-5p %c - %m%n"/>
</Console>
<SMTP name="Mail" subject="Error Log for ${env:HOSTNAME}" to="${sys:mail.to}" from="${sys:mail.from}"
smtpHost="${sys:mail.host}" smtpPort="${sys:mail.port}" smtpDebug="true" bufferSize="1">
<PatternLayout>
<pattern>%d [%t] %-5p %c - %m%n</pattern>
</PatternLayout>
</SMTP>
<Async name="AsyncMail">
<appender-ref ref="Mail" />
</Async>
</appenders>
<loggers>
<root level="info">
<appender-ref ref="Console"/>
<appender-ref ref="AsyncMail">
<MapFilter onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="throwable.class" value="java.lang.RuntimeException" />
</MapFilter>
</appender-ref>
</root>
</loggers>
</configuration>
// Java Code to log the msg
Throwable throwable; // this is the exception that is thrown by the app.
MapMessage message = new MapMessage();
message.put("throwable.message", throwable.getMessage());
message.put("throwable.class", throwable.getClass().getName());
message.put("throwable.stacktrace", ExceptionUtils.getStackTrace(throwable)); // ExceptionUtils from apache-commons
LOGGER.error(message, throwable); // org.apache.logging.log4j.Logger
The problem is that none of these values are replaced dynamically. Is there any way to do this?
Thanks in advance.
You need to set the mail.to and mail.from System properties. The problem you're having might be that you're running in a Servlet 3.0 environment, in which case the Log4j2.xml file is being processed before your code that sets the properties is executed.
If that is the case, you can create a servlet container initializer that you configure in your web.xml file to load before Log4j2's servlet container initializer is loaded.

Categories

Resources