How to Change log4j Configuration When Packaging - java

I have a fairly simple Java application that is being distributed out to users as an executable JAR file. In order to track usage and assist in diagnostics, I want to add logging capability to the application but, from one execution to the next, I can never be sure where the users are going to be running this application.
In order to make this work, I have configured my application to use a log4j socket appender - no matter where the user is running this application, messages are sent to the socket and properly logged, which is perfect.
What I'm running into now, though, it that I would prefer to use different log4j configurations when I am running locally vs. when I deploy this application into production. When running locally (from my IDE, IntelliJ), I would prefer to use a console appender for a couple reasons:
It's trivial to see what is happening.
Should I be developing without an Internet connection, I don't want to hang up on not being able to connect.
I don't want to clutter the production logs with what I am doing during development.
When I package the application and distribute it, however, I would like it to use the socket appender, rather than the console appender.
Is there any easy way to accomplish what I want? I am using Maven to build my application, but I am not horribly skilled with it.

Here's a simpler approach to your problem...
Put two log4j.properties files under src/main/resources directory, like this:-
src/main/resources
|- log4j.properties
|- log4j_dev.properties
log4j.properties contains the production configuration, and by default, Log4J will automatically pick this file up because you are using the standard file name.
log4j_dev.properties contains the development configuration. To ensure IntelliJ picks this up during development, you will overwrite the log configuration using -Dlog4j.configuration=<configuration-file> VM option. I attached a screenshot on how you might configure this using IntelliJ:-

This turned out to be simpler than I originally expected - and Vikdor's comment led me to the right answer. I had started digging into having multiple profiles (one for dev and one for prod) but later realized I didn't really need to have two. When working locally, I wasn't really going through the Maven build process - I was just executing the Java classes. The only time I went through the Maven build process was when I wanted to package my application for deployment. As such, I simply added a section to my POM file that uses the maven-antrun-plugin. My final code ended up looking like this:
File: log4j.properties:
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
File: log4j_production.properties
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A2
log4j.appender.A2=org.apache.log4j.net.SocketAppender
log4j.appender.A2.remoteHost=my.server.com
log4j.appender.A2.port=6000
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
File: POM.xml
...
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete file="${project.build.outputDirectory}/log4j.properties"/>
<copy file="src/main/resources/log4j_production.properties"
toFile="${project.build.outputDirectory}/log4j.properties"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
...
That seemed to do the trick. When I run locally, I load log4j.properties, which gives me a console appender. When I package for a production distribution, Maven will replace the default log4j.properties file with the alternate one, which uses a socket appender.
Thanks!

I will strongly recommend making it determined in run-time instead of build-time.
For example, when you are running your app, have config/ directory put in beginning of classpath, and put your log4j.xml there. Of course, you may still keep a default log4.xml in your application JAR, so that if you don't provide it in deployment, your app can still run.

Related

log4j2 - set file path from properties issue

