天天看点

【JavaSE入门系列】第21章_浅述Log4J第21章浅述Log4J——v512工作室   编辑:玄玉

完整版见 https://jadyer.github.io/

第21章浅述Log4J——v512工作室   编辑:玄玉

核心 Layout log4j.xml 我的博客
基本用法 Logger log4j.properties v512工作室
下载使用 Appender log4j对性能的影响 中科院新科海学校

为什么要使用日志log

开发阶段:发现程序问题并排错

产品阶段:记录程序运行的状况

补充说明:日志在软件开发中是非常重要的功能,很多系统程序都需要日志处理系统

                     我们可以自己开发这样的系统,也可以使用已有的日志处理系统

                     比如Log4j就是非常好的一个日志处理系统

System.out.println的局限性

                 不能在运行时打开或者关闭这个功能//说明①

                 不能选择包或者类,在运行的时候打开或者关闭//说明②

                 输出的信息没有分级//说明③

                 只能输出文本信息,不能改变输出的位置//说明④

                 Log4j可以解决以上问题//说明⑤

说明①:我们可能希望println在某刻输出日志信息,在另外的时候我们可能希望它不输出,我们就想随时能关闭或打开这个日志信息的输出

                 如果没有额外的代码帮助它的话,那么println是比较难实现的

说明②:就是说要么就都输出一些日志信息要么就不输出。若想针对某些类或某些包当中的类的日志信息输出,那么通过println的方式是无法设定的

说明③:也就是说一般的排错信息或紧急的信息等都是不分级的,所有的信息都是一同输出的

说明④:若想把这些文本信息保存在物理文件中,通过println是无法实现的

                 再者若想把它输出到终端上还想把它保存在文本文件或者数据库中的话,直接使用println是实现不了的,必须自己再写另外的代码才能实现

说明⑤:Log4j使用上非常简单,只要配置一下,在使用它的API上也是比较简单。很多著名开源系统都使用Log4j做为它们的日志处理系统,如Hibernate

log4j可以免费下载使用:http://logging.apache.org/log4j

Log4j是最流行的Java日志处理框架,是Apache的子项目,是开源软件

下载log4j的API类库:2.0正处于开发阶段,1.3已经被终止,所以下载1.2版本

                                        Download→Mirrors→apache-log4j-1.2.15.zip。然后解压出log4j-1.2.15.jar

                                        再把log4j-1.2.15.jar的路径添加到当前项目的Build Path下或者系统的CLASSPATH中

添加Log4j的类库:项目右键→Build Path→Configure Build Path→Libraries→Add External JARs→log4j-1.2.15.jar→OK

新建Log4j配置文件:项目里的src右键→New→File→File name为log4j.properties→Finish

编辑Log4j配置文件:文件名log4j.properties上右键→Text Editor

Log4j的基本用法

import org.apache.log4j.Logger;

public class HelloLog4j {

        private static Logger logger=Logger.getLogger(HelloLog4j.class);

        //生成log4j的一个Logger类型的对象logger

        //调用Logger的一个静态的getLogger方法传当前类的名字HelloLog4j.class

        //这样就可以通过logger完成日志信息的记录

        public static void main(String[] args) {

                logger.debug("This is debug message.");

                logger.info("This is info message.");

                logger.error("This is error message.");}}

运行这个例子,需要log4j.properties,它可以设置日志输出的格式即外观。还可以设置日志信息输出的位置(终端或物理文件等)

默认的系统会自动寻找log4j.properties,若没找到,则会试图寻找log4j.xml

log4j.properties内容如下:

        log4j.rootLogger=debug,appender1<!--设置我们的log4j输出级别是debug-->

        log4j.appender.appender1=org.apache.log4j.ConsoleAppender<!--指明日志信息到哪里去处理,这里是到终端进行输出-->

        log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout<!--TTCCLayout是它输出的日志信息的样式-->

最后运行HelloLog4j.java输出内容如下:

        [main] DEBUG com.v512.log4j.HelloLog4j - This is debug message.

        [main] INFO com.v512.log4j.HelloLog4j - This is info message.

        [main] ERROR com.v512.log4j.HelloLog4j - This is error message.

        main代表的是main方法

        DEBUG、INFO、ERROR代表日志输出的级别

        com.v512.log4j.HelloLog4j是日志信息所在的类,后面就是日志的信息

