Log4j printing to console twice - java

Before with one class, logging was working well, but after I added 2nd Java class, it is logging twice in this second class. Can anyone help me, how to make it log only once. The problem seems to be in this log4j.xml file, because if I comment out appender, it is logging once, but I don't want to change the code in log4j sufficiently, because then I am afraid logging will not work properly in the 1st class.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: [%d{MMM-dd HH:mm:ss,SSS}] %c{3} - %m%n"/>
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.FileAppender">
<param name="file" value="/user/Dave/log.out"/>
<param name="immediateFlush" value="true"/>
<param name="threshold" value="debug"/>
<param name="append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: [%d{MMM-dd HH:mm:ss,SSS}] %c{3} - %m%n"/>
</layout>
</appender>
<logger name="com.asaqa.score">
<level value="all"/>
</logger>
<!-- Root Logger -->
<root>
<priority value="error"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>

By default loggers inherit appenders, and each appender creates log entries. In your case the "com.asaqa.score" logger inherits from root. You can turn this off by setting additivity to false. And you should complete the config of your logger to include an appender
<logger name="com.asaqa.score" additivity="false">
<level value="all"/>
<appender-ref ref="console"/>
</logger>
Also, the error below suggests you're using the old version of log4j. You may want to consider upgrading to log4j 2. In fact, it's recommended by Apache themselves.
On August 5, 2015 the Logging Services Project Management Committee announced that Log4j 1.x had reached end of life. For complete text of the announcement please see the Apache Blog. Users of Log4j 1 are recommended to upgrade to Apache Log4j 2.
When you do, note that there are some changes to the config syntax.

Related

How to configure application logging using Log4J on Tomcat 9?

I want to use Log4J to log from my Tomcat-based application.
The Log4J configuration is
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true">
<appender name="roller" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/application.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[slf5s.start]%d{DATE}[slf5s.DATE]%n%p[slf5s.PRIORITY]%n%x[slf5s.NDC]%n%t[slf5s.THREAD]%n%c[slf5s.CATEGORY]%n%l[slf5s.LOCATION]%n%m[slf5s.MESSAGE]%n%n"/>
</layout>
</appender>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="|%d|%5.5p|%5.5t|%20.20c{20}.%M - %m%n"/>
</layout>
</appender>
<category name="com.acme" additivity="false">
<priority value="trace"/>
<appender-ref ref="roller"/>
<appender-ref ref="console"/>
</category>
</log4j:configuration>
I can see in the stdout/stderr logs that Log4J gets initialised and the expected logging file is created but it remains empty.
The other catalina logs are all created and filled. Is it possible that the JULI logging is preventing Log4J from working properly?
I am migrating the project from Websphere to Tomcat and also introducing Maven.
The problem was that Maven dependencies was loading 2 SLF4J providers: log4j adapter and classic logback.
This resulted in the NopLogger being used which does not log anything.
I explicitly excluded the classic logback dependency and logging now works.

create two log files using RollingFileAppender in log4j.xml

My log4j.xml configuration was like ,
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<appender name="fileAppender1" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="ALL" />
<param name="MaxFileSize" value="3KB" />
<param name="MaxBackupIndex" value="10" />
<param name="File" value="F:/logs/Testing/Project_moduleOne.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MMM-dd-yyyy HH:mm:ss:SSS} %-5p %m%n" />
</layout>
</appender>
<appender name="fileAppender2" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="ALL" />
<param name="MaxFileSize" value="3KB" />
<param name="MaxBackupIndex" value="10" />
<param name="File" value="F:/logs/PAD_Testing/Project_moduleTwo.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MMM-dd-yyyy HH:mm:ss:SSS} %-5p %m%n" />
</layout>
</appender>
<!--sets the priority log level for org.springframework -->
<logger name="com.comp.logger1">
<appender ref="fileAppender1"/>
</logger>
<logger name="com.comp.logger2">
<appender ref="fileAppender2" />
</logger>
<!--sets the default priority log level -->
<root>
<priority value="all"></priority>
<appender-ref ref="fileAppender1" />
<appender-ref ref="fileAppender2" />
</root>
</log4j:configuration>
And two log files also created in the specified location.
I need to know how to log two different data's in these two different log_files independently in JAVA class.
For example,
Logger logOne = Logger.getLogger("com.comp.logger1");
Logger logTwo = Logger.getLogger("com.comp.logger2");
The above code is not working for me. All the log informations are logged to both the created two log files. I need the separation of logging data.
My need is ,
I want to create two log file. Because my project has two modules and log each module in separate log files.
After that , I have to log each module logging data independently .
Please make sure I used the logger name for logging in my java class correctly.
Any new or complete examples using log4j.xml are greatly appreciated.
EDIT :
If I add the additivity="false" in the logger as,
<logger name="com.comp.logger1" additivity="false">
<appender ref="fileAppender1" />
</logger>
<logger name="com.comp.logger2" additivity="false">
<appender ref="fileAppender2" />
</logger>
The log data didn't logged in the created log file.The log file was empty.
Please make sure my <root>...</root> is correct.
You problem is with the <root> section, the root section captures all logs, and you've told it to log to both appenders...
You could remove it, or set additivity="false" on each of your logger elements - this will tell log4j not to log the same log through 'root' if it's already been logged through one of your 'logger's.
Edit: you don't say which version of log4j you are using, but I'm using log4j-1.2.16, and using the file in your post, it fails completely for me because it doesn't like the <appender ref="fileAppender1"/>, it wants them to be <appender-ref ref="fileAppender1"/> (note the -ref after the appender). If I add these in, and also add the additivity attributes that I suggested, then for me it works as you expect.

