How to setup Log4j2 for an application deployed in WildFly 9? - java

When I test my application with JUnit, it is printing the log as specified by layout pattern in log4j2.xml, but when I deploy my application
in WildFly 9, I am no more getting the same format. Even the log level in Log4j2 is also not reflecting while deployed in server.
JUnit log example:
2016-02-15 11:14:16,314 DEBUG [main] b.t.r.c.XAPool - a connection's
state changed to IN_POOL, notifying a thread eventually waiting for a
connection
Server log example:
11:11:33,796 INFO [org.quartz.core.QuartzScheduler] (ServerService
Thread Pool -- 89) Scheduler
quartzScheduler_$_anindya-ubuntu1455514892022 started.
Log4j2.xml:
<Configuration status="WARN" name="myapp" monitorInterval="5">
<Appenders>
<RollingFile name="RollingFile" fileName="${myapp.log-dir}/myapp.log"
filePattern="${myapp.log-dir}/$${date:yyyy-MM}/myapp-%d{MM-dd-yyyy}-%i.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
<DefaultRolloverStrategy max="100">
<Delete basePath="${myapp.log-dir}" maxDepth="2">
<IfFileName glob="*/myapp-*.log">
<IfLastModified age="7d">
<IfAny>
<IfAccumulatedFileSize exceeds="1 GB" />
<IfAccumulatedFileCount exceeds="1" />
</IfAny>
</IfLastModified>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.company.myapp" level="trace" additivity="false">
<AppenderRef ref="RollingFile"/>
</Logger>
<Root level="info">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
While starting the server, I am providing below starup properties as JAVA_OPTS:
export JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active='qa'
-Dlog4j.configurationFile=/home/anindya/1.0/log4j2.xml -myapp.log-dir=/home/anindya/log -Dorg.jboss.logging.provider=log4j"
I have no specific setup in web.xml as it is Servlet 3.1 container. But I have a jboss-deployment-structure.xml in my WEB-INF as below:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->
<exclusions>
<module name="org.apache.logging.log4j" />
</exclusions>
</deployment>
</jboss-deployment-structure>
And finally, here are my classpath dependencies (only the relevant parts are mentioned here):
hibernate-5.0.7.Final dependencies
jbpm-6.3.0.Final dependencies
spring-4.2.4.RELEASE dependencies
commons-logging-1.2.jar
log4j-1.2-api-2.5.jar
log4j-api-2.5.jar
log4j-core-2.5.jar
log4j-jcl-2.5.jar
log4j-slf4j-impl-2.5.jar
log4j-web-2.5.jar
jboss-logging-3.3.0.Final.jar
With all of the above setup, I am still not able to configure Log4j2 in WildFly environment according to my log4j2.xml. Can someone please help?
NOTE: I am running WildFly in standalone mode and I would like to avoid using jboss-cli.

I managed to get it working by using the below jboss-deployment-structure.xml.
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<exclusions>
<module name="org.apache.logging.log4j" />
</exclusions>
<exclude-subsystems>
<subsystem name="logging"/>
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
All I had to do is to exclude the logging subsystem.

Late to the game but I needed support for log4j2 in Wildfly and thought I would share some details for anyone else facing this. This solution will let you configure logging through standalone.xml, that is no log4j2.xml will be used/picked up. The solution I chose is to bridge log4j2 to slf4j. Wildfly supports slf4j out-of-the-box. For the advanced users the solution in one sentence is 'Create a Wildfly module and use it', for others like me the solution follows a bit more detailed below...
First create a wildfly module, I will not give all the details how this is done, but my module.xml ended up looking like this
<module xmlns="urn:jboss:module:1.1" name="org.apache.logging.log4j2">
<resources>
<resource-root path="log4j-api-2.11.1.jar"/>
<resource-root path="log4j-to-slf4j-2.11.1.jar"/>
</resources>
<dependencies>
<module name="org.slf4j" />
</dependencies>
</module>
(Basically make sure this xml is in your module path, typically you would add it at $JBOSS_MODULEPATH/org/apache/logging/log4j2/main/module.xml, and add the referenced jar-files in the same directly as well)
Next step is to add a dependency to this module from my application. This is accomplished using a jboss-deployment-structure.xml. If you are not familiar with this file please look it up. Add a line like this
<module name="org.apache.logging.log4j2" export="true" />
You might also need to exclude log4j-api-2.11.1.jar from your application deployment, I am not 100% sure it is needed but I always do when I create a module.
After this you should be able to see log4j2 messages in your server.log
I hope this can help someone out there!

