zoukankan      html  css  js  c++  java
  • Java学习笔记(十九)——Java 日志记录 AND log4j

    【前面的话】

          学习的进度应该稍微在快一点。

          Java日志到了必须学习怎么使用的时候了,因为在项目中要进行使用。基础性文章,选择性阅读。

    【结构】

         java日志对调试,记录运行,问题定位都起到了很重要的作用,一般常用的日志框架有:

    1. sf4j
    2. commons-logging
    3. log4j
    4. JDK自带logging
    5. 其他日志框架

    【定义】

         记录日志:一般在最开始写代码的时候总是会在代码中加入一些System.out.println方法的语句来观察代码运行的情况。这样需要反复加入和修改,日志API就是为了解决这个问题。

         java.util.logging包就是JDK的日志开发包。

         Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

         好处

    1. 可以很容易的取消全部日志记录,或者仅仅取消某个级别的日志,而且打开和关闭这个操作也很容易。
    2. 可以很简单地禁止日志记录的输出,因此,将这些日志代码留在程序中所付出的代价很小。
    3. 日志记录可以被定向到不同的处理器,用于在控制台中显示,用于存储在文件中。
    4. 日志记录器和处理器都可以对记录进行过滤。过滤器可以根据过滤实现器制定的标准丢弃那些无用的记录项。
    5. 日志记录可以采用不同的方式格式化。如:纯文本或者XML。
    6. 应用程序可以使用多个日志记录器,他们使用类似包名的这种具有层次结构的名称,如:com.mycompany.myapp。
    7. 在默认情况下,日志系统的配置由配置文件控制,如果需要的话,应用程序可以替换这个配置。

    JDK自带logging

    一、 日志级别 

    级别

    意义

    等级

    OFF

    这个日志级别比较特殊,用来关闭日志

     

    SEVERE

    系统比较严重的错误级别,一般是无法恢复的bug

    最高

    WARNING

    警告提示

     

    INFO

    普通信息输出

     

    CONFIG

    静态配置信息输出,如cpu,mem

     

    FINE

    FINE,FINER,FINEST三个日志级别都是用来跟踪日志信息,输出信息的详细程度依次递增

     

    FINER

     

    FINEST

    最低

    ALL

    所有的日志信息都输出

     

    在默认情况下,只记录前面三个级别。也可以设置级别如下:

    1 logger.setLevel(Level.ALL);

    二、例子

         1. 代码

     1 import java.util.logging.ConsoleHandler;
     2 import java.util.logging.Level;
     3 import java.util.logging.Logger;
     4 
     5 public class LoggerTest {
     6     public static void main(String []args){    
     7         Logger logger =Logger.getLogger("cn.cc.ccc");
     8     /*    ConsoleHandler handler=new ConsoleHandler();
     9         handler.setLevel(Level.ALL);
    10         logger.addHandler(handler);*/
    11         logger.setLevel(Level.ALL);
    12         logger.severe("严重错误");
    13         logger.warning("警告信息");
    14         logger.info("普通输出");
    15         logger.config("配置信息");
    16         logger.fine("日志信息");
    17         logger.finer("日志信息");
    18         logger.finest("日志信息");
    19     }
    20 }

        2. 结果:

    1 四月 10, 2014 4:48:55 下午 LoggerTest main
    2 严重: 严重错误
    3 四月 10, 2014 4:48:55 下午 LoggerTest main
    4 警告: 警告信息
    5 四月 10, 2014 4:48:55 下午 LoggerTest main
    6 信息: 普通输出

       3. 问题:

           进行了等级设置以后为什么不能输出下面的几个级别的信息?也就是为什么没有输出:

    1 四月 10, 2014 4:44:43 下午 LoggerTest main
    2 配置: 配置信息
    3 四月 10, 2014 4:44:43 下午 LoggerTest main
    4 详细: 日志信息
    5 四月 10, 2014 4:44:43 下午 LoggerTest main
    6 较详细: 日志信息
    7 四月 10, 2014 4:44:43 下午 LoggerTest main
    8 非常详细: 日志信息

        4. 原因:

            默认规定只能输出到INFO级别,我们没有修改配置文件,也就是使用了默认的配置。有两种修改方式,

            一种是修改.properties文件(本文没有实现),默认情况下配置文件存在于:jre/lib/logging.properties

            第二种是安装一个新的ConsoleHandler,如下代码:

     1 import java.util.logging.ConsoleHandler;
     2 import java.util.logging.Level;
     3 import java.util.logging.Logger;
     4 
     5 public class LoggerTest {
     6     public static void main(String []args){    
     7         Logger logger =Logger.getLogger("cn.cc.ccc");
     8         ConsoleHandler handler=new ConsoleHandler();
     9         handler.setLevel(Level.ALL);
    10         logger.addHandler(handler);
    11         logger.setLevel(Level.ALL);
    12         logger.severe("严重错误");
    13         logger.warning("警告信息");
    14         logger.info("普通输出");
    15         logger.config("配置信息");
    16         logger.fine("日志信息");
    17         logger.finer("日志信息");
    18         logger.finest("日志信息");
    19     }
    20 }

        结果

     1 四月 10, 2014 4:44:43 下午 LoggerTest main
     2 严重: 严重错误
     3 四月 10, 2014 4:44:43 下午 LoggerTest main
     4 严重: 严重错误
     5 四月 10, 2014 4:44:43 下午 LoggerTest main
     6 警告: 警告信息
     7 四月 10, 2014 4:44:43 下午 LoggerTest main
     8 警告: 警告信息
     9 四月 10, 2014 4:44:43 下午 LoggerTest main
    10 信息: 普通输出
    11 四月 10, 2014 4:44:43 下午 LoggerTest main
    12 信息: 普通输出
    13 四月 10, 2014 4:44:43 下午 LoggerTest main
    14 配置: 配置信息
    15 四月 10, 2014 4:44:43 下午 LoggerTest main
    16 详细: 日志信息
    17 四月 10, 2014 4:44:43 下午 LoggerTest main
    18 较详细: 日志信息
    19 四月 10, 2014 4:44:43 下午 LoggerTest main
    20 非常详细: 日志信息

    log4j

         再学习一个常见的日志框架,log4j。先看个例子。

    一、例子

         1. LoggerTest.java

     1 import java.util.logging.Level;
     2 
     3 import org.apache.log4j.Logger;
     4 
     5 public class LoggerTest {
     6     public static void main(String []args){
     7         //获取Logger实例,参数为本类
     8         Logger logger=Logger.getLogger(LoggerTest.class);
     9         logger.debug("debuging");//输出一段DEBUG信息
    10         logger.info("info..."); //输出一段INFO信息
    11         logger.error("error..."); //输出一段ERROR错误信息
    12         logger.fatal("fatal");
    13         logger.warn("warn");
    14         }
    15     }

        2. log4j.properties

    1 #此属性指定日志等级等于或低于INFO的日志信息输出到名为stdout的目的地
    2 log4j.rootCategory=INFO, stdout
    3 #此属性执行stdout这个输出目的地类型为控制台
    4 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    5 #此属性指定输出日志的布局类,这里采用LOG4J默认的布局类
    6 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

        3. 结果

    1 info...
    2 error...
    3 fatal
    4 warn

        4. 注意事项

        需要把log4j-1.2.16.jar导入

    二、log4j的结构

    (一) log4j的构成

    1. 根目录(级别和目的地);
    2. 目的地(控制台、文件等等);
    3. 输出样式。

    (二) log4j包含类的意义

    1. Logger - 日志写出器,供程序员输出日志信息
    2. Appender - 日志目的地,把格式化好的日志信息输出到指定的地方去
    3. ConsoleAppender - 目的地为控制台的Appender
    4. FileAppender - 目的地为文件的Appender
    5. RollingFileAppender - 目的地为大小受限的文件的Appender
    6. Layout - 日志格式化器,用来把程序员的logging request格式化成字符串
    7. PatternLayout - 用指定的pattern格式化logging request的Layout

    三、.properties配置信息

          Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。

          在.properties进行配置的时候,也是针对日志信息的优先级,日志信息的输出目的地,日志信息的输出格式进行配置。

          1. 配置根Logger

          例子中,properties文件中的第一句就是配置这个。

    1 log4j.rootLogger = level,appenderName1,appenderName2, ···

         其中,level 是日志记录的优先级,分为OFFFATALERRORWARNINFODEBUGALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。 appenderName就是指B日志信息输出到哪个地方。您可以同时指定多个输出目的地。优先级:ALL < DEBUG < INFO <WARN < ERROR < FATAL < OFF

         2. 配置日志信息输出目的地Appender

    1 log4j.appender.appenderName = Log4j提供的appender类
    2 log4j.appender.appenderName.属性名 = 属性值
    3 ···
    4 log4j.appender.appenderName.属性名 = 属性值

         其中,Log4j提供的appender有以下几种:

    1 org.apache.log4j.ConsoleAppender(控制台),
    2 org.apache.log4j.FileAppender(文件),
    3 org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
    4 org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
    5 org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

         1) ConsoleAppender选项

             Threshold=WARN:指定日志消息的输出最低层次。

             ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。

             Target=System.err:默认情况下是:System.out,指定输出控制台

        2) FileAppender 选项

            Threshold=WARN:指定日志消息的输出最低层次。

            ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。

            File=mylog.txt:指定消息输出到mylog.txt文件。

            Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。

        3) DailyRollingFileAppender 选项

           Threshold=WARN:指定日志消息的输出最低层次。

           ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。

           File=mylog.txt:指定消息输出到mylog.txt文件。

           Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。

           DatePattern=''.''yyyy-ww:每周滚动一次文件,即每周产生一个新的文件。

           当然也可以指定按月、周、天、时和分。即对应的格式如下:

    • ''.''yyyy-MM: 每月
    • ''.''yyyy-ww: 每周
    • ''.''yyyy-MM-dd: 每天
    • ''.''yyyy-MM-dd-a: 每天两次
    • ''.''yyyy-MM-dd-HH: 每小时
    • ''.''yyyy-MM-dd-HH-mm: 每分钟

        4) RollingFileAppender 选项

           Threshold=WARN:指定日志消息的输出最低层次。

           ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。

           File=mylog.txt:指定消息输出到mylog.txt文件。

           Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。

           MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件。

           MaxBackupIndex=2:指定可以产生的滚动文件的最大数。

        3. 配置日志信息的格式(布局)

    1 log4j.appender.appenderName.layout = Log4j提供的layout类 
    2 log4j.appender.appenderName.layout.属性 =3 •••
    4 log4j.appender.appenderName.layout.属性 = 值 Log4j 

           其中,Log4j提供的layout有以下几种:

    1 org.apache.log4j.HTMLLayout(以HTML表格形式布局), 
    2 org.apache.log4j.PatternLayout(可以灵活地指定布局模式), 
    3 org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串), 
    4 org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

        1) HTMLLayout选项

            LocationInfo=true:默认值是false,输出java文件名称和行号

            Title=my app file: 默认值是 Log4J Log Messages.

        2) PatternLayout选项

            ConversionPattern=%m%n :指定怎样格式化指定的消息。

        3) XMLLayout选项

            LocationInfo=true:默认值是false,输出java文件和行号

            Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:

    1 og4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n 

           这里需要说明的就是日志信息格式中几个符号所代表的含义:

           -X号: X信息输出时左对齐;

          %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,

          %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,

           比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

          %r: 输出自应用启动到输出该log信息耗费的毫秒数

          %c: 输出日志信息所属的类目,通常就是所在类的全名

         %t: 输出产生该日志事件的线程名

         %l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及行数。

         举例:Testlog4.main(TestLog4.java:10)

         %x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。

         %%: 输出一个"%"字符

         %F: 输出日志消息产生时所在的文件名称

         %L: 输出代码中的行号

         %m: 输出代码中指定的消息,产生的日志具体信息

         %n: 输出一个回车换行符,Windows平台为" ",Unix平台为" "输出日志信息换行

         可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如:

    • %20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
    • %-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。
    • %.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
    • %20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边交远销出的字符截掉

    四、xml配置信息

          详细内容见例子:

          1. LoggerTest.java

     1 import org.apache.log4j.Logger;
     2 
     3 public class LoggerTest {
     4     private static final Logger log = Logger.getLogger(LoggerTest.class);
     5     public static void main(String[] args) {
     6         log.info("Enter the main()....");
     7         log.debug("Enter the main()....");
     8         log.warn("Enter the main()....");
     9         log.info("Enter the main()....");
    10         System.out.println("this is a log4j test.");
    11         log.info("log end.");
    12     }
    13 }

         2. log4j.xml

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
     3 <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
     4 
     5     <!-- ========================== 自定义输出格式说明================================ -->
     6       <!-- %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL -->
     7       <!-- %r 输出自应用启动到输出该log信息耗费的毫秒数  -->
     8       <!-- %c 输出所属的类目,通常就是所在类的全名 -->
     9       <!-- %t 输出产生该日志事件的线程名 -->
    10       <!-- %n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n” -->
    11       <!-- %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921  -->
    12       <!-- %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)  -->
    13       <!-- ========================================================================== -->
    14 
    15       <!-- ========================== 输出方式说明================================ -->
    16       <!-- Log4j提供的appender有以下几种:  -->
    17       <!-- org.apache.log4j.ConsoleAppender(控制台),  -->
    18       <!-- org.apache.log4j.FileAppender(文件),  -->
    19       <!-- org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件), -->
    20       <!-- org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),  -->
    21       <!-- org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)   -->
    22   <!-- ========================================================================== -->
    23   <!-- 输出到日志文件  -->
    24   <!-- 设置通道file和输出方式:org.apache.log4j.RollingFileAppender -->  
    25   <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
    26      <!-- 设置File参数:日志输出文件名 -->  
    27      <param name="File" value="D:/logxml/test_log4j_debug.log"/>
    28      <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->  
    29      <param name="Append" value="true"/>
    30      <param name="MaxFileSize" value="5KB"/>
    31      <param name="MaxBackupIndex" value="2"/>
    32      <layout class="org.apache.log4j.PatternLayout">
    33         <!-- 设置输出文件项目和格式 -->  
    34         <param name="ConversionPattern" value="%c %d{ISO8601}-- %p -- %m%n"/>
    35      </layout>
    36      <filter class="org.apache.log4j.varia.LevelRangeFilter">
    37         <param name="LevelMin" value="DEBUG"/>
    38         <param name="LevelMax" value="DEBUG"/>
    39      </filter>
    40   </appender>
    41   <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
    42      <layout class="org.apache.log4j.PatternLayout"> 
    43         <param name="ConversionPattern" value="%c %d{ISO8601}-- %p -- %m%n"/>
    44      </layout>
    45      <filter class="org.apache.log4j.varia.LevelRangeFilter">
    46         <param name="LevelMin" value="INFO"/>
    47         <param name="LevelMax" value="INFO"/>
    48      </filter>
    49   </appender>
    50   <root>
    51      <priority value="debug"/>  
    52      <appender-ref ref="FILE" /><!-- 与前面的通道id相对应 -->  
    53      <appender-ref ref="STDOUT" />  
    54   </root>
    55 </log4j:configuration>

         3. 运行结果:

            在控制台中输出结果:

    1 LoggerTest 2014-04-11 16:20:17,683-- INFO -- Enter the main()....
    2 LoggerTest 2014-04-11 16:20:17,684-- INFO -- Enter the main()....
    3 this is a log4j test.
    4 LoggerTest 2014-04-11 16:20:17,684-- INFO -- log end.

           在D:/logxml/test_log4j_debug.log输出结果:

    1 LoggerTest 2014-04-11 16:20:17,684-- DEBUG -- Enter the main()....

    【参考资料】

       1. java日志详解

       2. J​A​V​A​应​用​开​发​日​志​解​决​方​案

       3. log4j入门、详解

    【后面的话】

        好好学习。

    ——TT

  • 相关阅读:
    English 2
    速算24点
    心理学1
    从微服务到函数式编程
    034 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 01 流程控制概述
    033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结
    032 01 Android 零基础入门 01 Java基础语法 03 Java运算符 12 运算符和if-else条件语句的综合案例——闰年问题
    031 01 Android 零基础入门 01 Java基础语法 03 Java运算符 11 运算符的优先级
    030 01 Android 零基础入门 01 Java基础语法 03 Java运算符 10 条件运算符
    029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑“非”运算符
  • 原文地址:https://www.cnblogs.com/xt0810/p/3659045.html
Copyright © 2011-2022 走看看