I just converted from log4j to log4j2, using an xml config file. Everything is working except that I can't seem to set the path of my log files using a properties file.
This is a Spring MVC app and I have a filedirs.properties file located in the src/main/resources folder along with the log4j2.xml, i18n message and other properties files. It has a simple entry: logs=G:/web/logs/.` I've looked through other posts and am just not getting how to configure log4j2 correctly. Here's what I've have:
<Configuration>
<Properties>
<Property name="filename">${bundle:net.myapp.filedirs:logs}standard.log</Property>
</Properties>
<File name="stdLog" fileName="${filename}" ignoreExceptions="false">
<PatternLayout pattern="%d{DEFAULT} %-5p: %c - %m%n"/>
</File>
...rest of config...
The error is this:
ERROR FileManager (${bundle:net.myapp.filedir:logs}standard.log) java.io.FileNotFoundException:
Substituting the actual path works, e.g.,
<Property name="filename">g:/web/logs/standard.log</Property>
I'm hung up on the correct domain portion of the bundle syntax - myapp.net is not the actual website, but it's similar enough. I've tried a couple dozen variations but in debug mode java.util.ResourceBundle never finds the filedirs properties file when it goes through the log4j2 initialization. The manual sample is com.domain.messages so I'm stumped why net.myapp.filedirs doesn't work.
As I indicated in my comment, it turns out that it does work but the manual may be incorrect. Instead of com.domain.messages as described here, Property Substitution, what worked was simply messages, e.g., <Property name="filename">${bundle:filedir:logs}standard.log</Property>. Adding status=debug to <Configuration> finally helped me figure this out.
I don't know if this makes any difference, but I'm testing through STS (localhost) on my PC - is it possible the documentation may be correct for a production website? No idea since I don't have a production deployment yet but it's something I'll check out when I get it up and running.

Filter JUnit Output to Only show exceptions that you don't expect? [duplicate]

Looking at the last JUnit test case I wrote, I called log4j's BasicConfigurator.configure() method inside the class constructor. That worked fine for running just that single class from Eclipse's "run as JUnit test case" command. But I realize it's incorrect: I'm pretty sure our main test suite runs all of these classes from one process, and therefore log4j configuration should be happening higher up somewhere.
But I still need to run a test case by itself some times, in which case I want log4j configured. Where should I put the configuration call so that it gets run when the test case runs standalone, but not when the test case is run as part of a larger suite?
I generally just put a log4j.xml file into src/test/resources and let log4j find it by itself: no code required, the default log4j initialisation will pick it up. (I typically want to set my own loggers to 'DEBUG' anyway)
The LogManager class determines which log4j config to use in a static block which runs when the class is loaded. There are three options intended for end-users:
If you specify log4j.defaultInitOverride to false, it will not configure log4j at all.
Specify the path to the configuration file manually yourself and override the classpath search. You can specify the location of the configuration file directly by using the following argument to java:
-Dlog4j.configuration=<path to properties file>
in your test runner configuration.
Allow log4j to scan the classpath for a log4j config file during your test. (the default)
See also the online documentation.
You may want to look into to Simple Logging Facade for Java (SLF4J). It is a facade that wraps around Log4j that doesn't require an initial setup call like Log4j. It is also fairly easy to switch out Log4j for Slf4j as the API differences are minimal.
I use system properties in log4j.xml:
...
<param name="File" value="${catalina.home}/logs/root.log"/>
...
and start tests with:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<systemProperties>
<property>
<name>catalina.home</name>
<value>${project.build.directory}</value>
</property>
</systemProperties>
</configuration>
</plugin>

Weblogic Log4j Loggging Server Logging Bridge throws ClassCastException when starting up

With Weblogic 11g I have done the following:
1 Created log4j.xml file where I created a new appender:
<appender name="WEBLOGIC" class="weblogic.logging.log4j.ServerLoggingAppender">
<param name="Threshold" value="ERROR"/>
</appender>
<root>
<priority value="WARN"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="WEBLOGIC"/>
</root>
2 Updated the ${DOMAIN_HOME}/bin/setDomainEnv.sh script with these changes:
LOG4J_CONFIG_FILE="${DOMAIN_HOME}/config/log4j.xml"
if [ "${LOG4J_CONFIG_FILE}" != "" ] ; then
JAVA_PROPERTIES="${JAVA_PROPERTIES} Dlog4j.configuration=file:${LOG4J_CONFIG_FILE}"
export JAVA_PROPERTIES
fi
JAVA_OPTIONS="${JAVA_OPTIONS} ${JAVA_PROPERTIES} -Dweblogic.log.Log4jLoggingEnabled=true -Dwlw.iterativeDev=${iterativeDevFlag} -Dwlw.testConsole=${testConsoleFlag} -Dwlw.logErrorsToConsole=${logErrorsToConsoleFlag}"
3 Copied the log4j jars to the domain/lib
cp ./wlserver_10.3/server/lib/wllog4j.jar user_projects/domains/my_domain/lib/
cp ./wlserver_10.3/server/lib/consoleapp/APP-INF/lib/log4j-1.2.8.jar user_projects/domains/my_domain/lib/
4 Starts the AdminServer, but I get this error:
java.lang.ClassCastException:
weblogic.logging.log4j.ServerLoggingAppender cannot be cast to
org.apache.log4j.Appender
Keep step 1 and remove changes done in other steps.
Now copy the log4j.xml to $DOMAIN_HOME/lib folder. This will keep your log4j.xml in the server's classpath and the server will use this log4j.xml as its log4j configuration. No additional changes are required.
In setDomainEnv.xml file, please add the set log4j.xml location as below:
set LOG4J_CONFIG_FILE=C:\bea\user_projects\domains\dev\lib\log4j.xml
if NOT "%LOG4J_CONFIG_FILE%"=="" (
set JAVA_PROPERTIES=%JAVA_PROPERTIES% -Dlog4j.configuration=file:%LOG4J_CONFIG_FILE%
)
What you have to see is if despite the warning that you get, if the ServerLogging is effectively not working on your appliction on your domain.
Probably not even there since you are only copying the log4j to the domain/lib folder but not the wllog4j.jar.
So your setup looks like is doomed not to work in any case.
To me, It looks to me that you are undergoing Class Loader Vodoo Messup.
(1) You set a global log4j properties file for the entire app server.
(2) it looks like weblogic console app is itself a ear and it bundles its own LOG4J implementation library, which you are copying into your domain.
When the console app runs, it must for sure make use of Log4j and the class loader loading the Log4j Appender definition is most likely a level lower than the class loader that knows about the ServerLoggin bridge adapter.
I am beting its for reason like this that weblogic is geting rid of LOG4j in future gnerations of the product.
They have too many class loader issues - JUL logging you have the APP class loader behind the core classes - such as Handlers/Adapters.
Anyway.
(3) When weblogic runs, namley when it bootstraps the console it probably runs some sort class loader that gives a level of isolation to the libs bundled in the applicaiton and it sees:
Oh! How nice, LOG4j is here, leets initialize it.
Second, LOG4j bootstraps and hits head on your log4j.properties where you put the server logging appender in there - cross cutingly for everybody (including the weblogic application console).
He goes hunting for this library and where does it find it?
One of them, the wllog4j.jar he finds somewhere in the weblogic generic container libraries. While the base core classes of Log4j he finds a level lower in the domain configuration or in the EAR configuraiton of the console applicaiton.
This is not good.
Try the following:
(a) go into the weblogic console app, go to the Meta Inf folder and re-write the weblogi-application.xml
It will have a prefer applicaiton packages that looks like this:
org.apache.log4j.*</package-name--> <---- here I've commented this line.
If you comment the above line, the application class loader will search for log4j libraries in the highest parent that knows about these classes.
So if you put at the same level where your ServerLogger is found you should be fine.
(b) Pug the log4j implementation library at the same level where the wllog4j.jar will be found.
Check if you still get the casting exceptions.
Be very careful when you make server wide cross cuting configurations.
Good luck.

No appenders could be found for logger(log4j)?

I have put log4j to my buildpath, but I get the following message when I run my application:
log4j:WARN No appenders could be found for logger (dao.hsqlmanager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
What do these warnings mean? Whats the appender here?
This Short introduction to log4j guide is a little bit old but still valid.
That guide will give you some information about how to use loggers and appenders.
Just to get you going you have two simple approaches you can take.
First one is to just add this line to your main method:
BasicConfigurator.configure();
Second approach is to add this standard log4j.properties (taken from the above mentioned guide) file to your classpath:
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
It looks like you need to add the location of your log4j.properties file to the Classpath in Eclipse.
Make sure your project is open in Eclipse, then click on the "Run" menu at the top of Eclipse and click on the following:
Run
Run Configurations
Classpath (tab)
User Entries
Advanced (button on the right)
Add Folders
then navigate to the folder that contains your log4j.properties file
Apply
Run
The error message should no longer appear.
Quick solution:
add code to main function:
String log4jConfPath = "/path/to/log4j.properties";
PropertyConfigurator.configure(log4jConfPath);
create a file named log4j.properties at /path/to
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
This is just a warning.
Fixing
This occurs when the default configuration files log4j.properties and log4j.xml can not be found and the application performs no explicit configuration.
To fix that, simply create/copy log4j.properties or log4j.xml into your a location on the classpath (usually the same as the jar files).
Optionally set java option: -Dlog4j.configuration=file:///path/to/log4j.properties.
log4j uses Thread.getContextClassLoader().getResource() to locate the default configuration files and does not directly check the file system. Knowing the appropriate location to place log4j.properties or log4j.xml requires understanding the search strategy of the class loader in use. log4j does not provide a default configuration since output to the console or to the file system may be prohibited in some environments.
Debugging
For debugging, you may try to use -Dlog4j.debug=true parameter.
Configuration of log4j.properties
Sample configuration of log4j.properties:
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.foo=WARN
Here is another configuration file that uses multiple appenders:
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
Apache Solr
If using Solr, copy <solr>/example/resources/log4j.properties into a location on the classpath.
Sample configuration of log4j.properties from Solr goes like:
# Logging level
solr.log=logs/
log4j.rootLogger=INFO, file, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x \u2013 %m%n
#- size rotation with log cleanup.
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.MaxFileSize=4MB
log4j.appender.file.MaxBackupIndex=9
#- File to log to and log format
log4j.appender.file.File=${solr.log}/solr.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS}; %C; %m\n
log4j.logger.org.apache.zookeeper=WARN
log4j.logger.org.apache.hadoop=WARN
# set to INFO to enable infostream log messages
log4j.logger.org.apache.solr.update.LoggingInfoStream=OFF
See also:
Short introduction to log4j: Default Initialization Procedure
Why can't log4j find my properties in a J2EE or WAR application?
Most of the answers here suggested that log4j.properties file be placed in the right location(for maven project, it should be located in src/main/resources)
But for me, the problem is that my log4j.properties is not correctly configured. Here's a sample that works for me, you can try it out first.
# Root logger option
log4j.rootLogger=INFO, stdout
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
As explained earlier there are 2 approaches
First one is to just add this line to your main method:
BasicConfigurator.configure();
Second approach is to add this standard log4j.properties file to your classpath:
While taking second approach you need to make sure you initialize the file properly,
Eg.
Properties props = new Properties();
props.load(new FileInputStream("log4j property file path"));
props.setProperty("log4j.appender.File.File", "Folder where you want to store log files/" + "File Name");
Make sure you create required folder to store log files.
You use the Logger in your code to log a message. The Appender is a Object appended to a Logger to write the message to a specific target. There are FileAppender to write to text-files or the ConsoleAppender to write to the Console. You need to show your code of the Logger and Appender setup for more help.
please read the tutorial for a better understanding of the interaction of Logger and Appender.
Make sure the properties file has properly set.
And again, it seems like that the compiler cannot find the properties file, you can set as follow at the pom (only when you use maven project).
<build>
<sourceDirectory> src/main/java</sourceDirectory>
<testSourceDirectory> src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>resources</directory>
</resource>
</resources>
</build >
I get the same error. Here the problem which leads to this error message:
I create some objects which use the Logger before I configure the log4j:
Logger.getLogger(Lang.class.getName()).debug("Loading language: " + filename);
Solution:
Configure the log4j at the beginning in the main method:
PropertyConfigurator.configure(xmlLog4JConfigFile);
// or BasicConfigurator.configure(); if you dont have a config file
Add the following as the first code:
Properties prop = new Properties();
prop.setProperty("log4j.rootLogger", "WARN");
PropertyConfigurator.configure(prop);
I faced the same issue when I tried to run the JUnit test class.
The issue is resolved after I manually added the log4j.properties file in the src/test/resources folder.
Adding the below code to the log4j.properties file solved the issue:
# Root logger option
log4j.rootLogger=INFO, file, stdout
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\\logging.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
I think you should understand where the log4j jar file or the Java code looks for the log4j configuration files.
src/main/resources/log4j.properties is Eclipse path.
Place them in a proper location so that you don't have to hard code the absolute path in code.
Read my article and sample solution for that
https://askyourquestions.info/how-to-see-where-the-log-is-logger-in-slf4j/
First of all: Create a log4j.properties file
# Root logger option
log4j.rootLogger=INFO, stdout
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
Place it in src/main/resources/
After that, use this 2 dependencies:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
It is necessary to add this final dependency to POM file:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
In my case, the error was the flag "additivity". If it's "false" for you root project package, then the child packages will not have an appender and you will see the "appender not found" error.
Another reason this may happen (in RCP4) is that you are using multiple logging frameworks in your target file. As an example, this will occur if you use a combination of slf4j, log4j and ch.qos.logback.slf4j in your target files content tab.
If you are using Eclipse and this problem appeared out of nowhere after everything worked fine beforehand, try going to Project - Clean - Clean.
I ran into this issue when trying to build an executable jar with maven in intellij 12. It turned out that because the java manifest file didn't include a class path the log4j properties file couldn't be found at the root level (where the jar file was executed from.)
FYI I was getting the logger like this:
Logger log = LogManager.getLogger(MyClassIWantedToLogFrom.class);
And I was able to get it to work with a pom file that included this:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mycompany.mainPackage.mainClass</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path> <!-- need to add current directory to classpath properties files can be found -->
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Make sure your project is open in Eclipse, then click on the "Run" menu at the top of Eclipse and click on the following:
Run
Run Configurations
Classpath (tab)
User Entries
add jar on the right
add log4j jar file
Apply
Run
The error message should no longer appear.
The reason can be lack of the word static in some:
final static Logger logging = Logger.getLogger(ProcessorTest.class);
If I make logger the instance field, I am getting exactly this very warning:
No appenders could be found for logger (org.apache.kafka.producer.Sender)
What is worse, the warning points not to ProcessorTest, where the mistake lives, but to an absolutely different class (Sender) as a source of problems. That class has correct set logger and need not any changes! We could look for the problem for ages!
I faced the same problem when I use log4j2. My problem is caused by using wrong dependent library:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>runtime</scope>
</dependency>
Instead, I should use:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>runtime</scope>
</dependency>
In my case, I have a log4j2.xml defined in my "resources" directory, and specified to use it by:
System.setProperty("log4j.configurationFile", "log4j2.xml");
Log4J display this warning message when Log4j Java code is searching to create a first log line in your program.
At this moment, Log4j make 2 things
it search to find log4j.properties file
it search to instantiate the appender define in log4j.properties
If log4J doesn't find log4j.properties file or if appender declared in log4j.rootlogger are not defined elsewhere in log4j.properties file the warning message is displayed.
CAUTION: the content of Properties file must be correct.
The following content is NOT correct
log4j.rootLogger=file
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=c:/Trace/MsgStackLogging.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%m%n
log4j.appender.FILE.ImmediateFlush=true
log4j.appender.FILE.Threshold=debug
log4j.appender.FILE.Append=false
because file appender is declared in LOWER-CASE in log4j.rootlogger statement and defined in log4j.appender statement using UPPER-CASE !
A correct file would be
log4j.rootLogger=FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=c:/Trace/MsgStackLogging.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%m%n
log4j.appender.FILE.ImmediateFlush=true
log4j.appender.FILE.Threshold=debug
log4j.appender.FILE.Append=false
If MAVEN is used, you must put log4j.properties files in src/main/resources AND start a MAVEN build.
Log4j.properties file is then copied in target/classes folder.
Log4J use the log4j.properties file that it found in target/classes !
I had this problem too.
I just forgot to mark the resources directory in IntelliJ IDEA
Rightclick on your directory
Mark directory as
Resources root
For me, the reason was apparently different, and the error message misleading.
With just this in my build.gradle, it would complain that slf4j was missing at the beginning of the log, but still log things, albeit in a poor format:
compile 'log4j:log4j:1.2.17'
Adding that dependency would cause the discussed "no appenders could be found" error message for me, even though I had defined them in src/main/java/log4j.properties:
compile 'log4j:log4j:1.2.17'
compile 'org.slf4j:slf4j-log4j12:1.7.25'
Finally, adding the following dependency (which I only guessed at by copycatting it from another project) resolved the issue:
compile 'log4j:log4j:1.2.17'
compile 'org.slf4j:slf4j-log4j12:1.7.25'
compile 'commons-logging:commons-logging:1.2'
I don't know why, but with this it works. Any insights on that?
My Eclipse installation could not find log4j.properties when running JUnit tests from Eclipse, even though the file was located at src/test/resources.
The reason was that Eclipse (or the m2e connector) did not copy content from src/test/resources to the expected output folder target/test-classes - the root cause was that in the project's properties under Java Build Path -> Source tab -> Source folders on build path -> src/test/resources, somehow there was an Excluded: ** entry. I removed that excluded entry.
Alternatively, I could have manually copied src/test/resources/log4j.properties to target/test-classes/log4j.properties.
If log4j.properties is indeed on the classpath, you are using Spring Boot to make a WAR file for deployment to an app server, you are omitting a web.xml file in favour of Spring Boot's autoconfigure, and you are not getting any log messages whatsoever, you need to explicitly configure Log4j. Assuming you are using Log4j 1.2.x:
public class AppConfig extends SpringBootServletInitializer {
public static void main( String[] args ) {
// Launch the application
ConfigurableApplicationContext context = SpringApplication.run( AppConfig.class, args );
}
#Override
protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
InputStream log4j = this.getClass().getClassLoader().getResourceAsStream("log4j.properties");
PropertyConfigurator.configure(log4j);
return application;
}
// Other beans as required...
}
Maybe add the relevent project contains log4j in java build path, I add mahout_h2o into it when I met this problem in a mahout project using eclipse, it works!
if you work together with a lot of projects you may face a style problem.
*you have to have one lof4j.properties file and this file is included log properties of other project.
*Beside you can try to put log4j properties files into src path when the project is worked Linux OS, libs of other project and log4.properties files can be under one folder into a location on the classpath.
First import:
import org.apache.log4j.PropertyConfigurator;
Then add below code to main method:
String log4jConfPath ="path to/log4j.properties";
PropertyConfigurator.configure(log4jConfPath);
Create a file at path to and add the below code to that file.
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
The solution on this site worked for me https://crunchify.com/java-how-to-configure-log4j-logger-property-correctly/. I now see no warnings at all from log4j
I put this in a log4j.properties file that I put in src/main/resources
# This sets the global logging level and specifies the appenders
log4j.rootLogger=INFO, theConsoleAppender
# settings for the console appender
log4j.appender.theConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.theConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.theConsoleAppender.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Consider the log4j JVM argument Dlog4j.configuration
In general:
Add the JVM argument that points out the log4j config file.
The syntax is just like follows:
java [ options ] -jar file.jar [ arguments ]
A sample of a real command line is just like the following:
java -Dlog4j.configuration=conf/log4j.xml -jar myJarFile.jar myArg1 myArg2
For IntelliJ IDE users:
1.Run/Debug Configurations
2.Edit configurations...
3.VM options
4.Enter the same value also starting with "-D"
Tips:
1.Eclipse IDE users will find an equivalent approach
2.For the run/debug configuration editor, it's very likely that, at the beginning of the times, your particular executable file is not there. Depending on the size of the project you're currently working on, it can be unpleasant to navigate directories to find it. It's less of a hassle if you just run/execute the file (click play) once before proceeding to run/debug config no matter what the execution result is.
3.Pay attention to your working directory, relative paths, and classpath.

Tomcat App says "Unable to configure the logging system. No log.properties was found."

I have an embedded tomcat app and whenever I start it up I see this error printed to the console twice:
Unable to configure the logging system. No log.properties was found.
It seems stupid, but I've done some googling and searched stackoverflow and can't seem to find someone experiencing this problem.
My main class Looks roughly like this:
public class AuthServerEntryPoint {
static {
org.apache.log4j.PropertyConfigurator.configure("conf/log4j.properties");
}
public static void main(String[] args) {
// ...
}
"conf/log4j.properties" contains a seemingly valid configuration:
log4j.appender.mainAppend=org.apache.log4j.ConsoleAppender
log4j.appender.mainAppend.layout=org.apache.log4j.PatternLayout
log4j.appender.mainAppend.layout.ConversionPattern=%d %p [%t] %c -- %m%n
log4j.appender.fileAppend=org.apache.log4j.FileAppender
log4j.appender.fileAppend.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppend.layout.ConversionPattern=%d %p [%t] %c - %m%n
log4j.appender.fileAppend.file=logs/myservice.log
log4j.rootLogger = info, fileAppend
log4j.logger.com.mycompany.myservice = debug, fileAppend
And the logging actually does work - i.e., logs are correctly written to myservice.log. So what gives?
Thanks!
-Carl
By embedded Tomcat app, do you mean that you are starting Tomcat from Java code and are using the class org.apache.catalina.startup.Embedded?
If yes, my guess is that Tomcat might not be able to find its logging configuration file that is set up in catalina.sh (or equivalent) when using the scripts:
LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
The odd part is that this file is called logging.properties, not log.properties, so I'm really not sure. I didn't check Tomcat sources though, maybe they are doing some kind of black magic in there.
Could you just try to rename $CATALINA_BASE/conf/logging.properties into log.properties (or not) and to put it on the classpath of your app (or to set -Djava.util.logging.config.file)?
By default, log4j will look for a logging properties file on the classpath. Put your webapp's logging properties config file into its WEB-INF/classes directory; e.g.
$CATALINA_HOME/webapps/<yourApp>/WEB-INF/classes/log4j.properties
This is the simple approach to getting a webapp to use Log4j is recommended by the referenced documentation. And it is the approach I use myself for webapp logging.
There are various other ways to configure Log4j logging on Tomcat as well. It is possible that your Tomcat has been (partly) configured to use one of them, but something has not been done quite right.
Configuring Tomcat' log4j logging via the system properties is an option that avoids figuring out where log4j is looking ... and what is going wrong. But you are then stuck with creating/using a custom launch script or having to remember to set environment variables before launching Tomcat.
References:
Configuring logging on Tomcat 5.5
Configuring logging on Tomcat 6
The "Default Initialization under Tomcat" section of the Log4j Manual

Categories