I am having problem that even though I specify the property log4j.additivity=false ,still log messages are getting displayed in both logs (Root log and intended log).
But I want to log only in intended log file how can I achieve it through configuration in properties file.
I am not a log4j expert so any help is appreciated.
my log file looks like this
#==============================================
# RIPNET Logger (..//logs everything under the sun)
#==============================================
log4j.rootLogger=INFO, RIPNETappender
log4j.appender.RIPNETappender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.RIPNETappender.layout=org.apache.log4j.PatternLayout
log4j.appender.RIPNETappender.layout.ConversionPattern=%d %p [%t:%c] - <%m>%n
log4j.appender.RIPNETappender.File=..//logs//RIPNET.log
#====================================
# WorkOrder Logger
#====================================
log4j.logger.com.reino.ripnet.servlet.alarm=INFO, WorkOrderAppender
log4j.appender.WorkOrderAppender=org.apache.log4j.DailyRollingFileAppender
log4j.additivity.com.reino.ripnet.servlet.alarm=false
log4j.appender.WorkOrderAppender.File=..//logs//WorkOrder.xml.log
log4j.appender.WorkOrderAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.WorkOrderAppender.layout.ConversionPattern=%d %p [%t:%c] - <%m>%n
though i set the value
log4j.additivity.com.reino.ripnet.servlet.alarm=false
the log messages are still getting logged in root log
i even tried setting
log4j.additivity.WorkOrderAppender=false
in the code i call the logger by
Logger logger = Logger.getLogger("WorkOrderAppender");
i also tried using
Logger logger = Logger.getLogger(getClass());
but still no use
You are mixing Loggers and appenders. Additivity can be configured on a logger, and the Logger takes the <severity level> and an <appender name> as argument. Look closely at how I renamed your WorkOrder* names (* = {Appender, Logger}).
Thus, the combination of
log4j.logger.WorkOrderLogger=INFO, WorkOrderAppender
log4j.additivity.WorkOrderLogger=false
and
Logger logger = Logger.getLogger("WorkOrderLogger");
should work.
Related
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
Am getting dupliate log entries when using the below log4j properties.
log4j.rootLogger.additivity=false
log4j.rootLogger=TRACE
#Standard Log
log4j.appender.SL=org.apache.log4j.DailyRollingFileAppender
log4j.appender.SL.File=${log.file}/log.log
log4j.appender.SL.layout=org.apache.log4j.PatternLayout
log4j.appender.SL.layout.ConversionPattern=[%5p] [%t %d{HH:mm:ss:SSS}] [%X{sessionId}:%X{hostId}:%X{userId}] (%F:%M:%L) %m%n
#Error Log
log4j.appender.EL=org.apache.log4j.DailyRollingFileAppender
log4j.appender.EL.File=${log.file}/error.log
log4j.appender.EL.layout=org.apache.log4j.PatternLayout
log4j.appender.EL.Threshold=ERROR
log4j.appender.EL.layout.ConversionPattern=[%5p] [%t %d{HH:mm:ss:SSS}] [%X{sessionId}:%X{hostId}:%X{userId}] (%F:%M:%L) %m%n
# Database Log
log4j.logger.org.springframework.jdbc=DEBUG,DL
log4j.appender.DL=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DL.File=${log.file}/db.log
log4j.appender.DL.layout=org.apache.log4j.PatternLayout
log4j.appender.DL.layout.ConversionPattern=[%5p] [%t %d{HH:mm:ss:SSS}] [%X{sessionId}:%X{hostId}:%X{userId}] (%F:%M:%L) %m%n
#Logger configuration
log4j.logger.com.singaporeair.maps=TRACE
Could not find out the cause of the duplicates.
Any help is appreciated.
Thanks
This properties file should cause you to have NO logging. The rootlogger has a no appenders defined. This makes me think you are actually using a different configuration that posted here.
I have two log4j loggers in each of my classes in my code :
logA = Logger.getLogger(com.some.class.in.my.project);
logB = Logger.getLogger('perf');
I want these two loggers to output data into two COMPLETELY different files. I can't seem to get it to work.
Here are my log4j properties :
log4j.rootLogger = myAppenderA
# A
log4j.appender.myAppenderA=org.apache.log4j.RollingFileAppender
log4j.appender.myAppenderA.File=../logs/mylogfileA.log
log4j.appender.myAppenderA.additivity=false
log4j.appender.myAppenderA.Threshold=DEBUG
log4j.appender.myAppenderA.layout=org.apache.log4j.PatternLayout
log4j.appender.myAppenderA.layout.ConversionPattern=%d{ISO8601} %-5p 0 %m%n
# perf
log4j.appender.perf=org.apache.log4j.RollingFileAppender
log4j.appender.perf.File=..logs/perf.log
log4j.appender.perf.additivity=false
log4j.appender.perf.Threshold=DEBUG
log4j.appender.perf.layout=org.apache.log4j.PatternLayout
log4j.appender.perf.layout.ConversionPattern=%d{ISO8601} %-5p 0 %m%n
log4j.logger.myAppenderB = perf
Both myLogfileA.log and perf.log contain the same data. Supposedly setting additivity to false fixes this, but i have tried it and it has little affect.
Additivity is a property of the logger not the appender so you have to remove additivity property from appender and add it to your loggers configuration.
Currently you have only the rootLogger configuration in the file (and you are not defining the logging level for it) so all your loggers will extend the appenders from it. To stop logging messages propagation to ancestors you have to use the additivity property on the logger. So to achieve what you want you have:
Define one more appender (root) for rootLogger. It will be the default one and inherited by other loggers which don't have additivity = false
Assign myAppenderA appender to mypackage.MyClass logger
Assign pref appender to pref logger
Set additivity of myAppenderA and pref loggers to false to stop log message propagation to ancestor loggers.
There is the hole properties file:
log4j.rootLogger = DEBUG, root
# Root
log4j.appender.root=org.apache.log4j.RollingFileAppender
log4j.appender.root.File=logs/mainLogInheritable.log
log4j.appender.root.Threshold=DEBUG
log4j.appender.root.layout=org.apache.log4j.PatternLayout
log4j.appender.root.layout.ConversionPattern=%d{ISO8601} %-5p 0 %m%n
# A
log4j.appender.myAppenderA=org.apache.log4j.RollingFileAppender
log4j.appender.myAppenderA.File=logs/mylogfileA.log
#log4j.appender.myAppenderA.additivity=false
log4j.appender.myAppenderA.Threshold=DEBUG
log4j.appender.myAppenderA.layout=org.apache.log4j.PatternLayout
log4j.appender.myAppenderA.layout.ConversionPattern=%d{ISO8601} %-5p 0 %m%n
# perf
log4j.appender.perf=org.apache.log4j.RollingFileAppender
log4j.appender.perf.File=logs/perf.log
#log4j.appender.perf.additivity=false
log4j.appender.perf.Threshold=DEBUG
log4j.appender.perf.layout=org.apache.log4j.PatternLayout
log4j.appender.perf.layout.ConversionPattern=%d{ISO8601} %-5p 0 %m%n
log4j.logger.mypackage.MyClass = DEBUG, myAppenderA
log4j.logger.perf = DEBUG, perf
log4j.additivity.perf = false
log4j.additivity.mypackage.MyClass = false
To test if it is logging to three different files you can try this:
Logger.getLogger("mypackage.MyClass").debug("1111");
Logger.getLogger("perf").debug("2222");
Logger.getLogger("anyName").debug("3333");
In my Java console app, I want to log certain events to a log file and certain others to console. This is what I've got now
log4j.rootLogger=error, 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{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.L1=org.apache.log4j.FileAppender
log4j.appender.L1.layout=org.apache.log4j.PatternLayout
log4j.appender.L1.layout.ConversionPattern=%-22d{dd/MMM/yyyy HH:mm:ss} – %m%n
log4j.appender.L1.file=failedtoaddusers.log
In my Java app, I instantiate two log instances using
private static Logger log = Logger.getLogger(ActiveDirectoryManage.class);
private static Logger failedToAddUsersLogger = Logger.getLogger("FailedToAddUsersLogging");
My issue is that failedToAddUsersLogger.warn("xyz") also writes to the console in addition to the log file failedtoaddusers.log.
I just want it to write to the log file and not to the console.
How do I accomplish that?
You need to set additivity to "false" (read more on logger additivity in the Appenders and Layouts section of the log4j manual):
log4j.additivity.FailedToAddUsersLogging=false
log4j.logger.FailedToAddUsersLogging = your level, L1
Also, make sure you have one of new versions of log4j, "additivity" setting was not available from beginning.
I want specific messages generated from within the same class to be logged separately. So, how can I create 2 different types of loggers within the same class. Currently, the Properties file looks like
log4j.rootCategory=DEBUG, O
# Stdout
log4j.appender.O=org.apache.log4j.ConsoleAppender
log4j.appender.O.layout=org.apache.log4j.PatternLayout
log4j.appender.O.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
# File
log4j.appender.MESSAGE=org.apache.log4j.RollingFileAppender
log4j.appender.MESSAGE.File=target/logs/messages.log
# Control the maximum log file size
log4j.appender.MESSAGE.MaxFileSize=1000KB
# Archive log files (one backup file here)
log4j.appender.MESSAGE.MaxBackupIndex=100
log4j.appender.MESSAGE.layout=org.apache.log4j.PatternLayout
log4j.appender.MESSAGE.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M (% F:% L) - %m%n
log4j.appender.MESSAGE.
log4j.category.failedMessagesLog=INFO, MESSAGE
I'm using the logging in my code as: –
/** Logger. */
Logger logger = Logger.getLogger(MyClass.class);
Logger msgLogger = Logger.getLogger("MESSAGE");
Upon testing, I get an empty log file (messages.log) created.
Any suggestions??
Create two loggers with different names. You can configure them on a per name basis.
A simple way to do this is to add a suffix to you class name. e.g.
Log log1 = LogFactory.getLog(getClass().getName()+".log1");
Log log2 = LogFactory.getLog(getClass().getName()+".log2");
in your properties file.
log4j.category.mypackage.myclass.log1=INFO, MESSAGE1
log4j.category.mypackage.myclass.log2=INFO, MESSAGE2
log4j.rootCategory=DEBUG, O
log4j.appender.O=org.apache.log4j.ConsoleAppender
log4j.appender.O.layout=org.apache.log4j.PatternLayout
log4j.appender.O.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
log4j.appender.MESSAGE=org.apache.log4j.RollingFileAppender
log4j.appender.MESSAGE.File=target/logs/messages.log
log4j.appender.MESSAGE.MaxFileSize=1000KB
log4j.appender.MESSAGE.MaxBackupIndex=100
log4j.appender.MESSAGE.layout=org.apache.log4j.PatternLayout
log4j.appender.MESSAGE.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M
log4j.appender.**MESSAGE2**=org.apache.log4j.RollingFileAppender
log4j.appender.**MESSAGE2**.File=target/logs/**messages2**.log
log4j.appender.**MESSAGE2**.MaxFileSize=1000KB
log4j.appender.**MESSAGE2**.MaxBackupIndex=100
log4j.appender.**MESSAGE2**.layout=org.apache.log4j.PatternLayout
log4j.appender.**MESSAGE2**.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M
log4j.category.failedMessagesLog=INFO, MESSAGE , **MESSAGE2**
"failedMessagesLog" is the java file to which appender (INFO,MESSAGE, MESSAGE1) is applied.
I have just reused existing RollingFileAppender. you can use any other appender ( like fileAppender).
You should use the right Class name Logger logger = Logger.getLogger(MyClass.class)
should be changed to private static final Logger log = Logger.getLogger( **failedMessagesLog.class** );
Make sure you are using log4j's logging ie
import **org.apache.log4j.Logger**;