`

Java程序调试与日志进阶

    博客分类:
  • java
阅读更多
概述
本文根据作者的开发经验叙述了对Java程序调试和日志的认识和理解。介绍了System.out.println, System.out.printf,手工制作的小工具类SysUtils.log,log4j和logback。

引言
在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,但又稍显繁琐)

2、Java5对System.out.println的改进:System.out.printf
         转向Java的C程序员无比怀念C语言中的printf,Java5也对此提供了支持,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:最简单的实现。

    Jul:java.util.logging,JDK中自带的日志实现

log4j:Apache Software Foundation开发的非常强大的日志实现



log主要有几个个概念:

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

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

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



5、log4J
         Log4J的意思是Log for Java,4是for的简写,当然也读作 “for”



         Log4J的输出级别:

Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

Log4J的输出目的地:

                  ConsoleAppender(控制台)        

FileAppender(文件)  

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

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

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

甚至能输出到数据库

         Log4J的输出格式:

HTMLLayout(以HTML表格形式布局)

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

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

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

         Log4J的输出内容:

                   Log级别

                   类名

                   线程名

                   时间

                   位置等等。

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



         Log4J在Java 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.");

       }

    }

}



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

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

参见: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 官方wiki(http://wiki.springside.org.cn/)。



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



分享到:
评论

相关推荐

    Java语言程序设计.进阶篇(原书第8版)中文版

    - **异常链与日志记录**:讲解如何利用异常链来追踪问题根源,并结合日志记录机制提高系统的可维护性和可调试性。 #### 3. 高级数据结构与算法 - **集合框架深入**:详细介绍`Collection`、`Set`、`List`、`Map`等...

    JAVA高端进阶开发课程 JAVA应用程序调试技术 从实战角度出发学习JAVA应用程序调试.rar

    总的来说,这门"JAVA高端进阶开发课程"将全面覆盖Java应用程序调试的各个方面,不仅教授基础的调试技巧,还将深入探讨高级调试策略,包括并发调试、性能优化和复杂问题的解决方法。无论你是经验丰富的开发者还是初学...

    Java进阶路线

    ### Java进阶路线详解 #### 一、Java基础 **1. 传值与传引用** 在Java中,基本类型(如int、char等)的传递是按值传递的,而对象类型的传递则是按引用传递的。理解这一点对于正确处理变量和对象之间的交互至关...

    CRUD 程序猿的 Mybatis 进阶.rar

    10. **插件机制**:Mybatis 提供了插件机制,可以自定义拦截器来增强其功能,例如,日志插件、性能分析插件等,方便进行监控和调试。 通过学习《CRUD 程序猿的 Mybatis 进阶》,开发者可以掌握更多关于 Mybatis 的...

    java日志框架-sl4f

    日志在软件开发中起着至关重要的作用,它帮助开发者追踪程序运行时的问题,调试错误,以及记录系统活动。SL4J通过提供一个简单的API,使得开发者可以轻松地记录不同级别的日志信息,如ERROR、WARN、INFO、DEBUG和...

    资料-最新工作流引擎Activiti7基础与进阶.zip

    Activiti7提供了一套丰富的Java API,方便开发者在应用程序中调用,实现对流程的启动、查询、控制等操作。 7. 事件与监听器: Activiti7允许设置监听器来捕获流程中的特定事件,例如任务完成、流程结束等,从而...

    Java 程序 日记本

    Java程序日记本是一个用于记录和学习Java编程过程中遇到的问题、解决方案以及心得的资源集合。它可能包含了一系列关于Java编程的笔记、代码示例、调试技巧和项目实践等内容,旨在帮助开发者提升技能,解决实际问题。...

    2021 Java架构进阶 Nginx企业级教程【视频课程】下载整理.zip

    6. **故障排查与调试**:通过错误日志分析问题,以及Nginx的调试技巧。 【标签】中的"数据集 源代码 计算机资料 学习资料 python stm32 C语言 小程序 心梓知识"表明课程可能还包含其他领域的学习资源,如: 1. **...

    一些Spring的入门与进阶教程

    - 面向切面编程(AOP)允许我们定义横切关注点,如日志、事务管理等,然后在程序的特定点(切点)自动应用这些关注点,提高代码的复用性和可维护性。 2. **Spring中文教程**: - "spring中文教程pdf.pdf"可能涵盖...

    java程序实用教程

    8. **异常处理和日志记录**:学习如何正确使用异常处理和日志记录工具(如Log4j),对于调试和优化代码大有裨益。 9. **泛型**:Java的泛型提供了一种方式来限制容器可以存储的数据类型,增加了代码的类型安全性和...

    Java语言程序设计第8版 习题解答+例题程序

    《Java语言程序设计第8版 习题解答+例题程序》是一份全面解析Java编程学习的资源,针对Java初学者和进阶者都极具价值。这份资料包含了书中的所有习题答案以及配套的例题程序,旨在帮助读者深入理解和实践Java编程...

    Java程序设计实验报告(仅供学习参考)2.zip

    总之,这份"Java程序设计实验报告(仅供学习参考)2"涵盖了从基础到进阶的Java编程知识,是学习和提升Java技能的良好资料。通过阅读文档和分析代码,学习者不仅可以加深对Java语言的理解,还能培养解决问题和分析...

    Java核心技术 第八版 卷Ⅰ(基础篇)电子版

    9. **异常、日志、断言和调试**:介绍Java异常处理机制、日志记录的最佳实践、断言的使用方法以及调试技巧。 10. **泛型程序设计**:讨论泛型的基本概念及其在集合框架中的应用,提高代码的复用性和类型安全性。 11....

    Java经典编程300例(完整版+源码

    实例013 重定向输出流实现程序日志 实例014 自动类型转换与强制类型转换 实例015 加密可以这样简单(位运算) 实例016 用三元运算符判断奇数和偶数 .  实例017 不用乘法运算符实现2×16 实例018 实现两个变量的...

    java源码:Java聊天程序(JBuilder).rar

    9. **日志记录**:为了便于调试和问题追踪,良好的实践是在程序中加入日志记录,例如使用java.util.logging库。 10. **网络协议理解**:虽然这里的聊天程序可能简化了网络协议的使用,但了解TCP/IP协议的基本原理,...

    164个完整Java代码

    9. **异常调试与日志记录**:学习如何使用IDE进行代码调试和日志记录,是成为一名优秀开发者的关键步骤。初学者可以从中学习到断点设置、步进执行、变量查看等调试技巧,以及如何使用如log4j这样的日志框架。 10. *...

    新手入学Java编程基础

    【log4j】是Java日志框架之一,用于记录程序运行过程中的信息、警告和错误。正确地配置和使用log4j可以帮助开发者在调试和优化代码时获取有价值的日志信息,提高问题定位的效率。理解log4j的配置文件、日志级别和...

    java应用工程

    Java的输入/输出(IO)系统是程序与外部世界交互的关键。它提供了读取和写入文件、网络通信以及处理流的能力。Java IO API包括了InputStream和OutputStream作为基础抽象类,以及它们的子类如FileInputStream和...

    Spring进阶

    在Java程序中,对象之间的依赖关系常常导致复杂的管理问题。Spring通过DI解决了这个问题,允许开发者在运行时动态地将依赖关系注入到对象中,降低了代码的耦合度,提高了可测试性。通过XML配置、注解或Java配置,...

    JAVA聊天小程序(局域网和Internet上都可用)

    5. **文本编码**:考虑到聊天消息通常涉及文字,Java程序需要处理字符编码。通常,我们会使用UTF-8编码,以支持多种语言的字符。 6. **用户界面**:尽管描述中没有明确提及,但实现一个用户友好的界面是必要的。这...

Global site tag (gtag.js) - Google Analytics