Why my log4j slf4j log once only when tomcat initialize war file? - java

My environment:
CAS 4.0.0 project
dependencies
slf4j-log4j12-1.7.5
log4j-1.2.17
slf4j-api.1.7.5
(Whole process in remote debug) when the tomcat initialize the webapp, in DatasourceWrapper, logger does log(i checked). But the problem is the logger does not log after webapp initialized.
My java file
package sg.com.innovax;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbcp.BasicDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DatasourceWrapper extends BasicDataSource implements Serializable
{
private static final long serialVersionUID = 4139847655780946796L;
private Logger logger = LoggerFactory.getLogger(getClass());
#Override
public Connection getConnection() throws SQLException
{
logger.debug("Number of active connections:" + super.getNumActive());
logger.info("Number of idle connections:" + super.getNumIdle());
logger.error("Number of max active:" + super.getMaxActive());
return super.getConnection();
}
#Override
public Connection getConnection(String username, String password) throws SQLException
{
logger.debug("Number of active connections:" + super.getNumActive());
logger.info("Number of idle connections:" + super.getNumIdle());
logger.error("Number of max active:" + super.getMaxActive());
return super.getConnection(username, password);
}
}
my xml
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true" xmlns:log4j="http://jakarta.apache.org/log4j/">
<!--
This default ConsoleAppender is used to logger all NON perf4j messages
to System.out
-->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %p [%c] - <%m>%n"/>
</layout>
</appender>
<appender name="cas" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="cas123.log" />
<param name="MaxFileSize" value="512KB" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
</layout>
</appender>
<!-- Perf4J appenders -->
<!--
This AsyncCoalescingStatisticsAppender groups StopWatch logger messages
into GroupedTimingStatistics messages which it sends on the
file appender defined below
-->
<appender name="CoalescingStatistics" class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
<param name="TimeSlice" value="60000"/>
<appender-ref ref="fileAppender"/>
<appender-ref ref="graphExecutionTimes"/>
<appender-ref ref="graphExecutionTPS"/>
</appender>
<!-- This file appender is used to output aggregated performance statistics -->
<appender name="fileAppender" class="org.apache.log4j.FileAppender">
<param name="File" value="perfStats.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n"/>
</layout>
</appender>
<appender name="graphExecutionTimes" class="org.perf4j.log4j.GraphingStatisticsAppender">
<!-- Possible GraphTypes are Mean, Min, Max, StdDev, Count and TPS -->
<param name="GraphType" value="Mean"/>
<!-- The tags of the timed execution blocks to graph are specified here -->
<param name="TagNamesToGraph" value="DESTROY_TICKET_GRANTING_TICKET,GRANT_SERVICE_TICKET,GRANT_PROXY_GRANTING_TICKET,VALIDATE_SERVICE_TICKET,CREATE_TICKET_GRANTING_TICKET,AUTHENTICATE" />
</appender>
<appender name="graphExecutionTPS" class="org.perf4j.log4j.GraphingStatisticsAppender">
<param name="GraphType" value="TPS" />
<param name="TagNamesToGraph" value="DESTROY_TICKET_GRANTING_TICKET,GRANT_SERVICE_TICKET,GRANT_PROXY_GRANTING_TICKET,VALIDATE_SERVICE_TICKET,CREATE_TICKET_GRANTING_TICKET,AUTHENTICATE" />
</appender>
<!-- Loggers -->
<!--
The Perf4J logger. Note that org.perf4j.TimingLogger is the value of the
org.perf4j.StopWatch.DEFAULT_LOGGER_NAME constant. Also, note that
additivity is set to false, which is usually what is desired - this means
that timing statements will only be sent to this logger and NOT to
upstream loggers.
-->
<logger name="org.perf4j.TimingLogger" additivity="false">
<level value="INFO" />
<appender-ref ref="CoalescingStatistics" />
</logger>
<!--
WARNING: Setting the org.springframework logger to DEBUG displays debug information about
the request parameter values being bound to the command objects. This could expose your
password in the logger file. If you are sharing your logger files, it is recommend you selectively
apply DEBUG level logging on a an org.springframework.* package level (i.e. org.springframework.dao)
-->
<logger name="org.springframework">
<level value="WARN" />
</logger>
<logger name="org.springframework.webflow">
<level value="WARN" />
</logger>
<logger name="org.jasig" additivity="true">
<level value="INFO" />
<appender-ref ref="cas" />
</logger>
<logger name="com.github.inspektr.audit.support.Slf4jLoggingAuditTrailManager">
<level value="INFO" />
<appender-ref ref="cas" />
</logger>
<!--
WARNING: Setting the flow package to DEBUG will display
the parameters posted to the login servlet including
cleartext authentication credentials
-->
<logger name="org.jasig.cas.web.flow" additivity="true">
<level value="INFO" />
<appender-ref ref="cas" />
</logger>
<logger name="sg.com.innovax">
<level value="INFO" />
<appender-ref ref="cas" />
</logger>
<!--
The root logger sends all logger statements EXCEPT those sent to the perf4j
logger to System.out.
-->
<root>
<level value="ERROR" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
another xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<description>
Log4J initialization. Configuration options are sourced from cas.properties. This allows deployers to externalize
both cas.properties and log4j.xml, so that a single cas.war file can be deployed to multiple tiers or hosts without
having to do any post configuration. This approach helps to preserve configuration between upgrades.
Deployers should not have to edit this file.
</description>
<bean id="log4jInitialization" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
p:targetClass="org.springframework.util.Log4jConfigurer" p:targetMethod="initLogging" p:arguments-ref="arguments"/>
<util:list id="arguments">
<value>${log4j.config.location:classpath:log4j.xml}</value>
<value>${log4j.refresh.interval:60000}</value>
</util:list>
</beans>
My datasourceWrapper in sg.com.innovax, and i do specify in log4j
<logger name="sg.com.innovax">
<level value="INFO" />
<appender-ref ref="cas" />
</logger>
then it should be able to log in cas.log, however when i check from netbeans output, it show the error info in apache tomcat.