I want to offer to have a look at the problem from another side.
You can in your code, use log4j2 interfaces, as a logging bridge. For instance you can use MDC, Suppliers, ClosableThreadContext. The features which are not availble in slf4j/logback at the moment:
import org.apache.logging.log4j.CloseableThreadContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
private static final Logger logger = LogManager.getLogger(SomeClass.class.getName());
public void doLog() {
try (final CloseableThreadContext.Instance ctc =
CloseableThreadContext.put("user", UUID.randomUUID().toString())) {
String note = "(originally, log4j2 war)";
logger.info(() -> "This is an info message, via supplier, " + note); // == INFO
logger.error("This is an error message, {}", note); // == ERROR
logger.warn("This is a warning message, {}", note); // == WARNING
logger.debug("Here is a debug message, {}", note); // == DEBUG
logger.info(logger.getClass().getName());
}
}
But you add a dependency to delegate all log4j2 calls to slf4j:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.14.0</version>
</dependency>
You do not need any other hacks. It works fine (checked on Wildfly 10).
The main advantages:
you have modern API for logging and some great features. Slf4j is going to support those features, but they are not yet included into the last final version.
which is more important, when you work with WildFly, you can adopt logging configuration via WildFly at runtime with CLI. It is very important possibility for production. Delivering a config file, like Log4j2.xml is a bad alternative. You need literally to change the content of this file. Most oftern, it means to rebuild the project, cause the logging config file is usually part of the resources. And it also means you need to redeploy the application.
With WildFly CLI I can temporary enable DEBUG mode for a certain package.

There is no module org.apache.logging.log4j. The module name you should be using is org.apache.log4j.
I'm not sure why you don't want to use CLI, but you could also set the add-logging-api-dependencies to false.
/subsystem=logging:write-attribute(name=add-logging-api-dependencies, value=false)

Related

Spring Boot: Enable logging in file in production environment only [duplicate]

