关于log4j在实际工作中使用的一些想法
2013-11-06 18:20
363 查看
近来在做部门的开发技术支持,但是在解决问题的过程中,发现一个很苦逼的事情。。。。就是日志各种混乱。
由于其部分模块,是多条任务线并行处理的,所以,打印日志时,一条任务线在打印日志时,不同类中的方法被调用时打印的日志,可能会被其他线程打印的日志分隔开N行。。查询起来,非常痛苦。。
如
高亮部分为所需日志信息。
因此,我想到,对于这种大量并行的,拥有一条主线索的日志记录,可以用另一个打印方式—就是在任务开始时,用LoggerFactory.getLogger(“任务ID”)获取logger对象。
这样的话,每个活动的日志,都可以用一个简单的 “grep
任务ID ” ,就抽取出来了,非常便于查看。
例:
日志打印如下:
可以发现,名字清晰。。。
这样,一条任务相关日志的抽取,会非常容易。。。
也便于后期,做更规范的日志打印,使得日志成为一个更有效的监控和处理问题的手段(如在每次打印时,统一打印每次打印间的时间间隔,当然若要增强其功能,需要对logger对象进行一定的封装的。。)。
PS:每个线程其实就类似于每个方法,在调用方法时,传入logger对象。。进行打印。。
另外,就是,
文章写的比较乱。。。从公司头脑风暴中,拉过来的,没有得到太多回应。希望在此找到有相同想法的朋友。。。
由于其部分模块,是多条任务线并行处理的,所以,打印日志时,一条任务线在打印日志时,不同类中的方法被调用时打印的日志,可能会被其他线程打印的日志分隔开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。
文章写的比较乱。。。从公司头脑风暴中,拉过来的,没有得到太多回应。希望在此找到有相同想法的朋友。。。
相关文章推荐
- 关于select标签使用的一些想法
- 关于使用性能测试工具的一些想法和问题
- 关于NandFlash在实际产品使用上的一些经验
- 关于2017开始的新工作想法与一些学习进步方向还有些阶段目标
- 关于项目中要使用thymeleaf的一些想法
- 关于布局的一些使用想法
- 关于在工作中使用dubbo和zookeeper的一些理解
- 关于NSDate的一些实际工作遇到的坑
- 关于工作的一些想法
- 分享关于平板电视的一些使用、选购经验和想法。
- wangchenxicool 关于NandFlash在实际产品使用上的一些经验
- 关于CListCtrl 实际项目中的一些简单使用
- 关于NandFlash在实际产品使用上的一些经验
- 关于UML使用和学习的一些想法
- 关于程序员工作的一些想法
- 关于互联网的一些观点想法
- 关于使用SuperMap以及开发中一些问题的解决方法。
- 在Android中使用adb命令时关于权限方面的一些总结
- 关于ExpressQuantumGrid4的cxGrid的一些使用方法
- ThinkPHP关于模板的一些嵌套、IF判断使用