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
Related
java 1.8
maven 3.5
In pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
In my Maven java project I want to generate new log file every new day (midnight).
So I use RollingFile and cron 0 0 0 * * ?. Here my log4j2.xml
<Properties>
<Property name="baseDir">logs</Property>
<Property name="patterLayout">%d{[dd.MM.yyyy HH:mm:ss.SSS]} %l %p:%n %m%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${patterLayout}"/>-
</Console>
<RollingFile name="RollingFile" fileName="${baseDir}/app.log"
filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="${patterLayout}"/>-
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}" maxDepth="2">
<IfFileName glob="*/app-*.log.gz"/>
<IfLastModified age="60d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
But all logs print in ONE file app.log.
Here result:
[27.11.2021 23:59:05.235] com.myproject.xls2metro2.App.main(App.java:18) TRACE:
JDK: 1.8.0_202
[27.11.2021 23:59:05.238] com.myproject.xls2metro2.App.main(App.java:33) WARN:
File path is mandatory
[28.11.2021 00:01:13.347] com.myproject.xls2metro2.App.main(App.java:18) TRACE:
JDK: 1.8.0_202
[28.11.2021 00:01:13.351] com.myproject.xls2metro2.App.main(App.java:33) WARN:
File path is mandatory
At first, verify that your original configuration doesn't have this hyphen character (probably you have added it accidentally while writing a question)
<PatternLayout pattern="${patterLayout}"/>-
Also, make sure that your code is wrapped inside the Configuration tag (I assume that you have omitted it for the sake of brevity):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
... your code here
</Configuration>
At second, your config looks exactly the same as in the official documentation examples, so it should be fine.
But in the documentation stated that:
The CronTriggeringPolicy triggers rollover based on a cron expression.
This policy is controlled by a timer and is asynchronous to processing
log events, so it is possible that log events from the previous or
next time period may appear at the beginning or end of the log file.
The filePattern attribute of the Appender should contain a timestamp
otherwise the target file will be overwritten on each rollover.
So probably, this is your case. Just wait a little longer to verify, that the next logs will be written to a separate file.
In my Maven project, Log4j2 latest dependencies state version 2.11.2. However; 1.2.12 is being imported instead. The only logging dependencies stated in the POM.XML file are as follow:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
In the repository folder located within the .m2 folder, there exists a 'log4j' folder that has a folder with the title '1.2.12'. Inside the 1.2.12 folder the following items exist:
_remote.repositories
log4j-1.2.12
log4j-1.2.12.jar.sha1
log4j-1.2.12.pom
log4j-1.2.12.pom.sha1
My log4j2.xml configuration file is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Configuration status="WARN">
<Properties>
<Property name="basePath">./logs</Property>
</Properties>
<Appenders>
<RollingFile name="File" filePattern="${basePath}/prints-%d{yyyy-MM-dd}.log" fileName="${basePath}/prints.log">
<PatternLayout pattern="%d{ yyyy-MMMM-dd: hh:mm a :ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<SizeBasedTriggeringPolicy size="500"/>
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{ yyyy-MMMM-dd: hh:mm a :ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
Log4j2.xml file is located under a package named resources which is situated under a source folder named src/main/java of the Maven project. I also get an occasional message (1 out of 5 times) stating that log4j2 configuration file can not be found. I have tried cleaning the project in addition to deleting the jars and re-including the dependencies but nothing seems to work.
log4j2:WARN No appenders could be found for logger (....) comes when application is not able to locate log4j2.xml/properties file.
/src/main/resources is the standard placement for this.
You mentioned yours is under src/main/java, please keep it under /src/main/resources. If log4j2.properties/xml file is not found under /src/main/resources then use -
PropertyConfigurator.configure("log4j2.properties/xml");
I use log4j 2.x in our maven java war application running on jetty9.
All I need is follow structure:
Single point of code (function) lo log message.
Log function calls org.apache.logging.log4j.core.Logger.[info, error ...] function.
log4j facility writes to main jetty9 log AND to log reside in appropriate folder defined on run time.
I have follow log4j2.xml config:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%-5L - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
I use follow dependency in maven pom:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
And follow imports:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger;
And I try to make brainstorming voodoo with huge amount of log4j classes:
//Configuration c = new AbstractConfiguration
//PatternLayout layout = new PatternLayout();
//FileAppender appender = new FileAppender("printlog", Layout.);
//logger.addAppender(null);
//OHH MY GOD!!!!
I searched a lot in documentation such as https://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender but I don't find anything close to solve the problem.
All I found is manual for hardcode path to file appender in the configuration.
How to do it programmatically???
I need programmatically defined FileAppender inherits the PatternLayout from ConsoleAppender defined in xml config, because code reuse and single point of control issues.
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.
I am using Log4j 2 and I am unsuccessfully trying to change the logging level of jBPM/Drools, having it as a reference. The drools class that keeps logging is ExtensibleXmlParser.
<?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="debug">
<AppenderRef ref="Console" />
</Root>
<Logger name="org.drools.core.xml.ExtensibleXmlParser" level="off">
<AppenderRef ref="Console" />
</Logger>
</Loggers>
</Configuration>
If I get it right, ExtensibleXmlParser uses slf4j and Log4j is compatible with sl4j.
Why doesn't this Log4j configuration work? Could someone provide me a working configuration? Should I configure jBPM/Drools logger indendently?
When log4j seems to ignore your tweaks to the log4j.properties/xml file, it most often means you're not fiddling with the right file. It is likely that there is another configuration file in your classpath that gets found earlier and is taken into account.
Search your entire classpath for log4j* pattern and see what comes out (include the contents of .jar files and application server /lib and /ext folders, if any).
If I get it right, ExtensibleXmlParser uses slf4j and Log4j is compatible with sl4j.
"Is compatible" is not equivalent with "is configured to use". SLF4J plugs into appropriate logging framework through the org.slf4j.impl.StaticLoggerBinder class. Search the classpath (best in your IDE) to see what library this class came with. If there is no such class, then SLF4J logs nothing.