I am implementing logging in a Spring Boot project with logback library. I want to load different logging configuration files according to my Spring profiles (property spring.pofiles.active). I have 3 files:
logback-dev.xml
logback-inte.xml
logback-prod.xml
I am using Spring Boot version 1.2.2.RELEASE.
As you can read in Spring Boot documentation:
The various logging systems can be activated by including the appropriate libraries on the classpath, and further customized by providing a suitable configuration file in the root of the classpath, or in a location specified by the Spring Environment property logging.config. (Note however that since logging is initialized before the ApplicationContext is created, it isn’t possible to control logging from #PropertySources in Spring #Configuration files. System properties and the conventional Spring Boot external configuration files work just fine.)
So I tried to set logging.config property in my application.properties file:
logging.config=classpath:/logback-${spring.profiles.active}.xml
But when i start my application, my logback-{profile}.xml is not loaded.
I think logging is a common problem that all projects using Spring Boot have encountered. Am I on the right track with the above approach?
I have other solutions that work, but I find them not as elegant (conditional parsing with Janino in logback.xml file or command line property).
I found a solution and I understood why Spring doesn't use my logging.config property defined in the application.properties file.
Solution and explanation
When initializing logging, Spring Boot only looks in classpath or environment variables.
The solution I used was to include a parent logback.xml file that included the right logging config file according to the Spring profile.
logback.xml
<configuration>
<include resource="logback-${spring.profiles.active}.xml"/>
</configuration>
logback-[profile].xml (in this case, logback-dev.xml) :
<included>
<!-- put your appenders -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{ISO8601} %p %t %c{0}.%M - %m%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- put your loggers here -->
<logger name="org.springframework.web" additivity="false" level="INFO">
<appender-ref ref="CONSOLE" />
</logger>
<!-- put your root here -->
<root level="warn">
<appender-ref ref="CONSOLE" />
</root>
</included>
Note
spring.profiles.active has to be set in command line arguments when starting the app.
Example for JVM properties: -Dspring.profiles.active=dev
Reference documentation
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
http://docs.spring.io/spring-boot/docs/0.5.0.M3/api/org/springframework/boot/context/initializer/LoggingApplicationContextInitializer.html
Edit (multiple active profiles)
In order to avoid multiple files, we could use conditional processing which requires Janino dependency (setup here), see conditional documentation.
With this method, we can also check for multiple active profiles at the same time. E.g (I did not test this solution, so please comment if it does not work):
<configuration>
<if condition='"${spring.profiles.active}".contains("profile1")'>
<then>
<!-- do whatever you want for profile1 -->
</then>
</if>
<if condition='"${spring.profiles.active}".contains("profile2")'>
<then>
<!-- do whatever you want for profile2 -->
</then>
</if>
<!-- common config -->
</configuration>
See #javasenior answer for another example of a conditional processing.
Another approach that could handle multiple profiles is to create a separate properties file for each environment.
application-prod.properties
logging.config=classpath:logback-prod.xml
application-dev.properties
logging.config=classpath:logback-dev.xml
application-local.properties
logging.config=classpath:logback-local.xml
BE AWARE
If you aren't careful you could end up logging somewhere unexpected
-Dspring.profiles.active=local,dev //will use logback-dev.xml
-Dspring.profiles.active=dev,local //will use logback-local.xml
Instead of adding separate logback xmls for each profile or having the IF condition , I would suggest the following (If you have less difference in the xmls') for easy conditional processing
Documentation link here:
<springProfile name="dev">
<logger name="org.sample" level="DEBUG" />
</springProfile>
<springProfile name="prod">
<logger name="org.sample" level="TRACE" />
</springProfile>
Conditional processing with logback will be a solution without many logback files. Here is a link and a sample logback configuration with spring profiles.
<configuration>
<property name="LOG_LEVEL" value="INFO"/>
<if condition='"product".equals("${spring.profiles.active}")'>
<then>
<property name="LOG_LEVEL" value="INFO"/>
</then>
<else>
<property name="LOG_LEVEL" value="ERROR"/>
</else>
</if>
.
.
appender, logger tags etc.
.
.
<root level="${LOG_LEVEL}">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Also, you might have to add this to your pom.xml
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.6</version>
</dependency>
Spring has support of next tag <springProperty/> inside Logback XML file, this tag described here . It means that you can easily add variable from Spring property file, even this variable value resolves from environment/system variable by Spring.
You can specific different logback.xml for different profile, only 3 steps:
1, Specify actived profile in application.properties or application.yml:
spring.profiles.active: test
2, Config logback to include different configuration by profile:
<!DOCTYPE configuration>
<configuration scan="true" scanPeriod="30 seconds">
<springProperty scope="context" name="profile" source="spring.profiles.active"/>
<include resource="logback.${profile}.xml"/>
</configuration>
3, Create configuration file logback.test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<included>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<root level="INFO"/>
</included>
It's very simple, don't need do anything else.

ERROR StatusLogger No log4j2 configuration file found. While updating the version 2.5.12 of Struts

As per the requirement and for security purpose I am updating Struts project. Before the Struts version is 2.3.24 and now I am updating it to 2.5.12. I have downloaded all the required jar files of Struts and applied to project but I am getting the below error
ERROR StatusLogger No log4j2 configuration file found. Using default
configuration: logging only errors to the console. Set system property
'org.apache.logging.log4j.simplelog.StatusLogger.level' to TRACE to
show Log4j2 internal initialization logging.
But I am not using any logger in my project. I have added all the dependency jar files and I am not using Maven, but added related libraries in lib folder. Any suggestions please.
Struts framework is using a logging framework log4j second version.
Struts 2.3 to 2.5 migration
Please be aware that the framework is using Log4j2 now as a main logging layer, the existing old logging layer is deprecated and will be removed soon. Log4j2 supports many different logging implementations, please check documentations for more details.
The file log4j2.xml is required to bootstrap the logging framework. But it's missing from the classpath. It's also missing from the Struts framework.
You should find some log4j2.xml, i.e. from the struts-showcase application or read a step 4 in this tutorial How To Create A Struts 2 Web Application
Step 4 - Add Logging
To see what’s happening under the hood, the example application for this tutorial uses log4j2. You’ll need to add a dependency node for log4j2 to the pom:
pom.xml log4j dependency node
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
Using both log4j-core and log4j-api allows to use the latest version of Log4j2 without a clash with version provided by the framework. Setup a log4j2.xml configuration in the src/main/resources folder which contains the following
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.opensymphony.xwork2" level="debug"/>
<Logger name="org.apache.struts2" level="debug"/>
<Root level="warn">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
Note the above log4j2 configuration specifies the console as the log target.
No log4j2 configuration file found means log4j2.xml configuration file is not in your classpath.
Check your project jar contains log4j confuguration file or not.
Otherwise you can set log4j confuguration file path as system property in your build script.
<sysproperty key="log4j.configurationFile" value="file:///${basedir}/src/log4j2.xml" />
Check https://logging.apache.org/log4j/2.x/manual/configuration.html for log4j configuration

Components written against log4j1 are not logging after log4j2 upgrade

I've been banging my head over this one for a few days and can't get it figured out. Log4j2 is backwards compatible if you add the log4j1 compatibility library.
My web-inf\lib has:
slf-api
log4j-1.2-api (backwards compat. library)
log4j-api (log4j2)
log4j-core (log4j2)
log4j-web (auto-wiring for web applications)
My web.xml has:
<!-- log4j2 auto-wiring -->
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///${catalina.base}/conf/log4j2.xml</param-value>
</context-param>
My [tomcat]/conf/log4j2.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<!-- Appends to CONSOLE -->
<Console name="consoleAppender" target="SYSTEM_OUT">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />
<PatternLayout pattern="%5p (%F:%L) - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.mycompany.componentA" level="WARN" />
<Logger name="com.mycompany.componentA.QueryLogger" level="DEBUG" />
<Logger name="com.mycompany.mycode" level="DEBUG" />
<Root level="WARN">
<AppenderRef ref="consoleAppender" />
</Root>
</Loggers>
</Configuration>
I have upgraded code under my control (com.mycompany.mycode) to log4j2 APIs and they work/log flawlessly. Code that is not under my control but was written against log4j1 (com.mycompany.componentA) just simply fails to log at all. No errors, no debugs, nothing.
Something interesting though... when I start the application I get a log4j1 warning about incorrect configurations when the application starts. This also stumps me because there are no log4j1 libraries (except the compatibility API) in the WAR. Warning is:
log4j:WARN No appenders could be found for logger (com.mycompany.componentB)
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
EDIT: I (finally) figured out what's going on. One of my dependencies did a horribly bad thing and BUNDLED the log4j1 classes into it's final jar. So there are no log4j1 jars on the classpath, but there are log4j1 CLASSES on the classpath.
The only way I was able to get this working was to:
Create BOTH a log4j1 and log4j2 XML configuration files (even though the log4j2 configuration contained all the loggers I wanted)
Let Log4j2 auto-wire itself via the 'log4j-web' artifact + 'log4jConfiguration' web.xml parameter
Manually wire log4j1 by calling the deprecated Log4jConfigurer.initLogging(...) API on server startup
This is probably horribly incorrect, but as indicated above, it was the only way I got it working after weeks of fooling around.
My understanding of the lo4j1 bridge is that wiring up log4j2 and including the bridge is all that should be required (e.g. no need to manually wire log4j1). In practice, that does not seem to be occurring.
That error message means you still have the log4j-1.x jar in your application. Look for it in your WEB-INF/lib and remove it and then it should work.
If not in WEB-INF/lib, then perhaps in your web container (Tomcat?) shared lib folder? Ralph is right that this error message is generated by Log4j-1.2, so it is on the classpath somewhere... Try printing the value of System property java.class.path if necessary.
Update: another way to find the location of the Log4j1 jar is by printing the value of org.apache.log4j.AppenderSkeleton.class.getResource("/org/apache/log4j/AppenderSkeleton.class") from your application.
(I originally suggested Category but this also exists in the Log4j 1 bridge, so AppenderSkeleton is better.)

Log4j2.xml configuration file location for EAR

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.

Write simple logs using log4j 2

I've looked everywhere but couldn't find any guides (that made sense to me) on how to use log4j 2. As a background, I'm extremely new to log4j or any type of logging, and the closest to logging I've ever gotten was System.out.println() or PrintWriter in Java (if that's even considered logging).
I went to Apache Log4j 2 page to download the jar files, but there are 36 jar files and I have no clue which one to use.
Can anyone get me started on how to append simple String messages to a log file from my server code (in Java)? For instance, when a user connects to my server, I have a simple
System.out.println("user A connected to server at " + time);
code, which serves me no good during real usage. I'd like to replace all my System.out statements to logging using Log4j, so that I can read them later and detect any bugs/crashes in my server code.
Thanks in advance!
Is this a webapp? In other words, does it have a WEB-INF folder? If so, create a simple log4j.properties file that contains something like:
# Define the root logger with appender file
log4j.rootLogger = DEBUG, FILE
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=log.out
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n
Make sure on this line:
log4j.appender.FILE.File=log.out
that you have a file actually created for it. I used log.out as an example.
Place this in your WEB-INF folder.
If it's a Maven project, find a place in your project for the file and add it manually by right clicking Run->Run Configuration -> [classpath tab] -> click on user Entries -> Advanced -> Select Add Folder -> and adding the directory where you put the file.
In your class, import:
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.FileAppender;
Then instantiate your logger object:
static Logger log = Logger.getLogger(LdapPurge.class.getName());
Try that and see if it works.
I've been working with Log4j version 2.x and recently wrote a post about its use. You can review it, maybe it will help you:
To use Log4j 2.x 2 libraries are required:
<dependency>
<groupId> org.apache.logging.log4j </groupId>
<artifactId> log4j-core </artifactId>
<version> 2.8.2 </version>
</dependency>
<dependency>
<groupId> org.apache.logging.log4j </groupId>
<artifactId> log4j-api </artifactId>
<version> 2.8.2 </version>
</dependency>
Create the log42.xml file in the resources folder:
<?xml version="1.0" encoding="UTF-8"?>
<!--https://logging.apache.org/log4j/2.x/manual/configuration.html-->
<Configuration status="TRACE" monitorInterval="30">
<!-- The properties that are needed in the configuration of the appenders are defined | property definition -->
<Properties>
<!--The pattern is defined. For writing in logs -->
<Property name="LOG_PATTERN">%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ} [%t] %-5level %logger{36} - %msg%n</Property>
<!--Storage location is defined -->
<Property name="APP_LOG_ROOT">var/log/tomcat0</Property>
</Properties>
<Appenders>
<!-- Configuration for writing events to console (cmd, ide, terminal)-->
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}" />
</Console>
<!--
Configuration for writing debug events.
for more information about properties: https://logging.apache.org/log4j/2.x/manual/appenders.html
-->
<RollingFile name="debugLog"
fileName="${APP_LOG_ROOT}/logs/automatizador-debug.log"
filePattern="${APP_LOG_ROOT}/logs/$${date:yyyy-MM}/automatizador-debug-%d{yyyy-MM-dd}-%i.log.gz">
<LevelRangeFilter minLevel="DEBUG" maxLevel="DEBUG" onMatch="ACCEPT"
onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="19500KB" />
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<!--Define the logger-->
<Loggers>
<!--only log events from type "debug" for the package: com.advanced.development -->
<Logger name="com.advanced.development" additivity="false"
level="trace">
<AppenderRef ref="debugLog" />
<AppenderRef ref="Console" />
</Logger>
<Root level="error">
<AppenderRef ref="debugLog"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
For more details: https://su9.co/9BaE74E

Categories

Resources