I have log4j appenders that print outputs to the console once when running the program in intellIj
but twice when running the program via executable .jar.
The actual logs that get written to the log file only appear once which is correct.
I define my logger/appenders programmatically in this code block
and after everything is done I call
rootLogger.setAdditivity(false);
but for some reason my classes still output twice to cmdline console when running as a .jar. I call loggers in each class by defining a log variable at the top like so:
public class SomeClass {
static Logger log = Logger.getLogger(SomeClass .class);
and this log variable is used everywhere in the "SomeClass" class.
I've tried setting additivity to false for all the package loggers as well before and after I set their levels...
Logger.getLogger("com.company").setAdditivity(false);
Logger.getLogger("com.company.project.database.Admin").setAdditivity(false);
...
but when I run the code that way it complains it cannot find the appenders for the class that I'm defining all the log4j stuff in, and nothing gets written to output/log.
I think you are on the right track with additivity, however additivity is a property of a child, telling log4j not to use the parents:
https://logging.apache.org/log4net/release/sdk/html/P_log4net_Repository_Hierarchy_Logger_Additivity.htm
You have set additivity to false for the ultimate parent logger, that will never do anything as root will not be a child of anything.
Try setting the additivity to false of each package logger and hopefully that will solve the issue.
Related
In my progrm I have 2 loggers and now I have to save them to files, but no files are being created.
log4j.rootLogger=arcLog, errorLog, INFO
#ARC-logger properties
log4j.appender.arcLog=org.apache.log4j.FileAppender
log4j.appender.arcLog.File=logs/ARC-1Logger.log
log4j.appender.arcLog.Append=true
log4j.appender.arcLog.maxFileSize=5MB
log4j.appender.arcLog.maxBackupIndex=5
log4j.appender.arcLog.threshold=INFO
log4j.appender.arcLog.layout=org.apache.log4j.PatternLayout
log4j.appender.arcLog.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.appender.arcSLog=org.apache.log4j.FileAppender
log4j.appender.arcSLog.File=logs/ARC-Session_Logger.log
log4j.appender.arcSLog.Append=true
log4j.appender.arcSLog.maxFileSize=1024KB
log4j.appender.arcSLog.maxBackupIndex=5
log4j.appender.arcSLog.threshold=WARN
log4j.appender.arcSLog.layout=org.apache.log4j.PatternLayout
log4j.appender.arcSLog.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.category.arcLog=TRACE, ARC-Logger
log4j.additivity.arcLog=false
log4j.category.errorLog=WARN, ARC-Session_Logger
log4j.additivity.arcSLog=false
To get logger I use:
loggerF = Logger.getLogger("ARC-Logger");
loggerS = Logger.getLogger("ARC-Session_Logger");
Appenders was found cause there was no errors about that, but files are not being created.
Can it be that this project is library that I use in another project together with Hibernate that it also has another logger?
I see a few things that are not quite right there. Your properties file should look more like this:
log4j.rootLogger=INFO, arcApp, arcSApp
#ARC-logger properties
log4j.appender.arcApp=org.apache.log4j.RollingFileAppender
log4j.appender.arcApp.File=logs/ARC-1Logger.log
log4j.appender.arcApp.Append=true
log4j.appender.arcApp.maxFileSize=5MB
log4j.appender.arcApp.maxBackupIndex=5
log4j.appender.arcApp.threshold=INFO
log4j.appender.arcApp.layout=org.apache.log4j.PatternLayout
log4j.appender.arcApp.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.appender.arcSApp=org.apache.log4j.RollingFileAppender
log4j.appender.arcSApp.File=logs/ARC-Session_Logger.log
log4j.appender.arcSApp.Append=true
log4j.appender.arcSApp.maxFileSize=1024KB
log4j.appender.arcSApp.maxBackupIndex=5
log4j.appender.arcSApp.threshold=WARN
log4j.appender.arcSApp.layout=org.apache.log4j.PatternLayout
log4j.appender.arcSApp.layout.ConversionPattern=%d [%24F:%t:%L] - %m%n
log4j.logger.arcLog=TRACE, arcApp
log4j.additivity.arcLog=false
log4j.logger.arcSLog=WARN, arcSApp
log4j.additivity.arcSLog=false
And then you should be able to call your classes like:
private static final Logger loggerF = Logger.getLogger("arcLog");
private static final Logger loggerS = Logger.getLogger("arcSLog");
Few problems I saw in your properties:
arcLog and arcSLog are appenders, not loggers, which might lead you to confusion.
If you want to use maxFileSize and maxBackupIndex what you need is a RollingFileAppender, not a FileAppender.
In the rootLogger property you should first define the level, then the appenders.
When you actually create the logger is in log4j.logger.arcLog=TRACE, arcApp, where you define the level for the logger and the previously declared appender.
For using the loggers in your java classes you need to call the loggers instead of the appenders.
I'm working on jdk 1.6 and I have a class that needs to log to 2 different log files using log4j. I have read many other answers, but I can't get mine to work the way I want it. This is my log4j properties.
log4j.debug=false
log4j.rootLogger=ERROR, appLog
log4j.logger.com.my.apps.idm.transactionalemail=DEBUG, appLog, infoLog
log4j.appender.appLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.appLog.File=/opt/apps/logs/${ni.cluster}/TransactionalEmail/1.0/TransactionalEmail.log
log4j.appender.appLog.DatePattern='.'yyyy-MM-dd
log4j.appender.appLog.layout=org.apache.log4j.PatternLayout
log4j.appender.appLog.layout.ConversionPattern=DATE: %d{DATE}%nPRIORITY: %p%nCATEGORY: %c%nTHREAD: %t%nNDC: %x%nMESSAGE:%m%n%n
log4j.appender.infoLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.infoLog.File=/opt/apps/logs/${ni.cluster}/TransactionalEmail/1.0/Info.log
log4j.appender.infoLog.DatePattern='.'yyyy-MM-dd
log4j.appender.infoLog.layout=org.apache.log4j.PatternLayout
log4j.appender.infoLog.layout.ConversionPattern=DATE: %d{DATE}%nPRIORITY: %p%nCATEGORY: %c%nTHREAD: %t%nNDC: %x%nMESSAGE:%m%n%n
And the way I want this to work is like this
public class MyClass{
private static final LOG = Logger.getLogger("appLog");
private static final INFO_LOG = Logger.getLogger("infoLog");
public void myMethod(){
INFO_LOG.debug("This is info");
LOG.debug("This is debug");
}
}
What happens when I run my app is that the Info.log has the same information as TransactionalEmail.log, and also, the line "This is a test" doesn't show up in either of the log files.
What am I doing wrong?
I would recommend against using multiple logger instances for classes. Utilize log4j's configuration to handle logging events as they are generated. You may want to look at the Routing File Appender to decide how log events are handled. From the link
The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. The RoutingAppender should be configured after any Appenders it references to allow it to shut down properly.
I've having issues getting logging set up properly on my development app server (launched from Eclipse). I have the correct logging.properties location in my appengine-web.xml, and the most global parameter is working:
.level=ALL
If I change that to INFO everything quiets down and all is good. But trying to add any sort of override for my packages appears to do nothing at all:
.level=ALL
com.company.level=INFO
(I am using my real package name, using the above as an example)
When I try to a full package path such as com.company.user.level or even a class name such as com.company.user.User.level I still get no change. I've also tried moving my entry above and below the .level statement with no luck. As a last resort I tried taking out .level altogether, but that resulted in no change to my custom class logging.
Between each change I fully stop and restart the development appserver to make sure the file is re-read. Again, if I change .level I see a change in logging level output, but nothing else works. I'm stumped? Any suggestions?
AppEngine SDK: 1.9.17 (1.9.18 is the latest as of this writing but there is nothing to indicate this would be fixed in the change logs).
Thanks!!
UPDATE (Solution)
Thanks to #farrellmr below!!
I was doing the following:
private static final Logger log = Logger.getLogger("MyClass"); // wrong
When I should have been doing:
private static final Logger log = Logger.getLogger(MyClass.class.getName()); // correct
You need to define your logger as -
package test;
private static final Logger LOGGER = Logger.getLogger(MyClass.class.getName());
Then you can define your package log configuration as -
test.level = INFO
I've in my log4j.properties file :
log4j.rootLogger=WARN, CONSOLE, FILEWARN
...
log4j.appender.CONSOLE.threshold=ERROR
...
During Java execution, I would like to put it to WARM.
I did not found anything like Logger.getRootLogger().getAppender("CONSOLE")....setThreshold("WARN")
Is it a solution with some method, or have I to reaload some dedicated properties File with
log4j.appender.CONSOLE.threshold=WARN inside?
The setThreshold method is defined on AppenderSkeleton (the abstract base class of all the standard appenders), not on the Appender interface directly.
((AppenderSkeleton)Logger.getRootLogger().getAppender("CONSOLE"))
.setThreshold(Level.WARN);
I am using a package with many java classes where a lot of org.apache.commons.logging.Log objects are defined. Now I write my own Java main class using these classes; how can I turn on the log information?
I do have log4j.properties file ready. But I am not sure what needs to be included in the java main class in order for this to be effective.
Thank you.
Edit
My log4j.properties file has the following content:
log4j.rootLogger = DEBUG,sysout
log4j.appender.sysout=org.apache.log4j.ConsoleAppender
log4j.appender.sysout.layout=org.apache.log4j.PatternLayout
The package classes use the logger like the following:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
...
public class AClass {
private static final Log log = LogFactory.getLog(AClass.class);
log.debug("Some info ");
...
I am asking what I need to do in my main class in order to get logging information printed out in stdout.
You don't do it in the Java main class, although it might be possible. You need to modify the log4j.properties.
There is a root appender that should already appear in the property file. Set the level to DEBUG and you should see every log message. I recommend defining a fileappender first though. That way you can use your favorite text editor to browse the log messages.
You should define the conversion pattern for the PatternLayout of your appender.
For example:
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Try adding the code below to your main class
import org.apache.log4j.BasicConfigurator;
In main():
BasicConfigurator.configure();
This will use a simple configuration which should output all log messages to the console. Accourding to the Apache logging manual, you can send in the name of a config file as a parmeter like so:
import com.foo.Bar;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class MyApp {
static Logger logger = Logger.getLogger(MyApp.class.getName());
public static void main(String[] args) {
// BasicConfigurator replaced with PropertyConfigurator.
PropertyConfigurator.configure(args[0]);
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
logger.info("Exiting application.");
}
}
I'm assuming the logger jar is in the classpath. I don't know about the apache logging framework but Log4J would send a message to the console (or stderr) about not finding the config file, and it could be easily overlooked depending on what else is sent to stdout. Also, (again for log4j) the directory the property file was in had to be in the CLASSPATH as well.
It occurs to me to double check the expected name of the logfile. Log4J uses log4j.properties but is that what the Apache framework expects? Either way, you can declare the name of the config file when the logger is instantiated. Not sure what the methodname is though.