log4j log one class [duplicate]

I want to set up log4j so that all log meessages produced from classes under package com.foo.bar go to bar.log, and all the log meessages produced from classes under package com.bar.blatz go to blatz.log.
Questions
How do I do this using log4j.xml?
I know its possible using property files, but how do I do it using the XML configuration?
This is based on my answer to a similar question:
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- general application log -->
<appender name="BarLogFile" class="org.apache.log4j.FileAppender">
<param name="File" value="bar.log" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %t [%-40.40c] %x - %m%n"/>
</layout>
</appender>
<!-- additional fooSystem logging -->
<appender name="BlatzLogFile" class="org.apache.log4j.FileAppender">
<param name="File" value="blatz.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %t [%-40.40c] %x - %m%n"/>
</layout>
</appender>
<logger name="com.foo.bar">
<appender-ref ref="BarLogFile"/>
</logger>
<logger name="com.bar.blatz">
<appender-ref ref="BlatzLogFile"/>
</logger>
<root>
<level value="INFO"/>
<!-- no appender, output will be swallowed (I think) -->
</root>
</log4j:configuration>
If you add an appender-ref to the root element, it will also receive com.foo.bar etc messages. You can stop that by specifying 'additivity="false"' on the loggers.
<root>
<level value="INFO"/>
<!-- no appender, output will be swallowed (I think) -->
</root>
We can add appenders here. It will work if the application is using root logger. for example quartz Scheduler API.

why does log4j not log to the files I configured it to with a log4j.xml file?

