How the logging is happening in this scenario - java

I don't have a much knowledge in log4j and slf4j. But I want to understand how the actual logger is working in the below case.
I have a Web module,Service module and a Dao module.Web module has a dependency to Service and Service has a dependency to Dao .
In my web module there are 3 jars. slf4j jar, log4j jar and slf4j-log4j12 jar and log4j.xml is as below.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<!-- ============================== -->
<!-- Append messages to the console -->
<!-- ============================== -->
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="C:\\temp\\web.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%t] %d{HH:mm:ss,SSS} %-5p %l - %m%n" />
</layout>
</appender>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<!--
Set the root logger priority via a system property. Note this is parsed by log4j
-->
<level value="trace" />
<appender-ref ref="CONSOLE"/>
</root>
<logger name="com.mywork">
<level value="DEBUG" />
<appender-ref ref="FILE" />
</logger>
<logger name="org.hibernate">
<level value="ERROR" />
<appender-ref ref="FILE" />
</logger>
<logger name="org">
<level value="ERROR" />
<appender-ref ref="FILE" />
</logger>
</log4j:configuration>
And In my service module and dao module contain only slf4j jar. And logging details are in file.(logging details of all modules)
Should the loggers of hibernate and Spring also available in my file ?
How the exception occur are available in logger file?
Thank you

You explicitly constrain org.* with ERROR level.
This effectively eliminates almost all output of hibernate and spring loggers.
But exceptions logged with error level should still get to file log.
Module dependencies configured in IDE are irrelevant. Logging happens in JBoss container and depends only on actual application's runtime classpath.
BTW, I highly recommend against trace level on root category.
See Production settings file for log4j? for the explanation.

Related

log4j.xml configuration is not storing logs to file

I have the following log4j.xml configuration file, but don't see the log data stored in the file specified (in my documents folder: Documents/debug.log).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="true">
<appender name="applicationLogFile" class="org.apache.log4j.RollingFileAppender">
<param name="DatePattern" value="'.'yyyyMMdd'.log'" />
<param name="File" value="Documents/debug.log" />
<param name="threshold" value="TRACE" />
<param name="MaxNumberOfDays" value="90"/>
<param name="CompressBackups" value="TRUE"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c] %m%n" />
</layout>
</appender>
<logger name="APP_VERSION_LOGGER">
<appender-ref ref="applicationVersionFile" />
</logger>
<logger name="org.springframework">
<level value="WARN" />
</logger>
<root>
<priority value="DEBUG" />
<appender-ref ref="applicationLogFile" />
<appender-ref ref="bmcAlertFile" />
</root>
</log4j:configuration>
How an I get my log data sent to my Documents directory on my computer? I'm using log4j-core version 2.13.3. And yes, I've looke at the docs, but I still don't see where my log data is going.
Your line here says:
<param name="File" value="Documents/debug.log" />
It will make a folder with name Documents on your project root level and logs will be there.
I f you want to put them in to specific location on your machine then you need to provide full pathname.
ex.
<param name="File" value="/Users/myUser/Documents/debug.log" />

Jetty: Debug logging for specific Java class not working

I am working on a Spring-MVC application in which I am using Jetty as our application server. I want to debug log a specific java class, but even after enabling log4j or slf4j, and adding files it's not working.
Finally, I created a war file, added to start log4j with this command java -jar start.jar --add-to-start=logging-log4j, which created a log4j.xml file in resources directory. In that log4j.xml, I added the class I want to debug, but no [DEBUG] entries are getting added.
Enabled modules :
log4j2-slf4j.mod
slf4j-log4j2.mod
slf4j-api.mod
logging-slf4j.mod
I have also tried their combinations and different loggings as documentation suggested.
log4j.xml present in resources directory of both IDE and Jetty.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- console appender -->
<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{1} - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelMatchFilter">
<param name="LevelToMatch" value="INFO" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender>
<logger name="com.zaxxer.hikari" additivity="false">
<level value="DEBUG" />
<appender-ref ref="console" />
</logger>
<root>
<priority value="ERROR" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
What am I doing wrong?
It seems that the problem is that you have only bridges and not log4j itself in the classpath.
As requested a simple logback.xml config file:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<logger name="test" level="DEBUG" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

How to create different files for logger hierarchy in tomcat?

