Java程序调试与日志进阶

 

概述

本文根据作者的开发经验叙述了对Java程序调试和日志的认识和理解。介绍了System.out.println System.out.printf,手工制作的小工具类SysUtils.loglog4jlogback

引言

Java开发中,除了IDE提供的调试工具之外,监控代码中变量变化,跟踪代码运行有很多种方法:

1、招之即来的System.out.println

System.out.println无疑是最方便的,受众也是最广,知名度最高。Java学习者往往从第一个HelloWorld的例子开始就接触它,学习Java的人应该没有人不知道它。

示例代码:

System.out.println(sql);

System.out.println("My name is " + name + " I am " + age + " years old.");

优点是显而易见的,缺点也不少,如:

只能输出到控制台;

大量的代码混在业务逻辑中,在生产环境中需要处理这些影响性能的代码。

字符串拼接容易带来性能损失(当然可以使用StringBuffer,但又稍显繁琐)

2Java5System.out.println的改进:System.out.printf

         转向JavaC程序员无比怀念C语言中的printfJava5也对此提供了支持,Java也开始为开发者着想了,看代码:

    System.out.println(sql);

    System.out.printf("My name is %S I am %d years old.", name, age);

 

C程序员对此最熟悉不过了,无论是可读性和效率都比上面的好很多,唯一的缺点就是需要Java 5 的支持。

3、土制的utils小工具

         System.out.println,带来的最大问题是从开发环境向生产环境转换时带的性能问题(当然其它的问题也不少),部署时应该去除或注释这些代码,。

         解决这个问题最好的办法是土制一个小工具类,look:

public class SysUtils {

  public static final void log(Object o) {

     System.out.println("==" + String.valueOf(o));

  }

}

以后的调试代码全部调用上面的静态方法,代码如下:

SysUtils.log(sql);

SysUtils.log("My name is " + name + " I am " + age + " years old.");

 

部署的时候,只要把SysUtils.log里的System.out.println 注释掉就万事大吉了。

4、进阶过程,日志小知识

然而一切似乎还是没有改变,功能太弱,和代码耦合性太强...于是日志(log)出现了。日志,源于log,有航海日志的意思。指记录海员记录每天的行程,生活及发生的事件。在软件开发领域,用来监控代码中变量变化,跟踪代码运行的轨迹,在开发环境中担当调试器作用,向控制台或文件输出信息,运行环境中记录程序的警告和错误信息。

    Java开源牛人们为了改变现状,不断开发出各种各样的日志工具,于是Java程序员受苦了,不得不在各种日志间转换奔波。

然而天下大事,分久必合,合久必分。于是乎commons-logging出现了。它提供了日志统一的接口和一个最简单的实现。Java程序员幸福了,因为只需要针对接口编程。而不管到底由谁来实现。

 

    最著名的几个实现有:

Simplelog:最简单的实现。

    Juljava.util.loggingJDK中自带的日志实现

log4jApache Software Foundation开发的非常强大的日志实现

 

log主要有几个个概念:

输出级别:是调试信息,信息,还是警告,错误,致命错误等

输出目的地:输出到控制台,文件,可写设备,还是数据库

输出格式和内容:输出哪些东西,如何排版等。

 

5log4J

         Log4J的意思是Log for Java4for的简写,当然也读作 for

 

         Log4J的输出级别:

Log4j建议只使用四个级别,优先级从高到低分别是ERRORWARNINFODEBUG

Log4J的输出目的地:

                  ConsoleAppender(控制台)        

FileAppender(文件)  

DailyRollingFileAppender(每天产生一个日志文件)

RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

WriterAppender(将日志信息以流格式发送到任意指定的地方)

甚至能输出到数据库

         Log4J的输出格式:

HTMLLayout(以HTML表格形式布局)

PatternLayout(可以灵活地指定布局模式)

SimpleLayout(包含日志信息的级别和信息字符串)

TTCCLayout(包含日志产生的时间、线程、类别等等信息)

         Log4J的输出内容:

                   Log级别

                   类名

                   线程名

                   时间

                   位置等等。

         强大到足以在开发环境或生产环境做一切你能想到的记录。

 

         Log4JJava Web项目中的使用方法:

1.       commons-logging.jar log4.jar扔到lib目录

2.       log4j.properties文件扔到classes根目录

3.       OK了。

 

示例代码:

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

 

public class TestLog {

    Log log = LogFactory.getLog(TestLog.class);

    public void print() {

       if (log.isDebugEnabled()) {

           log.debug (sql);

           log.debug ("My name is " + name + " I am " + age + " years old.");

       }

    }

}

 

6slf4jlogback,没有最好,只有更好

log4j经过这么久的发展,从外面看,经典,庄重,强壮,从内部看,却充满了代码的坏味道。就连它的作者也认为应该有一个更好的日志框架。于是,再次操刀,创建了slf4j来取代jcl,创建了logback来取代log4j

目前,log4jjul应用最为广泛,slf4j作为新兴的抽象层,整合logback,以其简洁,快速,正被越来越多的顶级项目使用。如大名鼎鼎的hibernateJetty

参见:http://www.slf4j.org/

        

十个转移到logback的理由http://logback.qos.ch/10reasons.ppt

 

     slf4j支持参数化的logger.error("帐号ID{}不存在" userId);告别了if(logger.isDebugEnable()) 时代。

 

     另外logback的整体性能比log4j也较佳,hibernate等项目已经采用了slf4j:

 

     "某些关键操作,比如判定是否记录一条日志语句的操作,其性能得到了显著的提高。这个操作在LOGBack中需要3纳秒,而在Log4J中则需要30 秒。 LOGBack创建记录器(logger)的速度也更快:13毫秒,而在Log4J中需要23毫秒。更重要的是,它获取已存在的记录器只需94纳秒,而 Log4J需要2234纳秒,时间减少到了1/23"

 

Slf4j    相当于commons-logging 提供了一系列的日志接口

Logback相当于 log4j                        提供了强大的实现

 

作者也称Logback是可靠,通用,快速,灵活的java日志工具(官方描述)。

 

commons-logging slf4j的代码比较:

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class TestLogBySlf4J {

    Logger logger = LoggerFactory.getLogger(TestLogBySlf4J.class);

    public void print() {

       logger.debug(sql);

       logger.debug("My name is {} I am {} years old.", name, age);

    }

}

 

依稀又有了一点Java5的影子。

 

项目选择的思考。

如果是简单的项目,如小工具,小Demo等,采用System.out.printf , 土制工类,jul,都是不错的选择。

 

如果是web开发,宜采用log4j,因为系统已经有了很多的配置文件,不在乎多一个,而且功能强大。公司目前很多项目采用log4j

 

如果是较新的项目,可采用slf4j,在学习成本不高的情况下,获得更好的架构,灵活性和性能。

小结

限于篇幅,本文只简要介绍了从原始的内置类到简单的封装,再到Log4j,再到强大的logback的进阶过程和主要示例代码,中间细节请查阅官方详细的文档。

参考资料

Slf4j官方网站(http://www.slf4j.org/)

Logback官方网站(http://logback.qos.ch/)


Jcl
官方网站(http://commons.apache.org/logging/)


Log4j
官方网站(http://logging.apache.org/)

SpringSide 官方wikihttp://wiki.springside.org.cn/)。

 

Java日志系统研究(http://yanboy.javaeye.com/blog/204436

 

关于作者

kimsoft

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值