Related

How to understand log4j.xml file

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

log4j not writing messages to file

Looked at quite a few examples on this and have seen some confusing stuff. Here is the log4j.xml file
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<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>
</appender>
<appender name="file" class="org.apache.log4j.RollingFileAppender">
<param name="append" value="false" />
<param name="maxFileSize" value="1000KB" />
<param name="maxBackupIndex" value="5" />
<!-- For Tomcat -->
<param name="file" value="${catalina.home}/logs/demandManage.log" />
<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="com.xxx.demand.domain.data" additivity="true">
<level value="debug" />
<appender-ref ref="file"/>
</logger>
<logger name="com.xxx.rita.serviceserver.controller.AbstractRestController" additivity="true">
<level value="debug" />
<appender-ref ref="file"/>
<appender-ref ref="console" />
</logger>
<logger name="com.xxx.dao.AbstractDAOImpl" additivity="true">
<level value="debug" />
<appender-ref ref="file"/>
<appender-ref ref="console" />
</logger>
<logger name="org.hibernate" >
<level value="warn" />
<appender-ref ref="file"/>
</logger>
<root>
<priority value ="warn" />
<appender-ref ref="console" />
<appender-ref ref="file"/>
</root>
</log4j:configuration>
In my java class:
package com.xxx.dao;
public abstract class AbstractDAOImpl<T, ID extends Serializable> implements AbstractDAO<T,ID>{
private Logger logger = LoggerFactory.getLogger(com.xxx.dao.AbstractDAOImpl.class);
#SuppressWarnings("unchecked")
public T read(ID id){
T response = (T) getCurrentSession().get(clazz, id);
if(response==null){
logger.error(RiskTaker.name.get()+ " tried to load " + clazz + " of " +id);
throw new RuntimeException("hibernate object did not exist");
}
return response;
}
}
So when I am hitting the logger.error message with this configuration, nothing is going to the demandManage.log file or the console. I don't see what's wrong. When I had root set to debug, hibernate of course practically fills up that log file so it does work.
Is there a difference between using level vs priority? Like a slfj4 vs appache logger? The root sets priority but the child loggers are using level.
I am starting tomcat in debug mode and know I am hitting those logger.error statements but the file remains empty. May be I need to flush to it right away?
I previously had the logger in the xml file as fully qualified and in the java class as just class name only but fixing that did nothing. I am wondering what I am missing. Thank you in advance.

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.

Send Log4J INFO to database and DEBUG to Console?

I have com.mycompany.library.*
I want DEBUG go to console, and INFO go to DB. how I can achieve it?
this is part of my log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="false"
xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- APPENDERS LIST -->
<!-- show log entries on console -->
<appender name="ConsoleApp" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} [%-5p][%-16.16t][%32.32c] - %m%n" />
</layout>
</appender>
<appender name="DBAppender" class="org.apache.log4j.jdbc.JDBCAppender">
<param name="URL" value="jdbc:postgresql://localhost:5432/myDB" />
<param name="driver" value="org.postgresql.Driver" />
<param name="user" value="postgres" />
<param name="password" value="password" />
<param name="sql"
value="INSERT INTO logs(user_id, dated,logger,lev,message) VALUES('%t', '%d{yyyy-MM-dd HH:mm:ss}','%-50c{3}','%p','%m')" />
</appender>
<logger name="com.mycompany">
<level value="INFO" />
<appender-ref ref="DBAppender" />
</logger>
<logger name="com.mycompany.library">
<level value="DEBUG" />
<appender-ref ref="ConsoleApp" />
</logger>
<root>
<priority value="ERROR" />
<appender-ref ref="DBAppender" />
</root>
</log4j:configuration>
With this config:
INFO and DEBUG goes to console. But Also INFO and DUBUG with double entries go to DB.
I want that to DB goes events with INFO level(and higher), not DEBUG. How to do that?
You can set a treshold on your appenders (not on the loggers). For instance:
<appender name="std-out" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">...</layout>
<param name="Threshold" value="info"/>
</appender>
See http://wiki.apache.org/logging-log4j/LogByLevel
edit: You also don't have to set an appender on both the com.mycompany logger and the root logger. This is why you have duplicate entries, because they are treated as additive (so at the level of com.mycompany, you essentially have 2 DB appenders).
Just set DBAppender on root and remove it from the com.mycompany logger.

Categories