I am having problem that even though I specify the level to ERROR in the root tag, the specified appender logs all levels (debug, info, warn) to the file regardless the settings. I am not a log4j expert so any help is appreciated.
Here is a bit more info on the subject:
- I have checked the classpath for log4j.properties (there is none) except the log4j.xml
here is the log4j.xml file:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="[AC - %5p] [%d{ISO8601}] [%t] [%c{1} - %L] %m%n" />
</layout>
</appender>
<appender name="logfile" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/server.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="2" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
</layout>
</appender>
<appender name="payloadAppender" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/payload.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
</layout>
</appender>
<appender name="errorLog" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/error.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[AC - %-5p] {%d{dd.MM.yyyy - HH.mm.ss}} %m%n" />
</layout>
</appender>
<appender name="traceLog"
class="org.apache.log4j.RollingFileAppender">
<param name="File" value="./logs/trace.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="20" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="[AccessControl - %-5p] {%t: %d{dd.MM.yyyy - HH.mm.ss,SSS}} %m%n" />
</layout>
</appender>
<appender name="traceSocketAppender" class="org.apache.log4j.net.SocketAppender">
<param name="remoteHost" value="localhost" />
<param name="port" value="4445" />
<param name="locationInfo" value="true" />
</appender>
<logger name="TraceLogger">
<level value="trace" /> <!-- Set level to trace to activate tracing -->
<appender-ref ref="traceLog" />
</logger>
<logger name="org.springframework.ws.server.endpoint.interceptor">
<level value="DEBUG" />
<appender-ref ref="payloadAppender" />
</logger>
<root>
<level value="error" />
<appender-ref ref="errorLog" />
</root>
</log4j:configuration>
If I replace the root with another logger, then nothing gets logged at all to the specified appender.
<logger name="com.mydomain.logic">
<level value="error" />
<appender-ref ref="errorLog" />
</logger>
... and thank you guys for the hints so far:-)
This is correct behavior. The root logger is like the default behavior. So if you don't specify any logger it will take root logger level as the default level but this does not mean that root logger level is the level for all your logs.
Any of your code which logs using 'TraceLogger'logger or 'org.springframework.ws.server.endpoint.interceptor' logger will log messages using TRACE and DEBUG level respectively any other code will use root logger to log message using level, which is in your case ERROR.
So if you use logger other than root, root log level will be overridden by that logger's log level. To get the desired output change the other two log level to ERROR.
I hope this is helpful.
Two things: Check additivity and decide whether you want log events captured by more detailed levels of logging to propagate to the root logger.
Secondly, check the level for the root logger. In addition you can also add filtering on the appender itself, but this should normally not be necessary.
Run your program with -Dlog4j.debug so that standard out gets info about how log4j is configured -- I suspected that it isn't configured the way that you think it is.
To add on to what James A. N. Stauffer and cynicalman said - I would bet that there is another log4j.xml / log4j.properties on your classpath other than the one you wish to be used that is causing log4j to configure itself the way it is.
-Dlog4j.debug
is an absolute killer way to troubleshoot any log4j issues.The root logger resides at the top of the logger hierarchy. It is exceptional in three ways:
The rootLogger is the father of all appenders. Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy (including rootLogger)
For example, if the
console
appender is added to theroot logger
, then all enabled logging requests will at least print on the console. If in addition a file appender is added to a logger, sayL
, then enabled logging requests forL
andL's
children will print on a file and on theconsole
. It is possible to override this default behavior so that appender accumulation is no longer additive by setting the additivity flag to false.From the log4j manual
To sum up:
If you want not to propagate a logging event to the parents loggers (say rootLogger) then add the additivity flag to false in those loggers. In your case:
In standard log4j config style (which I prefer to XML):
Hope this helps.
If you are using a
log4j.properties
file, this file is typically expected to be in the root of your classpath, so make sure it's there.