• java 调试


    使用log

    System.out.println() 有很大的不足之处, 当程序调试结束后, 将这个程序投入产品化时, 往往需要消除 System.out.println()的输出, 这时候可能需要逐行扫描, 麻烦.

    log4j 是一个功能强大, 简单易用的日志工具, 因此 log4j 除了可用于辅助调试之外, 还可用于记录程序的运行日志.  log4j 已经可以支持 c, c++, c#, perl, python 等等.

    1. 下载和安装 log4j

    http://logging.apache.org/log4j/ 下载后解压, 看到如下文件结构:

    • examples: 该文件夹下包含了 log4j 的一些使用范例.
    • site: 该文件夹下包含了 log4j 官方站点的相关页面, 包括 log4j的API文档
    • src: 该文件夹下包含了log4j 的源代码.
    • tests: 该文件夹下包含了 log4j 的一些测试用例.
    • log4j-1.2.15.jar: 这个JAR包就是log4j项目的核心工具包.
    • 其他一些杂项文件.

    最简单的做法是将 log4j-1.2.15.jar 添加到系统的 CLASSPATH环境变量中, 以后即可在程序中使用 log4j日志工具包. 或者将log4j-1.2.15.jar核心类库添加到应用的类的加载路径里, 如WEB应用, 将 log4j-1.2.15.jar添加到WEB-INF/lib路径下即可.

    2. Logger

    Logger 是 log4j 最重要一个组件, 它代表一个日志输出器, 其功能有点类似 System.out的功能, 也就是说, 在程序中通过 Logger即可进行输出, Logger比 System.out更强大的地方在于, 它可以自由的关闭部分一些调试信息的输出, 而不影响其他人得调用.

    为了让 Logger 能关闭部分调试信息的输出而不影响其他人, Logger必须对日志进行分类控制,  log4j 里 Logger 的分类是通过它的名字来控制的,Logger 的名字是一个区分大小写的, 形如 org.crazyit.empsys.Manager 的字符串.

    在程序中得到一个Logger非常简单, Logger提供了如下两个静态方法来获得 Logger对象.

    • static Logger getLogger(java.lang.Class clazz): 以clazz类的类名作为 Logger的名字创建Logger, 该方法的本质是 getLogger(clazz.getName())
    • static Logger getLogger(java.lang.String name): 创建一个名为 name 的 Logger 对象.

    从上面介绍不难看出, Logger 的名字与 Java 包名的集成关系非常相似, 这一点是 log4j 故意设计的. 通过这种方式控制 Logger 之间的继承关系, 例如 名为 org 的 Logger 是名为 org.crazyit的祖先

    log4j 还提供了一个根(root) Logger, 它是所有 Logger 的祖先, 根具有两个特征:

    • 根 Logger 总是存在的
    • 程序不能通过使用字符串名字得到根, 只能通过Logger的静态方法 getRootLogger 来得到根.

    得到对象之后, 可以通过 5 个方法执行输出

    • public void debug(Object message, [Throwable t]): 以 debug 级别输出 message 信息, 如果传入了 t 参数, 还会输出 t 的跟踪栈信息.
    • public void info(Object message, [Throwable t]):
    • public void warn(Object message, [Throwable t]):
    • public void error(Object message, [Throwable t]):
    • public void fatal(Object message, [Throwable t]):

    从上面可以看出, Logger 执行输出时, 涉及到一个级别问题. log4j 为上面 5 个方法提供了 5 个对应的级别, 它们的优先级从低到高依次为: DEBUG<INFO<WARN<ERROR<FATAL

    与此同时, log4j准许调用Logger的setLevel(Level level) 方法设置自身的级别, 例如: logger.setLevel(level.DEBUG);

    log4j 制定了一个规则: 只有当Logger的输出方法的级别高于或等于 Logger 本身的级别时, 这条输出语句才会生成真正的输出. 示例如下:

    Logger logger = Logger.getLogger("com.foo");

    logger.setLevel(Level.INFO);  // 设置 Logger 本身的优先级别 INFO

    logger.warn("www.crazyit.org");  // 这条输出语句生成输出, 因为 WARN > INFO

    logger.debug("www.cryzit.org");  // 这条输出语句不会输出, 因为 DEBUG < INFO

    使用 Logger 输出调试信息只要3隔步骤,

    1) 调用 Logger 的 getLogger() 静态方法返回一个 Logger对象

    2) 使用 setLevel()方法设置 Logger的级别

    3) 使用 Logger 的 debug(), info(), warn(), error(), fatal() 方法输出信息.

    如果程序每次都需要通过3个步骤来执行输出, 那 log4j 只比 System.out 稍微灵活一点, 当程序需要关闭某批调试输出时, 将它们对应的 Logger 的 level 设置的更高即可. 但是这样也不很好.

    为此, log4j 又制定了一个规则: 如果程序没有为某个 Logger 显示指定其 level, 它将继承离它最近的祖先的 level.

    程序无需为每个 Logger 显示设置 level, 如果想控制一批 Logger 的信息输出, 可以控制这批 Logger 的最顶层 Logger 的 level 即可.

    为了便捷地控制每个类中得 Logger, 习惯上将每个 Logger的名称设为与当前类的类名相同. 例如: Logger log = Logger.getLogger(EmpManager.class);

    假如 EmpManager 类位于 org.crazyit.salary.service 包下, 那这个 Logger 的名字就是 org.crazyit.salary.service.EmpManager.

    3. Appender 和 Layout

    log4j 可以将日志输出到各种设备, 例如控制台, 文件, GUI组件, 远程 Socket 服务器 等, 而且可以将日志输出到多个输出设备中.

    log4j 使用 Appender 来代表日志信息的输出目的,

    ConsoleAppender: 输出到控制台

    DailyRollingFileAppender: 输出到文件的 Appender. 等等很多.

    Logger 提供了一个 addAppender() 方法用于将指定 Appender 添加为与 Logger 关联. 默认情况下, 每个Logger关联的Appender是其所有祖先Logger关联的Logger和它自己关联的 Appender的总和.

    Layout 是指输出的式样

    HTMLLayout: 控制日志输出成 HTML 格式的 Layout.

    XMLLayout, PatternLayout(字符串),SimpleLayout(简单日志信息)

    4. 使用 log4j 输出

    实际开发中使用 log4j 时几乎不会再 java 代码中定义 Logger, Appender 和 Layout, 而通常都回采用配置文件来管理, log4j 准许以下两种格式的配置文件.

    Properties 属性文件格式的配置文件, 通常配置文件名为 log4j.properties

    xml 格式的配置文件, 通常配置文件名为 log4j.xml

    不管使用那种文件, 配置的方法都是一样的. 配置以下 3 个部分.

    配置一个或多个 Logger, 这些 Logger 用于控制输出

    还需要配置一个或多个 Appender, Appender 代表日志的输出设备, 配置 Appender 时需要制定使用的 Layout

    将 Logger 和 一个或多个 Appender 进行关联.

    例如: log4j.xml

    <?xml version="1.0" encoding="gdk" ?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
        <!-- 定义输出到控制台的 Appender -->
        <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
            <!-- 定义该 Appender 对应的 Layout -->
            <Layout class="org.apache.log4j.PatternLayout">
                <param name="ConversionPattern"
                            value="===CRAZYIT.ORG=== %r %d [%t] %-p %c %x - #%l# - %m%n"/>
            </layout>
        </appender>
    <!-- 该logger将对 lee 包及其所有子包之内的 Logger 起作用 -->
    <logger name="lee">
        <!-- 输出 debug 及更高级别的日志 -->
        <level value=“debug”/>
        <!-- 将日志输出到控制台 -->
        <appender-ref ref="stdout"/>
    </logger>
    <!-- 制定日志级别, 引用那些 Appender -->
    <root>
        <!-- 输出 info 及其更高级别的日志 -->
        <level value="info"/>
        <appender-ref ref="stdout"/>
    </root>
    </log4j:configuration>

    然后就可以在程序中直接使用 logger.debug("开始执行程序");

    其他方法

    1. 利用编译器的提示信息

    2. 跟踪程序的执行流程

    3. 断点调试 ( IDE 提供, 比如 eclipse )

    4. 隔离调试 (将一部分代码注释掉)

    5. 调试的基本思路( 分段调试 )

  • 相关阅读:
    ftp下载显示进度
    Java 类加载器(转)
    Java中的Enum的使用与分析
    Iterator的remove方法可保证从源集合中安全地删除对象(转)
    [置顶] 关于我
    Java实现 蓝桥杯 算法提高 周期字串
    Java实现 蓝桥杯 算法提高 学霸的迷宫
    Java实现 蓝桥杯 算法提高 上帝造题五分钟
    Java实现 蓝桥杯 算法提高 上帝造题五分钟
    Java实现 蓝桥杯 算法提高 周期字串
  • 原文地址:https://www.cnblogs.com/moveofgod/p/3784893.html
Copyright © 2020-2023  润新知