说明:使用log4j可以设置日志输出的级别。debug、info、error三者的级别是依次递增的

             而且输出的内容只能是比log4j.properties里设置的级别要高的级别才能输出

             比如把log4j.properties中第一行的debug改为info,那么运行HelloLog4j.java后则只会输出INFO和ERROR的信息

这种级别对于实际开发的好处:开发阶段输出的信息与产品阶段输出的信息或者说记录的日志信息是有很大区别的

                                                           开发的时候我们要跟踪程序运行的情况,要求输出的日志信息要非常的详细

                                                           但是如果产品已经部署到服务器了,交付给用户使用了,那么我们可能不需要用户看到很详细的信息

                                                           因为这些(侦错信息)对用户来讲可能是没有用的,我们只要把一些很严重的错误信息输出或记录下来

                                                           要实现这样的目的,在开发中可以把级别(比如debug)设置的很低,在交付给用户的时候可以把级别设置的高一些

把日志信息保存在文件中:将log4j.properties第二行最后面的ConsoleAppender改为FileAppender

指定日志保存的文件位置:log4j.appender.appender1.File=c:\demolog4j.log(保存在C盘根目录下的demolog4j.log中)

                                                   这时运行HelloLog4j.java后终端是不会输出内容的而是自动把日志信息保存在c:\demolog4j.log中

设定日志文件输出的样式:TTCCLayou指输出文本样式。HTMLLayout指输出HTML样式(这时保存的文件名后缀同时改为.htm)

log4j核心

Logger:完成日志信息的处理

Appender:设置日志信息的去向(终端、文件或数据库中)

Layout:设置日志信息的输出样式(包含当前线程、类的情况、行号以及执行到该位置的时间等等)

配置文件:log4j.properties或log4j.xml(前者用的更多些)

Logger可以定义输出的层次和决定信息是否输出

Logger输出的信息是有优先级别的:ALL,TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF(级别依次递增,红色为常用级别)

DEBUG输出一些错误信息。INFO输出一些日常记录的信息。WARN输出警告信息。当程序出错时使用ERROR输出

Logger示例:log.debug("X="+X);(首先要定义一个Logger类型的对象log)

                         log.info("System started at"+new Date());

                         log.warn("Server down - returning");

                        log.error("Could not access server",e);

Appender就是设置日志讯息输出到哪个地方。您可以同时指定多个输出目的地

                log4j.appender.appenderName=Appender.class

                log4j.appender.appenderName.option1=value1

                log4j.appender.appenderName.optionN=valueN

例如:终端输出的同时也输出到HTML中(FileAppender和ConsoleAppender等都是Appender类)

             log4j.rootLogger=debug,appender1,appender2

             log4j.appender.appender1=org.apache.log4j.FileAppender

             log4j.appender.appender2=org.apache.log4j.ConsoleAppender

             log4j.appender.appender1.File=c:\demolog4j.htm

             log4j.appender.appender1.layout=org.apache.log4j.HTMLLayout

             log4j.appender.appender2.layout=org.apache.log4j.TTCCLayout

常用的有以下几个:

             org.apache.log4j.ConsoleAppender(控制台)(把日志讯息通过控制台在终端进行输出)

             org.apache.log4j.FileAppender(文件)(通过文件把日志讯息保存在文件中)

             org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)

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

             org.apache.log4j.WriterAppender(将日志讯息以串流格式发送到任意指定的地方)

             org.apache.log4j.JdbcAppender(将日志讯息保存到数据库中)

Layout就是指定日志讯息的格式。配置的格式如下:

           log4j.appender.appenderName.layout=Layout.class

           log4j.appender.appenderName.layout.option1=value1

Log4j提供的layout有以下几种:

           org.apache.log4j.HTMLLayout(以HTML表格形式布局)

           org.apache.log4j.SimpleLayout(包含日志讯息的级别和讯息字符串)

           org.apache.log4j.TTCCLayout(包含日志产生的时间、执行的线程、类别等等讯息)

           org.apache.log4j.PatternLayout(可以灵活地指定布局模式)

