log4j Could not read configuration file - java

I am adding logging to a java web project I am working on. I have run into an error that I am unable to figure out.
The error I am getting from tomcat is:
log4j:ERROR Could not read configuration file [log4j.properties].
java.io.FileNotFoundException: log4j.properties (No such file or directory)
I have this simple method in my class:
#RemotingInclude
public UserAccount save(UserAccount dataObject)
{
PropertyConfigurator.configure("log4j.properties");
logger.debug(dataObject.toString());
return dao.save(dataObject);
}
When I look in my webapps//WEB-INF/class folder I do see my log4j.properties file. When I deploy to my tomcat server and restart tomcat, I do see my admin.log file created, but nothing is written to it. Even after hitting the method above. Any help with this is greatly appreciated.
This is the current contents of my log4j.properties file:
log4j.appender.AdminFileAppender=org.apache.log4j.FileAppender
log4j.appender.AdminFileAppender.File=admin.log
log4j.appender.AdminFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.AdminFileAppender.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n.
log4j.appender.ReportFileAppender=org.apache.log4j.FileAppender
log4j.appender.ReportFileAppender.File=report.log
log4j.appender.ReportFileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.ReportFileAppender.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n
log4j.logger.com.rottmanj.services=WARN,AdminFileAppender

That approach of bootstraping the Log4j is wrong. This is usually the way that is implemented:
import org.apache.log4j.Logger;
public class MyService {
public UserAccount save(UserAccount dataObject) {
logger.debug(dataObject.toString());
return dao.save(dataObject);
}
private static Logger logger = Logger.getLogger(MyService.class);
}
This way Log4j will automatically lookup for the log4j.properties in the root of the classpath.

Related

loading log4j.properties for log4j2

please check the attached image of project structure, let me know if i positioned log4j2.properties right.
also have a look at versions of jars I am using.
I wrote a simple program to print logs on console. in order to achieve this I wrote log4j2.properties file as follows.
Root logger option
log4j.rootLogger=INFO, file
log4j.appender.file= org.apache.logging.log4j.core.appender.ConsoleAppender
log4j.appender.file.Target=System.out
log4j.appender.file.Layout=org.apache.logging.log4j.core.layout.PatternLayout
log4j.appender.file.Layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
Main program is as follows.(also shown in image)
package goldensource.track.logs;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.PropertiesUtil;
public class TestLogger {
private Logger logger;
private PropertiesUtil pu;
TestLogger()
{
System.setProperty("log4j.configurationFile","log4j2.properties");
logger = LogManager.getLogger(TestLogger.class);
logger.info("Yes I am there!");
logger.debug("I am debugging!");
logger.warn("giving you a warner!");
}
public static void main(String[] args) {
TestLogger z = new TestLogger();
}}
I have created a reference of PropertiesUtil but anyways I am not using it.
when I am executing this program nothing is shown on console. as I could make out, I am not able to load properties file properly.
suggest me any modifications or alternatives with examples.
Thanks in advance!
Without any feedback on the error you are getting, I can guess that one of the problems is with the file name. You should specify the absolute path to your log4j2.properties file when you are setting the system property:
System.setProperty("log4j.configurationFile","/absolute/path/to/log4j2.properties");
In this way the logger system will know exactly where to find your file.

Log4j Could Not Read Configuration File SELENIUM JAVA

How do I get log4j to read up a properties file.
I'm writing a Java for testing with selenium which I want to use log4j. As i encounter an error of Log4j could not read configuration file [ERROR] Ignoring configuration file . Kindly advise , Thanks you . In my main method if have this:
static Logger log = Logger.getLogger(Testing.class);
Log4j.properties:
log4j.rootCategory=DEBUG, R
# File
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=D:/log4j.log
# Control the maximum log file size
log4j.appender.R.MaxFileSize=100KB
# Archive log files (one backup file here)
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
My Testcase :
#Test //Tested Login
public void TestLogin_Success() throws Exception {
try{
//PropertyConfigurator.configure("log4j.properties");
driver = new FirefoxDriver();
LoginBuilder.Execute(driver);
log.info("TEST A TEST");
driver.quit();
}catch (Exception e){
//Log.error(e.getMessage());
throw (e);
}
}
You can put the log4j.properties file under the resources folder corresponding to the java folder of your class file.
Also to configure it using configurator you can use the following code :
import org.apache.log4j.PropertyConfigurator;
....your base class
....inside the main/setup method
PropertyConfigurator.configure(Testing.class.getClassLoader().getResource("log4j.properties"));
To make sure if the logger is working or not, you can try and log the same details to the console window and see the differences. Just add these changes and observe :
log4j.rootCategory=DEBUG, console, R
log4j.appender.console =org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p -> %m %n
Or in your case ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
Your log4j.properties expected to be in class path. You also can set it via system property
log4j.configuration
. Below is example for ant target
<sysproperty key="log4j.configuration" value="file:///${lib.dir}/log4j.properties" />