I've run into this in various environments and have never found a consistent explanation. I've heard comments about the Tomcat container being 'messy', with different logging implementations possibly in there, and then my app or the classloader doesn't know which configuration to use.
This is one of those maddening scenarios when the logging worked once, and then doesn't log an hour later, with no changes to the log4j.xml file. I've got my log4j.xml file in the root of my /src directory, so it gets deployed to the root of the /WEB-INF/classes directory. I'm using Java 6, Tomcat 6, and it's a GWT 2.3 app, running from inside Eclipse Helios on a Windows 7 box.
For what it's worth, here's the log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE}
%5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<appender name="fileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/log4j.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d
%-5p [%c{1}] %m %n" />
</layout>
</appender>
<root>
<priority value="debug"></priority>
<appender-ref ref="fileAppender"/>
</root>
</log4j:configuration>
here's how I get the logger in my class that's doing the logging
protected static Logger m_logger = Logger.getLogger(RemoteLoggingServiceImpl.class);
and then to actually log I just do
m_logger.debug("my log message");
Using the above code, it doesn't write to the logj4.log file.
Then I tried the following, which got it logging to the log4j.log file, but not to the otherFile.log file as I expected. Here's the updated log4j.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE}
%5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<appender name="fileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/log4j.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d
%-5p [%c{1}] %m %n" />
</layout>
</appender>
<appender name="otherFileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/otherFile.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d
%-5p [%c{1}] %m %n" />
</layout>
</appender>
<root>
<priority value="debug"></priority>
<appender-ref ref="fileAppender"/>
</root>
<logger name="com.mypackage.myLoggingClass">
<level value="debug"/>
<appender-ref ref="otherfileAppender"/>
</logger>
</log4j:configuration>
and I create this logger with this instead :
protected static Logger m_logger = Logger.getLogger("com.mypackage.myLoggingClass");
Can anyone explain why it doesn't log at all in the first scenario, and/or why it logs to log4j.log but not otherFile.log in the 2nd scenario?
First off, you didn't list what version of Log4j you are using, so I'm assuming you're using a relatively recent version of Log4j.
In the first block of example code you provided:
<root>
<priority value="debug"></priority>
<appender-ref ref="fileAppender"/>
</root>
You have not modified the logging level of the root appender. Per the
log4j 2.x documentation
If no configuration files are present logback will default to the
DefaultConfiguration which will set up a minimal logging environment
consisting of a ConsoleAppender attached to the root logger. The output
will be formatted using a PatternLayout set to the pattern
"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n".
Note that by default, the root logger is assigned to Level.ERROR.
In order have the logger output to the file in the first example you need to change your root logger to:
<root level="debug">
<appender-ref ref="fileAppender"/>
</root>
A good indicator that the debug logging wasn't working is that you wouldn't have seen any output on the console either since the default logging level was set to "error". I always like to have a console appender on my loggers, so that I can see that my application is actually logging.
<appender-ref ref="Console"/>
In the second example, the root logger does not log to the file for precisely the same reason as in the first example. However you managed to set the "com.mypackage.myLoggingClass" logger up correctly, which is why your application has debug output when you use the "com.mypackage.myLoggingClass" class based logger.
As far as I can see all your original assumptions are correct and the log should be printed, so here's a few things I'd check in this case:
Check your classpath, did you import other logging library jars causing conflicts (slf4j, common-logging etc)?
Check your imports, was it really org.apache.log4j.*, not other logging libraries
Check gwt logging guide, does it conflicts with log4j?
Check the file system lock on log4j.log, is there any other process locking it causing writes to fail?
Check your war/ear file, was log4j.xml really placed on WEB-INF/classes?
Check ${catalina.home} does resolve to the path you intended
Your JRE uses a file named logging.properties to set the handlers and log levels and a few other settings to be shared globally across all Java commands.
Many a times its seen that default is handlers= java.util.logging.ConsoleHandler, you can try appending java.util.logging.FileHandler like below.
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
Also try settng the file formatter to SimpleFormatter instead of XML formatter
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

Spring 3 standalone application does not write output to file

I have a Spring 3 standalone application and I'm using log4j for logging. Log4j settings are the ones in the xml that is pasted below. I get log output writen to console but nothing is writen to log file.
Log4j is initialized in class Main by statement:
DOMConfigurator.configure("abanol-loader-log4j.xml");
I've already tried by changing loggers level values, by changing value of attribute additivity in logger file and even by removing it. I get output writen to console but nothing is writen to log file (but it is created).
I've validated XML file successfully, I've googled for a solution but I get nothing. Any idea?
Thanks in advance.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" threshold="debug" debug="false">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c - %m%n"/>
</layout>
</appender>
<appender name="file" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="abanol-loader.log"/>
<param name="MaxFileSize" value="25MB"/>
<param name="MaxBackupIndex" value="20"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%5p-%d{ISO8601}-[%t]-%C.%M:%L(%c{1}) - %m%n"/>
</layout>
</appender>
<logger name="es.pack1.mypackage" additivity="true">
<level value="DEBUG"/>
<appender-ref ref="file"/>
<appender-ref ref="console"/>
</logger>
<logger name="org.springframework" additivity="true" >
<level value="WARN"/>
<appender-ref ref="file"/>
</logger>
<logger name="net.sf.jasperreports" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="file"/>
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
</log4j:configuration>
You have configure both "The Console Appender" and "RollingFile Appender" in your log4j.xml
So, Log4j defaultly selects the first. i.e, Console Appender as the logging.
So, it was writting the log report in Console(System.out.println)
Please remove the Console Appender, then it will automatically save the log's in the File...........
I've replaced log4j XML configuration by a properties file finally. I think it's same than XML that I was using but it works while XML doesn't. I really don't know why.
log4j.rootCategory=DEBUG, S, file
log4j.logger.es.bod.freenergy.abanol=DEBUG, file
log4j.appender.S = org.apache.log4j.ConsoleAppender
log4j.appender.S.layout = org.apache.log4j.PatternLayout
log4j.appender.S.layout.ConversionPattern =%5p-%d{ISO8601}-[%t]-%C.%M:%L(%c{1}) - %m%n
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File =abanol-loader.log
log4j.appender.file.MaxFileSize = 10Mb
log4j.appender.file.MaxBackupIndex=25
log4j.appender.file.Append = false
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%5p-%d{ISO8601}-[%t]-%C.%M:%L(%c{1}) - %m%n
Thanks to who has answered my question anyway.

Categories