In my Tomcat application, I want to use two loggers to log general event informations and errors to two different files.
Logger eventLogger = Logger.getLogger("event");
Logger errorLogger = Logger.getLogger("error");
Now I want to do the following: the logs of the eventLogger should be written to a "events.log" file, and the errorLogger logs should be written in a "errors.log" file. All logs from any other logger (e.g. Tomcat logs) should be written to catalina.out (or any other default file).
How can I achive this with JULI? Or do I need a third party lib?
This can't be achieved with Juli. You might use log4j.
Basically you need appenders. They will manage the logs to go to separate files. Example configuration in xml:
<?xml version="1.0"?>
<!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.EnhancedPatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%t][%c{1}:%L] %m%n" />
</layout>
</appender>
<appender name="eventFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="#tomcat.home#/logs/event.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<appender name="errorFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="#tomcat.home#/logs/error.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<logger name="event" additivity="false">
<level value="INFO" />
<appender-ref ref="eventFILE" />
</logger>
<logger name="error" additivity="false">
<level value="INFO" />
<appender-ref ref="errorFILE" />
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="FILE" />
</root>
</log4j:configuration>
you have to define an appender for each file in your log4j.xml and connect them to your loggers:
<?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="%d{ISO8601} %5p [%c.%M:%L] - %m%n" />
</layout>
</appender>
<appender name="FILE-error" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/error.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="ImmediateFlush" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %5p [%c.%M:%L] - %m%n" />
</layout>
</appender>
<appender name="FILE-event" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/event.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="ImmediateFlush" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss};%m%n" />
</layout>
</appender>
<!-- Loggers -->
<logger name="error" additivity="false">
<level value="warn" />
<appender-ref ref="FILE-error" />
</logger>
<logger name="event" additivity="false">
<level value="info" />
<appender-ref ref="FILE-event" />
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="FILE-error" />
</root>
</log4j:configuration>
Tomcat documentation does not provide any way to define more than one file per application when using JULI. Actually it provides the steps to use log4j instead of it because JULI configuration can be too basic.
But again this configuration is at container level:
Note: The steps described in this section are needed when you want to
reconfigure Tomcat to use Apache log4j for its own logging. These
steps are not needed if you just want to use log4j in your own web
application. — In that case, just put log4j.jar and log4j.properties
into WEB-INF/lib and WEB-INF/classes of your web application.
So using a third party library is the logical choice and you can find how to configure it in this SO post
Tomcat JULI logging supports this only via the logging.properties located in the ${catalina.base}/config folder.
#Declares the handlers allowed for use.
handlers = 100catalina.org.apache.juli.FileHandler, 200catalina.org.apache.juli.FileHandler, 300catalina.org.apache.juli.FileHandler
#Install the 'all' hander on the root logger.
.handlers=300catalina.org.apache.juli.FileHandler
#Install the 'event' handler on the 'event' logger and don't report to root.
event.handlers=100catalina.org.apache.juli.FileHandler
event.useParentHandlers=false
#Install the 'error' handler on the 'error' logger and don't report to root.
error.handlers=200catalina.org.apache.juli.FileHandler
error.useParentHandlers=false
#Event handler settings.
100catalina.org.apache.juli.FileHandler.level = ALL
100catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
100catalina.org.apache.juli.FileHandler.prefix = event.
#Error handler settings.
200catalina.org.apache.juli.FileHandler.level = ALL
200catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
200catalina.org.apache.juli.FileHandler.prefix = error.
#Root handler settings.
300catalina.org.apache.juli.FileHandler.level = ALL
300catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
300catalina.org.apache.juli.FileHandler.prefix = all.
This config will not work if you try to install this file in the WEB-INF/classes/logging.properties. This is because the ClassLoaderLogManager doesn't allow you to install handlers on named loggers.

Using log4j.xml, log specific file or package at debug everything else at error

I'd like to setup my log4j.xml file to log specific classes/packages at DEBUG level and the rest at ERROR level.
As you can see below I updated the logging level to info for gov.xxxx.app.batch.thread and gov.xxxx.app.batch.sms.DoWork to info.
However it looks like the threshold takes precedence (which makes sense).
Is there a way to make it so that the class/package level config takes precedence over the threshold? Or another approach that would yield the desired result?
log4j.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="threshold" value="all"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern" value="%d %p %c %L - %m%n"/>
</layout>
</appender>
<appender name="logFile" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${app.batchdriver.home}/logs/${app.batchdriver.log.name}"/>
<param name="maxFileSize" value="5MB"/>
<param name="maxBackupIndex" value="20"/>
<param name="threshold" value="error"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="conversionPattern" value="%d %p %c %L - %m%n"/>
</layout>
</appender>
<!-- Logger for Batch classes -->
<logger name="gov.xxxx.app">
<level value="error"/>
</logger>
<!-- Logger for Spring classes -->
<logger name="org.springframework">
<level value="error"/>
</logger>
<!-- Logger for Hibernate classes -->
<logger name="org.hibernate">
<level value="error"/>
</logger>
<!-- Logger for Apache classes -->
<logger name="org.apache">
<level value="error"/>
</logger>
<!-- Logger for Apache classes -->
<logger name="net.sf">
<level value="error"/>
</logger>
<!-- Logger for testing Performance -->
<logger name="gov.xxxx.app.batch.thread">
<level value="info"/>
</logger>
<logger name="gov.xxxx.app.batch.sms.DoWork">
<level value="info"/>
</logger>
<root>
<priority value ="all" />
<appender-ref ref="console"/>
<appender-ref ref="logFile"/>
</root>
</log4j:configuration>
If I understand your requirements correctly you want to log:
everything to console
errors to logFile + INFO logs from specific packages
If that is the case you need to do following:
remove threshold (or make it INFO) on logFile appender
remove <appender-ref ref="logFile"/> from root logger because root logger specifies "all" and you do not want that
add to all loggers which you want to see in logFile

Why is the root logger collecting all log types regardless the configuration?

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.
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>
The root logger resides at the top of the logger hierarchy. It is exceptional in three ways:
it always exists,
its level cannot be set to null
it cannot be retrieved by name.
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 the root logger, then all enabled logging requests will at least print on the console. If in addition a file appender is added to a logger, say L, then enabled logging requests for L and L's children will print on a file and on the console. 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:
<logger name="org.springframework.ws.server.endpoint.interceptor"
additivity="false">
<level value="DEBUG" />
<appender-ref ref="payloadAppender" />
</logger>
In standard log4j config style (which I prefer to XML):
log4j.logger.org.springframework.ws.server.endpoint.interceptor = INFO, payloadAppender
log4j.additivity.org.springframework.ws.server.endpoint.interceptor = false
Hope this helps.
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.
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.
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.
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.

Categories

Resources