SimpleLayout举例:log4j.rootLogger=debug,appender1

                                    log4j.appender.appender1=org.apache.log4j.ConsoleAppender

                                    log4j.appender.appender1.layout=org.apache.log4j.SimpleLayout

SimpleLayout输出:DEBUG - This is debug message.

                                    INFO - This is info message.

                                    ERROR - This is error message.

PatternLayout:用来定制所输出的日志信息的样式

                            %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

                            %r 输出自应用启动到输出该日志讯息所耗费的毫秒数

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

                            %f 输出日志讯息所属的类别的类别名

                            %c 输出日志讯息所属的类的全名

                            %d 输出日志时间点的日期或事件,指定格式的方式:%d{yyyy-MM-dd HH:mm:ss}(SSS代表毫秒)

                            %l 输出日志事件的发生位置,即输出日志讯息的语句处于它所在的类别的第几行

                            %m输出代码中指定的讯息,如log(message)中的message

                            %n 输出一个换行符号

                            %-4r 或%-5p 是表明输出的内容所占的字符的数量。若输出的内容大于该数值,则超出的内容就会被截取掉

                            %M表示的是方法名

                            [%C-%M] 这里的 [、] 将原样输出

PatternLayout举例:log4j.rootLogger=debug,appender1

                                     log4j.appender.appender1=org.apache.log4j.ConsoleAppender

                                     log4j.appender.appender1.layout=org.apache.log4j.PatternLayout

                                     log4j.appender.appender1.layout.ConversionPattern=%r [%t] %p - %c -%l -%m%n

PatternLayout输出:0 [main] DEBUG - com.v512.log4j.HelloLog4j -com.v512.log4j.HelloLog4j.main(HelloLog4j.java:9) -This is debug message.

                                     0 [main] INFO - com.v512.log4j.HelloLog4j -com.v512.log4j.HelloLog4j.main(HelloLog4j.java:10) -This is info message.

                                     0 [main] ERROR - com.v512.log4j.HelloLog4j -com.v512.log4j.HelloLog4j.main(HelloLog4j.java:11) -This is error message.

log4j.properties文件配置

        log4j.rootLogger=debug,appender1<!--说明-->

        log4j.appender.appender1=org.apache.log4j.ConsoleAppender

        log4j.appender.appender1.layout=org.apache.log4j.Simpleayout

        说明:rootLogger设定根的日志输出的内容

                     开发一个应用有很多的类,类是通过不同的包进行组织的

                     有时我们希望只把某些特定包的一些类的日志信息记录下来,而不是把所有类的日志信息都记录下来

                     这时就可以分别去设置,也可以把不同的包当中的类的输出日志的级别设置的不同

                     这里使用了rootLogger就表示当没有指定特定的包的时候,其余所有的类都使用后面定义的级别

RootLogger:log4j.rootLogger=[level],appenderName,appenderName,...

                        上面的设定若将输出登记设为INFO,就表示INFO—→FATAL等级的讯息将会输出,DEBUG等级的信息就会被忽略

                        appenderName设定日志文件的去处,可以有一个,可以有N个

                        这样一个日志讯息即可以保存在物理文件中也可以在终端输出还可以保存在数据库中也可以通过邮件发送出去

利用RootLogger为不同的包指定不同的日志处理策略。示例:log4j.logger.com.liuwei=info,appender1(对liuwei包里的所有的日志信息均采用info等级)

log4j.xml文件配置

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

       <appender name="appender1" class="org.apache.log4j.RollingFileAppender">

              <param name="File" value="logfile.html" />

              <param name="MaxFileSize" value="1MB" />

              <param name="MaxBackupIndex" value="5" />

              <layout class="org.apache.log4j.HTMLLayout">

                     <param name="append" value="true" />

              </layout>

       </appender>

       <root>

              <priority value="debug" />

              <appender-ref ref="appender1" />

       </root>

</log4j:configuration>

Log4j对性能的影响(对程序运行的性能影响非常小)

还可以通过下面的方式降低性能影响:if(log.isDebugEnabled()){log.debug("x="+longRunning())}

也就是先判断一下是否允许debug记录日志信息