I have a Java EE application packaged with ejbs and war. Following is the structure of the EAR:
myapp.ear
-lib
-META-INF
-ejbjar1.jar
-ejbjar2.jar
-mywebapp.war
I need to use log4j2 so I have tried to configure it at first from the web.xml by following instructions to initialize Log4j 2 in a web application but when I am creating the Logger
in an EJB it is throwing:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
The instruction given here is not much clear to me, but what I understand that I need to place the log4j2.xml in a shared location.
I have tried to place the xml inside the EAR, inside the EAR/lib, inside the EAR/META-INF but I got same result. In these case I haven't configured anything in the web.xml.
How can I configure log4j2 for an EAR so that the configuration will be available for all the classes (classes for ejb-module, web-module)?
I am using Weblogic 12C. Previously I have successfully used log4j2 in Weblogic 11G but in that case the packaging was a WAR file.
You can package the log4j2.xml file in one of your ejbjar1.jar or create a new configonly.jar if you like. It should then be shared across your ejb modules and war. Also if you want to separate the logs from ejb and war you can configure two different file appenders and two different loggers one for ejb and one for war. Here is a working sample log4j2.xml with GlassFish v4.1 Please note the status="trace" to trace any configuration issue.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MMM-dd EEE HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
</Console>
<!-- for GlassFish v4.1 the logs will be in the domains directory -->
<RollingFile name="appServerRollingFile" fileName="../app-logs/app-server.log"
append="true"
filePattern="../app-logs/$${date:yyyy-MMM}/app-server-%d{yyyy-MMM-dd}-%i.log.zip"
ignoreExceptions="false">
<PatternLayout
pattern="%d{yyyy-MMM-dd EEE HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
</RollingFile>
<!-- for GlassFish v4.1 the logs will be in the domains directory -->
<RollingFile name="appWebRollingFile" fileName="../app-logs/app-web.log"
append="true"
filePattern="../app-logs/$${date:yyyy-MMM}/app-web-%d{yyyy-MMM-dd}-%i.log.zip" ignoreExceptions="false">
<PatternLayout
pattern="%d{yyyy-MMM-dd EEE HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="TRACE">
<AppenderRef ref="Console" level="TRACE"/>
</Root>
<Logger name="test.business" level="TRACE" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="appServerRollingFile" />
</Logger>
<Logger name="test.web" level="TRACE" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="appWebRollingFile" />
</Logger>
</Loggers>
</Configuration>
Just to be sure, lets quote the sections that matter from the documentation you were referring to:
Java EE Applications
A Java EE application will consist of one or more WAR files and
possible some EJBs, typically all packaged in an EAR file. Usually, it
is desirable to have a single configuration that applies to all the
components in the EAR. The logging classes will generally be placed in
a location shared across all the components and the configuration
needs to also be shareable. Be sure to follow the instructions to
initialize Log4j 2 in a web application.
From "Using Log4j 2 in Web Applications":
Configuration
Log4j allows the configuration file to be specified in
web.xml using the log4jConfiguration context parameter. Log4j will
search for configuration files by:
- If a location is provided it will be searched for as a servlet context
resource. For example, if log4jConfiguration contains "logging.xml"
then Log4j will look for a file with that name in the root directory
of the web application.
- If no location is defined Log4j will search
for a file that starts with "log4j2" in the WEB-INF directory. If more
than one file is found, and if a file that starts with "log4j2-name"
is present, where name is the name of the web application, then it
will be used. Otherwise the first file will be used.
- The "normal"
search sequence using the classpath and file URLs will be used to
locate the configuration file.
Note that when starting from an EAR, each module therein starts typically using it's own isolated classloader.
First attempt at making it to work might by by providing the log4j2 as part of the individual embedded war components.
So, I am not sure what you are using to assemble your EAR, but easiest would be to drop it in the WEB-INF of (each of) your webModule (war) packaged within your EE Application (EAR).
If you are using maven, you would have separate projects for your individual EJB and web modules. As such, you should be able to provide the log4j2 file in following locations:
- Web Module: src/main/webapp/WEB-INF
- EJB: src/main/resources (which should let maven copy it to the META-INF within your jar).
To still provide the log4j2 file as part of your EAR (shared by modules), I think a Class-Path entry needs to be made in your META-INF/MANIFEST.MF. You would provide the directory, or your resource jar location as part of the Class-Path. For providing a directory, a trailing path separator will be needed.
I didn't try it out just now, but I hope it will get you a clue and you will correct me where needed.
Also Log4j2 has the feature to automatically reload on changes and adapt to it on the fly. For that to work in your advantage, I would strongly urge for you to provide the Log4j2 file as part of the Server's class path, and not embedded deep within your jar, war, or ear. It will just be easier to find and modify.