Log4j使用

场景如下:

由于项目要做一个统计分析与记录的功能,为了后期分析用户的一些行为,同时记录的东西要同时输出多处,并且可配置输出

想到了使用log4j,知道他是可以同时指定多个输出目的地,并且如有变更,直接修改配置文件。

问题一:把登录用户每次访问的ip地址时间等记录下来,存放到日志文件里,再存一份到数据库

Java代码

publicclassUserLogFilterimplementsFilter{

privateLoggerlogger;

@Override

publicvoiddestroy(){

//TODOAuto-generatedmethodstub

}

@Override

publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,

FilterChainchain)throwsIOException,ServletException{

HttpServletRequesthttpRequest=(HttpServletRequest)request;

Objectuser=httpRequest.getSession().getAttribute(

Constants.User.LOGIN_USER);

if(user!=null){

Integerusr_id=(Integer)ReflectionUtils.invokeGetterMethod(user,"usrId");

Stringlog_ip=request.getLocalAddr();

SimpleDateFormatformat=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");

Datenow=newDate(System.currentTimeMillis());

MDC.put("usr_id",usr_id);

MDC.put("log_title","网站访问记录");

MDC.put("log_type","记录");

MDC.put("log_title","网站访问记录");

MDC.put("log_datetime",format.format(now));

MDC.put("log_ip",log_ip);

logger.info(MDC.getContext());

}

chain.doFilter(request,response);

}

@Override

publicvoidinit(FilterConfigfilterConfig)throwsServletException{

logger=Logger.getLogger(UserLogFilter.class);

}

}

第二部:配置log4j.properties,输出到文件与数据库

引用

#不懂的话,参考给出的第一个连接地址一样,j2EE项目详细控制

log4j.logger.com.bhaman.yiyaosou.util.web=INFO,,project-util,project-util-db

#project-util-webfileappender

log4j.appender.project-util=org.apache.log4j.DailyRollingFileAppender

log4j.appender.project-util.file=${user.home}/logs/project-util.log

log4j.appender.project-util.layout=org.apache.log4j.PatternLayout

log4j.appender.project-util.threshold=INFO

log4j.appender.project-util.layout.conversionPattern=%d[%X{usr_id}/%X{log_ip}/%X{req.id}-%X{entranceMethod}-%X{req.requestURIWithQueryString}]%-5p%c-%m%n

log4j.appender.project-util-db=com.log4j.service.DBAppender

log4j.appender.project-util-db.bufferSize=16

log4j.appender.project-util-db.threshold=INFO

#此处对应filter里面的MDC里面的键值对,你懂的

log4j.appender.project-util-db.sql=insertintouser_log(usr_id,log_title,log_category,log_type,log_datetime,log_ip)VALUES('%X{usr_id}','%X{log_title}','%X{log_type}','%X{log_title}','%X{log_datetime}','%X{log_ip}')

第三部:由于log4j里面给出的输出JDBCappender,是有问题的,首先面对业务需求,他是用JDBC,性能上问题很大,特别是现在这个应用。log4j支持自己写appender

直接看JDBCAppender的源码

如下里面提到有做了缓冲,两个ArrayList,一个来存东西,一个来控制清零后默认的缓冲大小不变,具体看源码,配置文件可以直接配置初始化大小

Java代码

<p>Eachappendcalladdstoan<code>ArrayList</code>buffer.When

thebufferisfilledeachlogeventisplacedinasqlstatement

(configurable)andexecuted.

<b>BufferSize</b>,<b>dbURL</b>,<b>User</b>,&<b>Password</b>are

configurableoptionsinthestandardlog4jways.

<p>The<code>setSql(Stringsql)</code>setstheSQLstatementtobe

usedforlogging--thisstatementissenttoa

<code>PatternLayout</code>(eithercreatedautomaticlybythe

appenderoraddedbytheuser).Thereforebydefaultallthe

conversionpatternsin<code>PatternLayout</code>canbeused

insideofthestatement.(seethetestcasesforexamples)

protectedintbufferSize=1;

/**

*ArrayListholdingthebufferofLoggingEvents.

*/

protectedArrayListbuffer;

/**

*Helperobjectforclearingoutthebuffer

*/

protectedArrayListremoves;

里面执行的sql,连接url什么的就是配置文件里面配置,,会在调用的时候set进来

Java代码

protectedStringdatabaseURL="jdbc:odbc:myDB";

/**

*Usertoconnectasfordefaultconnectionhandling

*/

protectedStringdatabaseUser="me";

/**

*Usertousefordefaultconnectionhandling

*/

protectedStringdatabasePassword="mypassword";

