您的位置:首页 > 其它

关于log4j在实际工作中使用的一些想法

2013-11-06 18:20 363 查看
近来在做部门的开发技术支持,但是在解决问题的过程中,发现一个很苦逼的事情。。。。就是日志各种混乱。

由于其部分模块,是多条任务线并行处理的,所以,打印日志时,一条任务线在打印日志时,不同类中的方法被调用时打印的日志,可能会被其他线程打印的日志分隔开N行。。查询起来,非常痛苦。。








高亮部分为所需日志信息。

因此,我想到,对于这种大量并行的,拥有一条主线索的日志记录,可以用另一个打印方式—就是在任务开始时,用LoggerFactory.getLogger(“任务ID”)获取logger对象。

这样的话,每个活动的日志,都可以用一个简单的 “grep
任务ID ” ,就抽取出来了,非常便于查看。

例:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleLog4jTest {
public static void main(String[] args) {
int thrednum = 3;
Logger[] ls = new Logger[thrednum];
for(int a = 0; a < thrednum ; a++){
ls[a] = LoggerFactory.getLogger("我是活动"+ a);
new Thread(new Tlog41(LoggerFactory.getLogger("我是活动"+ a))).start();
}
//TODO 序列化 log对象,下个还可以用。。。不一定需要。
//		场景: ccms节点要流动的,但是如等待节点,时间节点,需要等待很久,可以将该logger对象序列化保存,然后下次继续使用
//	 	当然了。。如果要序列化保存logger对象的话,对象可以在logger基础上封装一层,保留更多的信息。
//		如果仅仅是logger对象,也可以在每次获取(LoggerFactory.getLogger("活动ID")) 时,将活动id从库中搜出,放入。
//		下部分代码可以运行,运行内容:
//		将上面的Logger对象序列化,等待20秒后,再反序列化后,使用其进行打印,打印信息中的name部分,仍为原name,及原活动ID。
//		for(int a = 0; a < thrednum ; a++){
//			try {
//				FileOutputStream fos = new FileOutputStream("c://" + "我是活动"+ a+ ".out");
//				ObjectOutputStream oos = new ObjectOutputStream(fos);
//				oos.writeObject(ls[a]);
//				oos.close();
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		}
//		try {
//			Thread.sleep(1000L);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//		System.err.println("序列化好了,你有9秒钟检查。。。");
//
//		try {
//			Thread.sleep(20000L);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//
//		for(int a = 0; a < thrednum ; a++){
//			try {
//				String path = "c://" + "我是活动"+ a+ ".out";
//				Logger s ;
//				FileInputStream fis = new FileInputStream(path);
//				ObjectInputStream ois = new ObjectInputStream(fis);
//				s = (Logger) ois.readObject();
//
//				new Thread(new Tlog41(s)).start();
//
//			} catch (Exception ex) {
//				ex.printStackTrace();
//			}
//		}
}
}
class Tlog41 implements Runnable{
private static int b = 0;
private int c = 0;
Logger logger = null;
public Tlog41(Logger logger){
this.logger = logger;
b++;
c = b;
}
@Override
public void run() {
for(int a = 0; a < 100 ; a++){
logger.info(a+ "我zhi dao 就是"+ a+ "试试afsdfkjsdlgkjd"+ "----"+ c);
try {
Thread.sleep(10L);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
if(c%2 ==0){
throw new Exception(" 要死。。出异常了。。。");
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
}


日志打印如下:



可以发现,名字清晰。。。

这样,一条任务相关日志的抽取,会非常容易。。。

也便于后期,做更规范的日志打印,使得日志成为一个更有效的监控和处理问题的手段(如在每次打印时,统一打印每次打印间的时间间隔,当然若要增强其功能,需要对logger对象进行一定的封装的。。)。

PS:每个线程其实就类似于每个方法,在调用方法时,传入logger对象。。进行打印。。

另外,就是,
LoggerFactory.getLogger(name
),在打印异常时,其实堆栈、类名、方法名及行数,其实已经都包含了,所以这个name根本就没必要再用类名这个信息了,而是应该用更有意义的内容,当做
name。


文章写的比较乱。。。从公司头脑风暴中,拉过来的,没有得到太多回应。希望在此找到有相同想法的朋友。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: