log4j个人实践(mysql数据库)

版权声明:欢迎查看,随便复制! https://blog.csdn.net/hunhun1122/article/details/82117354

log4j干啥的不在细说。

一、先介绍log4j自带的两个类MDC和NDC作用以及用途。

NDC和MDC是log4j用于存储应用程序的上下文信息(context infomation),从而便于在log中使用这些上下文信息。

1、NDC采用了一个类似栈的机制来push存储上下文信息,每一个线程都独立地储存上下文信息。比如说一个servlet就可以针对每一个request创建对应的NDC,储存客户端地址等等信息。

相关的信息使用NDC.push(message);

在log的时候将信息输出。在相应的PatternLayout中使用”%x”来输出存储的上下文信息(

x要小写)

eg:

NDC.push("ipdizhi");

log4j.appender.console.layout.ConversionPattern=%-d{yyyy/MM/dd HH:mm:ss,SSS} [%x] -[%c]-[%p] %m%n

2、MDC内部使用了类似map的机制来存储信息。

相对应的方法,MDC.put(key, value);

在配置PatternLayout的时候使用:%x{key}来输出对应的value

MDC.put("ip", "ipdizhi"); 

log4j.appender.console.layout.ConversionPattern=%-d{yyyy/MM/dd HH:mm:ss,SSS} [%X{ip}] -[%c]-[%p] %m%n

二、log4j的使用方法(存储数据库)

1、新建个数据库表log4j存储数据

-- ----------------------------

DROP TABLE IF EXISTS `log4j`;

CREATE TABLE `log4j` (

`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,

`LogName` varchar(200) NOT NULL,

`UserName` varchar(200) NOT NULL,

`ip` varchar(255) NOT NULL,

`Class` varchar(200) NOT NULL,

`Mothod` varchar(200) NOT NULL,

`LogLevel` varchar(20) NOT NULL,

`CreateTime` datetime NOT NULL,

`MSG` varchar(500) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=516 DEFAULT CHARSET=utf8;

2、配置log4j的配置文件

log4j.rootLogger=db

log4j.appender.db=org.apache.log4j.jdbc.JDBCAppender

log4j.appender.db.layout=org.apache.log4j.PatternLayout

log4j.appender.db.driver=com.mysql.jdbc.Driver

#定义什么级别的错误将写入到数据库中

log4j.appender.database.Threshold=info,error,warn

#设置缓存大小,就是当有1条日志信息是才忘数据库插一次

log4j.appender.db.BufferSize=3

#数据库链接

log4j.appender.db.URL=jdbc:mysql://localhost:3306/cy_test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false

log4j.appender.db.user=root

log4j.appender.db.password=sasa

#数据库插入语句

log4j.appender.db.sql=insert into LOG4j (LogName,UserName,ip,Class,Mothod,createTime,LogLevel,MSG) values ('%X{userId}','%X{userName}','[%x]','%C','%M','%d{yyyy-MM-dd HH:mm:ss}','%p','%m')

3、使用

可以写个拦截器,进行拦截写入。

这里举个简单的栗子:

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.log4j.MDC;

import org.apache.log4j.NDC;

import org.junit.Test;

public class log4jtest {

Log logger = LogFactory.getLog(test.class);

@Test

public void dbtest() {

//MDC test

MDC.put("userId", "h333");

MDC.put("userName", "zhang");

//NDC test

NDC.push("17.3.3.2");

// 在具体方法中就可以写入日志

logger.info("33");

logger.warn("55");

logger.error("66");

}

}

三、一个请求过程中日志追踪

1、可以根据用户id在一段时间内的记录,进行预估排查。

2、在日志中增加一次请求标识

MDC.put("req.id",rund());。

在一次请求时增加一个id,在这个请求过程中所有日志进行一个标识。

四、分布式多系统日志追踪

这个可以看做是多个请求进行标识。

实现自定义Filter,在接受到http请求时,计算一个eventID并存储在MDC中。如果涉及分布式多系统,那么向其他子系统发送请求时,需要携带此eventID。

response.setHeader("eventsign", eventsign);

很有用,返回的response中,将有httpheader:eventsign:000010x1489108079237

请求时再携带获取 request.getHeader("eventsign").

五、拦截器举例举例:

拦截器:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

String eventsign;

if (request.getHeader("eventsign") == null || request.getHeader("eventsign").length() == 0) {

eventsign = this.sign + String.valueOf(new Date().getTime()); //计算eventID

logger.error("set eventid:" + eventsign);

} else {

eventsign = request.getHeader("eventsign");//从请求端获取eventsign

logger.error("get eventid from request:" + eventsign);

}

MDC.put("eventid", eventsign);

response.setHeader("eventsign", eventsign);

filterChain.doFilter(request, response);

}

六、总结:

根据个人系统的特点,合理设计字段以助于问题发现排查。

猜你喜欢

转载自blog.csdn.net/hunhun1122/article/details/82117354
今日推荐