How to log from core libraries

I am uisng log4j in one of my applications, the code is as follows;
log=/var/lib/openshift/5372745b4382ec49cb0000d5/app-root/runtime/dependencies/jbossas/deployments/Logs/AppName.log
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
log4j.rootLogger=DEBUG, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.append=true log4j.appender.FILE.file=${log}
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d %-5p %c - %m%n
This application also will use some core application code which is shared between various apps - How do i therefore log from this core code base as it will be shared amongst many applications - this means i can't provide a concrete log= value
Would something like this suffice?
log=/var/lib/openshift/5372745b4382ec49cb0000d5/app-root/runtime/dependencies/jbossas/deployments/Logs/*.log
One approach would be to
have different File appenders for each appplication
Load those appeanders in the respective Application Logger.
protected static final Logger LOGGER = Logger.getLogger(X.class);
static
{
if (null == LOGGER.getAppender("TEST_LOG_APPENDER"))
{
RollingFileAppender fa = new RollingFileAppender();
fa.setName("TEST_LOG_APPENDER");
fa.setFile("/test-output/" + "App_1.log");
fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
fa.setThreshold(Level.DEBUG);
fa.setAppend(true);
fa.setMaxFileSize("10MB");
fa.activateOptions();
LOGGER.addAppender(fa);
}
}
Note that here you need not to create new appender, rather remove others and use only one.
Also this will work if you have a common app level logger.
Not sure if this is a right way of doing it. But just a thought.

Log4j config - different logs to different files

This might be a very easy question for some, but personally I find Log4j config to be nightmarishly difficult and that learning to perform brain surgery might be less challenging.
I am trying to lave multiple loggers logging into different files.
Here is what I have in my log4j.properties file:
# Root logger option
log4j.rootLogger=INFO, file, admin
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=/home/nick/logging/file.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
log4j.appender.admin=org.apache.log4j.RollingFileAppender
log4j.appender.admin.File=/home/nick/logging/admin.log
log4j.appender.admin.MaxFileSize=1MB
log4j.appender.admin.MaxBackupIndex=1
log4j.appender.admin.layout=org.apache.log4j.PatternLayout
log4j.appender.admin.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
And here is my (very simple) Java app used to test the config:
public static void main(String[] args) throws Exception {
Properties resource = new Properties();
InputStream in = new FileInputStream("/home/nick/logging/log4j.properties");
resource.load(in);
PropertyConfigurator.configure(resource);
Logger admin = Logger.getLogger("admin");
Logger file = Logger.getLogger("file");
admin.info("hello admin");
file.info("hello file");
}
I have 2 problems:
One problem I always get an exception in the line PropertyConfigurator.configure(resource);:
java.io.FileNotFoundException: /home/nick/logging (Is a directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:136)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:289)
at org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:167)
at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:163)
at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:256)
The 2nd problem is that both messages are written to both logs. Here is the actual result:
File admin:log:
2014-04-27 11:55:30 INFO admin - hello admin
2014-04-27 11:55:30 INFO file - hello file
File file.log:
2014-04-27 11:55:30 INFO admin - hello admin
2014-04-27 11:55:30 INFO file - hello file
Here is the required result:
File admin:log:
2014-04-27 11:55:30 INFO admin - hello admin
File file.log:
2014-04-27 11:55:30 INFO file - hello file
What is causing the exception, and how can I achieve the required result?
Log4J makes a distinction between loggers, which are responsible for generating log messages, and appenders, which are responsible for sending those messages somewhere (a file, the console, a database, etc.). Loggers form a hierarchy, the root logger is the parent of the logger named admin, which is the parent of admin.component1, etc., and you can attach appenders to any logger in the hierarchy. By default a logger will send messages to all appenders that are attached directly to it, or to any of its ancestors in the hierarchy (this is why loggers are conventionally named like Java classes, e.g. you can control logging for com.example.Class1 and com.example.subpkg.AnotherClass by configuring the com.example logger).
Loggers and appenders form separate namespaces and this is the source of your confusion - the logger named admin and the appender named admin are two separate entities.
The configuration you have given in the question defines one logger (the root logger) which sends all the messages it generates to two separate appenders, one for each of the two files. Your code then requests two different loggers and generates one log message with each logger. Both these loggers inherit the appender configuration from the root logger, so they both send their messages to both of the configured appenders.
Instead of attaching the two appenders to the root logger, you should attach the file appender to the file logger and the admin appender to the admin logger:
log4j.rootLogger=INFO
log4j.logger.file=INFO, file
log4j.logger.admin=INFO, admin
This way the file logger will send messages only to file.log, the admin logger only to admin.log, and all messages from other loggers will be silently discarded, as there are no appenders attached to the root.
The additivity flag is the exception to this rule - setting a logger's additivity to false essentially disconnects the arrow from a logger up to its parent, so messages generated by that logger (or flowing into it from one of its children) will not go any further up the tree, they will only go to appenders attached directly to the logger in question.
To answer my own question, this is what I needed:
log4j.logger.file=DEBUG, fileAppender
log4j.logger.admin=DEBUG, adminAppender
log4j.additivity.file=false
log4j.additivity.admin=false
log4j.appender.fileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.fileAppender.File=/home/nick/logging/file.log
log4j.appender.fileAppender.MaxFileSize=1MB
log4j.appender.fileAppender.MaxBackupIndex=1
log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
log4j.appender.adminAppender=org.apache.log4j.RollingFileAppender
log4j.appender.adminAppender.File=/home/nick/logging/admin.log
log4j.appender.adminAppender.MaxFileSize=1MB
log4j.appender.adminAppender.MaxBackupIndex=1
log4j.appender.adminAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.adminAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n
You don't need to load the properties file. Just place it inside the src folder that will automatically added in class path.
Sample code:
public static void main(String[] args) throws Exception {
Logger admin = Logger.getLogger("admin");
Logger file = Logger.getLogger("file");
admin.info("hello admin");
file.info("hello file");
}
First: log4j recommands to use xml format file for properties.
Second: its better to load the properties file in the classloader.
Third: there is inheritance in logger, but you can cut it with additivity property see log4j.properties file - multiple loggers in same class

log4j:ERROR while writing the logs statements in file

I have created a java project called Project1. for this project i created a log4j.properties file. For writing the log statements in log file, i used DailyRollingFileAppenders. I am using log4j-1.2.16.jar. The log file is :
log4j.logger.com.gridsense.server.automode=DEBUG, stdout,Rollfile
log4j.rootLogger=off
log4j.logger.com.gridsense.server.automode=debug,Rollfile,stdout
log4j.appender.Rollfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Rollfile.ImmediateFlush=false
log4j.appender.Rollfile.Append=true
log4j.appender.Rollfile.Threshold=DEBUG
log4j.appender.Rollfile.bufferedIO = true
log4j.appender.Rollfile.File=D:/logs/AutoGS.log
log4j.appender.Rollfile.layout=org.apache.log4j.PatternLayout
log4j.appender.Rollfile.layout.ConversionPattern=[%t] %-5p %c %d{dd/MM/yyyy HH:mm:ss} %m%n
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=DEBUG
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x %m%n
When i run the project i get the following error
log4j:ERROR Could not close org.apache.log4j.helpers.QuietWriter#1105348
java.io.IOException: The handle is invalid
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:282)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:263)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
at java.io.BufferedWriter.close(BufferedWriter.java:246)
at java.io.FilterWriter.close(FilterWriter.java:87)
at org.apache.log4j.FileAppender.closeFile(FileAppender.java:185)
at org.apache.log4j.FileAppender.reset(FileAppender.java:343)
at org.apache.log4j.WriterAppender.close(WriterAppender.java:207)
at org.apache.log4j.AppenderSkeleton.finalize(AppenderSkeleton.java:144)
at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
log4j:ERROR Failed to write [[DefaultQuartzScheduler_Worker-2] DEBUG com.gridsense.server.automode.backgroundWorker.TimerTaskToBeFired 03/05/2013 17:34:45 ? TimerTaskToBeFired.execute - firing timer job with Key [DropBoxFileFetchingSchedulerGroup.JobDetail-ID-1]].
I don't understand what is the problem.
My reading of the stacktrace is that something has leaked a FileAppender object, and that appender's finalize method is attempting to clean it up. But it looks like that is failing because the resource in question has already been closed.
That's the easy part. The hard part is identifying the source of the leak. My guess is that it is caused by this line:
log4j.logger.com.gridsense.server.automode=debug,Rollfile,stdout
which appears to be configuring a second logger tree duplicating the one configure a couple of lines earlier.

Categories