How to understand log4j.xml file - java

I'm trying to understand the following log4j.xml file:
---Item 1
<!-- 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: %c - %m%n" />
</layout>
</appender>
----Item 2
<!-- Application Loggers -->
<logger name="com.somepackagename">
<level value="info" />
</logger>
--Item 4
<logger name="org.hibernate.validator">
<level value="debug" />
</logger>
---Item 5
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
Can anyone explain what each item does?

<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>
Appenders are responsible for delivering LogEvents to their destination. The name of of the appender is "console" and this is the name that is used to refer to the appender in the rest of the configuration file. The class to use for the appender is org.apache.log4j.ConsoleAppender .
The console appender has one param element defined. Looking at the javadoc for ConsoleAppender , the setTarget method is used to choose which console stream to print messages to, System.out or System.err. This one configures the appender to use System.out.
The console appender also has a layout element defined which uses org.apache.log4j.PatternLayout . Looking at the javadoc for PatternLayout , the setConversionPattern method takes a string describing the layout for messages. The details of this format can also be found in the javadoc.
Then you have three loggers:
A logger element must have a name attribute. This is the name of the logger used when creating the Logger instance(usually the fully qualified class name, in this case com.somepackagename).
<!-- Application Loggers -->
<logger name="com.somepackagename">
<level value="info" />
</logger>
<logger name="org.hibernate.validator">
<level value="debug" />
</logger>
The most important logger you need to configure is the root logger. The root logger is configured to output log message at level "debug" or higher to the appender named "console".
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="console" />
</root>
For more on log4j priority values:
log4j logging hierarchy order

Related

log4j fatal level logging required

This is my log4j.xml. i want only FATAL log from package com.xyz.rest should print to /LOGS/Acb/d.log file.
But i can see Debug level logs as well in file. Why log4j is printing Debug level logs from com.xyz.rest package.
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="Def" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="/LOGS/Acb/d.log"/>
<param name="MaxFileSize" value="10000KB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p [%c{1}] %m%n"/>
</layout>
</appender>
<logger name="com.xyz.rest">
<logger value="fatal"/>
<appender-ref ref="Def"/>
</logger>
</log4j:configuration>
Its because with the following code you are adding another log level to your com.xyz.rest package which is not removing the debug level which your package inherits from parents:
<logger name="com.xyz.rest">
<logger value="fatal"/>
<appender-ref ref="Def"/>
</logger>
What you need is to set the additivity to false so that rather than adding another log level, you will set the log level:
<logger name="com.xyz.rest" additivity="false">
<logger value="fatal"/>
<appender-ref ref="Def"/>
</logger>
More information can be found here.
Not sure but it might also be necessary to enclose the <logger></logger> tags in <loggers></loggers> tag

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.

SLF 4j Logs are not written to log

Logs are not written properly
slf version slf4j-api-1.7.5.jar, slf4j-log4j12-1.7.5.jar, log4j-1.2.16.jar
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!-- log4j generic catchall for adapters. -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Example DailyRollingFile appender, this is the preferred logging appender -->
<appender name="CommonAdapterAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="/opt/adapter.log" />
<param name="encoding" value="UTF-8" />
<param name="append" value="true" />
<!-- Rollover at the top of every hour -->
<param name="DatePattern" value="'.'yyyy-MM-dd-HH" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS-zzz} %5p [%t] %c{1} - %m%n" />
</layout>
</appender>
<!-- Categories -->
<category name="com.other" additivity="false">
<priority value="warn" />
</category>
<logger name="com.adapter" additivity="false">
<level value="debug" />
<appender-ref ref="CommonAdapterAppender"/>
</logger>
<logger name="com.adaptations" additivity="false">
<level value="debug" />
<appender-ref ref="CommonAdapterAppender"/>
</logger>
<root>
<priority value="error" />
<appender-ref ref="CommonAdapterAppender" />
<!-- <appender-ref ref="SyslogAppender"/> -->
</root>
</log4j:configuration>
The above log4j file is used by multiple adapters. First time it is writing to adapter.log and after that only some component logs are written. Also I have noticed that after the second time it is writing few logs to adapter.log..
I cannot understand what is going wrong here. Can someone please help me out?
I believe you should be using a single shared log 4J configuration and instance for all your adapters if you want to use the the same log file.
As is, Log 4j instances are probably competing for the control of the file.

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.

Log4j: Log File correct, but Stdout only showing a subset

I have a problem with the configuration of my logging with log4j. All the log messages are shown as expected in the root.log file, but the stdout, however, does only show a subset of the root.log although I configured it to be the same.
EDIT: Precisely I am missing all messages from a.b.
EDIT 2: I am not absolutely sure, but I think that some messages from a.b. (INFO and DEBUG) get loggedd on stdout, others don't. Might that be a problem related to threads? E.g. some threads doing logging, some not?
The following is my log4j.xml, is there eventually a mistake?
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,SSS} [%t] (%C:%L) %-5p - %m%n" />
</layout>
</appender>
<appender name="FILE_ALL" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${catalina.home}/logs/root.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-4r (%F:%L) %-5p %x - %m%n" />
</layout>
</appender>
<logger name="a.b.master">
<level value="DEBUG" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE_ALL" />
</logger>
<logger name="a.b.master.orm.support.HibernateSessionFilter">
<level value="INFO" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE_ALL" />
</logger>
<logger name="a.b.master.aop.hibernate.OpenSessionInRequestInterceptor">
<level value="info" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE_ALL" />
</logger>
<root>
<level value="INFO"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE_ALL"/>
</root>
</log4j:configuration>
I am using Commons Logging as implementation.
Thanks for the help!
Your configuration is very similar to mine where my logs are dumped into the console and to some remote host. Try this to see if it works for you:-
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
...
</appender>
<appender name="FILE_ALL" class="org.apache.log4j.RollingFileAppender">
...
</appender>
<logger name="a.b.master">
<level value="debug" />
</logger>
<logger name="a.b.master.orm.support.HibernateSessionFilter">
<level value="info" />
</logger>
<logger name="a.b.master.aop.hibernate.OpenSessionInRequestInterceptor">
<level value="info" />
</logger>
<root>
<priority value="info"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE_ALL"/>
</root>
</log4j:configuration>
I don't think you need to define appender-ref in every a.b logger since it should pick up the appender from root. Also, I use priority instead of logger for root. Otherwise, your configuration looks identical to mine and I'm able to get mine working properly. If this doesn't work for you for some reason, I would suggest you to remove your custom a.b loggers from the configuration to see if you are able to get the a.b messages in your console.
Also, just FYI, I'm sure you already know this, but if your root is set to use "info", then there's really no need to set your custom a.b logger to "info" too. I usually leave my root to "warn" and have my custom loggers to override that with either "debug" or "info".
I found the solution even if not the problem directly. I added a parameter to my ConsoleAppender that everything is printed to the stderr. This now works. I guess its a problem of eclipse or log4j because if i am starting the app from the terminal (console) I can see all log messages properly.
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.err" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-4r (%F:%L) %-5p %x - %m%n" />
</layout>
</appender>

Categories