那么我自己写的appender继承它就好了,直接使用它的缓冲及sql执行,那么唯一要变的就是连接了。

我要从连接池里面取出,怎么做呢?看下面源码中注释-->>

引用

<li>Override<code>getConnection()</code>topassanyconnection

youwant.Typicallythisisusedtoenableapplicationwide

connectionpooling.

<li>Override<code>closeConnection(Connectioncon)</code>--if

youoverridegetConnectionmakesuretoimplement

<code>closeConnection</code>tohandletheconnectionyou

generated.Typicallythiswouldreturntheconnectiontothe

poolitcamefrom.

<li>Override<code>getLogStatement(LoggingEventevent)</code>to

producespecializedordynamicstatements.Thedefaultusesthe

sqloptionvalue.

我不需要覆写getLogStatement,我想改变的只是连接的获取方式罢了,如上分析后,直接写我的appender,里面用到了高效的BoneCP连接池,在spring里面本来是有配置这个的,但log4j是独立于spring的,是无法获取到,只能自己再来一份

Java代码

publicclassDBAppenderextendsorg.apache.log4j.jdbc.JDBCAppender{

privateBoneCPconnectionPool=null;

privateConnectionconnection=null;

privatestaticLoggerlogger=Logger.getLogger(DBAppender.class);

publicDBAppender(){

//设置连接池配置信息

BoneCPConfigconfig=newBoneCPConfig();

PropetiesUtilp;

try{

PropertiesP=newProperties();

P.load(DBAppender.class.getClassLoader().getResourceAsStream("application.properties"));

//数据库的JDBCURL

config.setJdbcUrl(P.getProperty("jdbc.url"));

//数据库用户名

config.setUsername(P.getProperty("jdbc.username"));

//数据库用户密码

config.setPassword(P.getProperty("jdbc.password"));

//数据库连接池的最小连接数

config.setMinConnectionsPerPartition(5);

//数据库连接池的最大连接数

config.setMaxConnectionsPerPartition(10);

config.setPartitionCount(1);

//设置数据库连接池

connectionPool=newBoneCP(config);

}catch(SQLExceptione){

//TODOAuto-generatedcatchblock

logger.error("连接池配置加载异常",e);

}catch(IOExceptione){

//TODOAuto-generatedcatchblock

logger.error("加载配置文件IO异常",e);

}

//fetchaconnection

}

@Override

protectedConnectiongetConnection()throwsSQLException{

if(connection==null||connection.isClosed()){

connection=connectionPool.getConnection();

}

returnconnection;

}

@Override

protectedvoidcloseConnection(Connectioncon){

//TODOAuto-generatedmethodstub

try{

connection.close();

connection=null;

}catch(SQLExceptione){

//TODOAuto-generatedcatchblock

logger.error("连接没正常关闭",e);

}

}

}

第四步:一切OK,然后就测试

日志文件:

引用

2011-07-2111:07:01,125[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:07:01,log_title=网站访问记录,usr_id=282}

2011-07-2111:07:03,640[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:07:03,log_title=网站访问记录,usr_id=282}

2011-07-2111:07:04,796[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:07:04,log_title=网站访问记录,usr_id=282}

2011-07-2111:07:08,906[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:07:08,log_title=网站访问记录,usr_id=282}

2011-07-2111:07:09,281[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:07:09,log_title=网站访问记录,usr_id=282}

2011-07-2111:07:14,531[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:07:14,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:10,984[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:10,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:11,796[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:11,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:22,078[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:22,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:22,875[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:22,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:28,562[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:28,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:30,250[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:30,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:31,390[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:31,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:32,750[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:32,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:33,781[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:33,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:36,156[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:36,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:41,578[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:41,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:43,156[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:43,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:44,968[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:44,log_title=网站访问记录,usr_id=282}

2011-07-2111:11:48,765[282/127.0.0.1/--]INFOcom.bhaman.yiyaosou.util.web.UserLogFilter-{log_type=记录,log_ip=127.0.0.1,log_datetime=2011-07-2111:11:48,log_title=网站访问记录,usr_id=282}

数据库:

第五步:

比如现在系统要记录登录用户与非登录用户各个时间段得访问与访问连接数,最后跟购买行为统计挂上钩,进行数据挖掘,但现在又改变需求,还要分析登录用户里面的各种级别的用户等

系统里面需要统计分析的东西很多的话,怎么解决?难道配置各种filter然后输出两地?本来太多的fiter就会带来性能问题,多了岂不是?

大范围记录一次到日志文件,然后写job从任务文件里面分析出数据然后写入数据库于日志文件。

相关推荐