log4j 是个日志框架,用于产生日志用的,因为你还没接触过,对于日志框架的介绍不宜掺杂代码,只能作一些概念上的介绍。
如果不采用日志的话,在调试的时候,为了查看运行中的结果,代码中含有很多的 System.out.println() 语句,
这也没问题,但是问题就出现在如果把问题给解决了,那些 System.out.println() 的去留问题,那我们是一个
一个地跑到代码里去把这些输出语句揪出来删掉,还是不管他们任凭他们躺在代码里影响运行效率呢?
当然了,我们在调试完成后,或者说是正式上线使用了得把这些输出语句去掉的。但是问题又来了,如果以后又出现问题
了该怎么办呢?难道再加,再找,再删?
采用日志框架就可以很好的解决上述问题,日志框架的级别一般有 DEBUG、INFO、WARN、ERROR、FATAL 几种常见的,如果
是用于调试的代码,可以采用 DEBUG 级别的日志,如果是普通信息可以采用 INFO 级别的,如果不影响使用的错误可以使
用 WARN 级别,如果影响使用的(比如说产生异常了)可以使用 ERROR 级别,如果严重影响使用的可以使用 FATAL 级别的。
将日志分级的目的就是在于可灵活配置,拿 log4j 举例子,如果日志级别限定于 DEBUG,那么包含 DEBUG 在内的,INFO、
WARN、ERROR、FATAL 都产进行日志记录,如果级别定为 INFO,那么 INFO 以下的级别,像 DEBUG 的日志就不会记录。
如果我们调试时把 System.out.println 换成 log.debug() 记录的话,我们把问题解决后,只要把日志级别在配置文件中改
成 INFO,那么那些 DEBUG 的日志就不用再输出了,如果以后再要调试,只要把日志级别调回到 DEBUG 就行了,很方便吧。
日志框架不仅可以把日志输出在控制台上,也可以把日志输出到文件、数据库中,不仅可以配置全局的日志级别,也可以为
某个包下面的代码配置日志级别,还能配置日志的输出格式。
很多的日志框架有个缺点,比如有以下的代码:
虽然我们可以把日志级别调成 INFO,不记录 DEBUG 的日志,但是上面这段代码就有个缺点,就是参数。大家都知道要执行
方法前,得先将参数中的表达式计算后再进行方法调用。同时我们还知道 Java 中的字符串是不可变对象,字符串与变量进
连接运算(+)时,其内部会使用 StringBuilder 或者 StringBuffer 来进行连接。
我们想想看看,如果 DEBUG 的日志不需要记录,那么这种效率很低的拼接还有意义么?如果不管他们,并且在代码中含有大
量此类的语句,那么会严重影响程序运行效率的。
一般日志框架都有这一个功能,就是可以判断当前的日志记录器的级别:
像这样做的话就可以解决效率低下的问题,因为在调用之前会进行日志记录级别的判断,达到的话才会执行。
但是问题又来了,这样做会导致日志代码可能会很繁锁,甚至有可能日志代码比业务代码还多。
目前的 log4j 还没有解决这个问题,据 Apache Logging 的介绍 log4j 2.0 会采用 JDK 5 的语法进行设计,
可能会解决这个问题。
像其他的日志记录器,比如 JBoss Seam 中的日志,就采用了 JDK 5 中新增的变参语法解决这个问题,如果
采用变参的话,那段代码只要写成:
这样的代码不涉及表达式计算,在 log.debug 中也会首先判断日志级别,以决定是否记录。
不知道上面啰里啰嗦了一堆,不知道你是不是明白了日志的作用了呢?
如果不采用日志的话,在调试的时候,为了查看运行中的结果,代码中含有很多的 System.out.println() 语句,
这也没问题,但是问题就出现在如果把问题给解决了,那些 System.out.println() 的去留问题,那我们是一个
一个地跑到代码里去把这些输出语句揪出来删掉,还是不管他们任凭他们躺在代码里影响运行效率呢?
当然了,我们在调试完成后,或者说是正式上线使用了得把这些输出语句去掉的。但是问题又来了,如果以后又出现问题
了该怎么办呢?难道再加,再找,再删?
采用日志框架就可以很好的解决上述问题,日志框架的级别一般有 DEBUG、INFO、WARN、ERROR、FATAL 几种常见的,如果
是用于调试的代码,可以采用 DEBUG 级别的日志,如果是普通信息可以采用 INFO 级别的,如果不影响使用的错误可以使
用 WARN 级别,如果影响使用的(比如说产生异常了)可以使用 ERROR 级别,如果严重影响使用的可以使用 FATAL 级别的。
将日志分级的目的就是在于可灵活配置,拿 log4j 举例子,如果日志级别限定于 DEBUG,那么包含 DEBUG 在内的,INFO、
WARN、ERROR、FATAL 都产进行日志记录,如果级别定为 INFO,那么 INFO 以下的级别,像 DEBUG 的日志就不会记录。
如果我们调试时把 System.out.println 换成 log.debug() 记录的话,我们把问题解决后,只要把日志级别在配置文件中改
成 INFO,那么那些 DEBUG 的日志就不用再输出了,如果以后再要调试,只要把日志级别调回到 DEBUG 就行了,很方便吧。
日志框架不仅可以把日志输出在控制台上,也可以把日志输出到文件、数据库中,不仅可以配置全局的日志级别,也可以为
某个包下面的代码配置日志级别,还能配置日志的输出格式。
很多的日志框架有个缺点,比如有以下的代码:
1
|
log.debug(
"customer address: "
+ address+
", coustomer count: "
+ count);
|
虽然我们可以把日志级别调成 INFO,不记录 DEBUG 的日志,但是上面这段代码就有个缺点,就是参数。大家都知道要执行
方法前,得先将参数中的表达式计算后再进行方法调用。同时我们还知道 Java 中的字符串是不可变对象,字符串与变量进
连接运算(+)时,其内部会使用 StringBuilder 或者 StringBuffer 来进行连接。
我们想想看看,如果 DEBUG 的日志不需要记录,那么这种效率很低的拼接还有意义么?如果不管他们,并且在代码中含有大
量此类的语句,那么会严重影响程序运行效率的。
一般日志框架都有这一个功能,就是可以判断当前的日志记录器的级别:
1
2
3
|
if
(log.isDebugEnabled()) {
log.debug(
"customer address: "
+ address+
", coustomer count: "
+ count);
}
|
像这样做的话就可以解决效率低下的问题,因为在调用之前会进行日志记录级别的判断,达到的话才会执行。
但是问题又来了,这样做会导致日志代码可能会很繁锁,甚至有可能日志代码比业务代码还多。
目前的 log4j 还没有解决这个问题,据 Apache Logging 的介绍 log4j 2.0 会采用 JDK 5 的语法进行设计,
可能会解决这个问题。
像其他的日志记录器,比如 JBoss Seam 中的日志,就采用了 JDK 5 中新增的变参语法解决这个问题,如果
采用变参的话,那段代码只要写成:
1
|
log.debug(
"customer address: {0}, customer count: {1}"
, address, count);
|
这样的代码不涉及表达式计算,在 log.debug 中也会首先判断日志级别,以决定是否记录。
不知道上面啰里啰嗦了一堆,不知道你是不是明白了日志的作用了呢?