logback和slf4j的使用chapter2

1.我们在http://logback.qos.ch/的首页,就可以看到logback is divided into three modules, logback-core, logback-classic and logback-access.


在logback中只要有三个JAR包:Logback-classic.jar,logback-core.jar,logback-access.jar,其中 logback.core是另外两个JAR包的基础,而logback-classic.jar包是log4j的改善版本,用于帮助打印日志, 而logback-access.jar包是通过互联网访问日志时需要的JAR包。


2.上一节中我们说到了基本的配置,采用logback的默认的配置环境,如果我们想自己配置自己想要的信息和样式该如何操作:那就先看看logback的内部状态是如何启动的。只要两句话就可以了:

<span style="font-size:18px;">import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;

public class HelloWorld2 {

  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld2");
    logger.debug("Hello world.");

    // print internal state
    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    StatusPrinter.print(lc);
  }
}</span>
当你运行之后就会出现下面的几句话:
<span style="font-size:18px;">10:20:48,314 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
10:20:48,314 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
10:20:48,314 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
10:20:48,316 |-INFO in ch.qos.logback.classic.BasicConfigurator@48b8f82d - Setting up default configuration.</span>
从运行的结果中我们知道:在logback初始化时,就会先在classpath(就是src的目录下)下有没有名字叫做logback.groovy的文件,如果有的话,就是用这个配置信息。如果没有的话,就去查找下一个logback-test.xml文件。如果没有的话就去找logback.xml文件的信息。如果有的话,就加载其中的信息,如果没有的话,就采用默认的配置信息。

所以我们要加载自己的logback的配置文件,就要用上面的三个名字中的任意一个作为文件的名字才能加载我们自己的logback的配置信息。


3.logback的配置信息:(打开logback的documentation的chapter2 Architecture)

Logback is built upon three main classes: LoggerAppender and Layout.

其中在logback中主要有三个类:就是Logger,Appender和Layout三个类,其中Logger类在logback-classic模块下,而Appender和Layout接口是在是在logger-core的模块下。下面就是三个部分的描述


4.Logger的返回值

Calling the LoggerFactory.getLogger method with the same name will always return a reference

to the exact same logger object.

我们要想得到一个Logger对象的话,就要使用LoggerFactory.getLogger的静态方法:但是如果使用相同的名字的话,只会返回同一个Logger对象。例如:
<span style="font-size:18px;">Logger x = LoggerFactory.getLogger("wombat"); 
Logger y = LoggerFactory.getLogger("wombat");</span>
其中x和y是同一个对象。

他有一个addtivity属性,在下面和Appender中讲到:


5.Appender:可以只看中文


1).Logback allows logging requests to print to multiple destinations. In logback speak, an output destination is called an appender. Currently, appenders exist for the console, files, remote socket servers, to MySQL, PostgreSQL, Oracle and other databases, JMS, and remote UNIX Syslog daemons.

1).他的作用:将我们的日志信息输出到哪里。Logback可以将日志按照需要打印到多个目标设备上去,按照logback的说法:一个目标设备可以说成是一个appender,目前的话,可以输出到控制台、文件、远程的服务器、到MYSQL数据库、PostgreSQL数据库、Oracle数据库、其他数据库、Email和UNIX系统的日志中。

***注意appender是可以累加的***


2).原文中说道:Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy. In other words, appenders are inherited additively from the logger hierarchy. For example, if a console appender is added to the root logger, then all enabled logging requests will at least print on the console. If in addition a file appender is added to a logger, say L, then enabled logging requests for L and L's children will print on a file and on the console. It is possible to override this default behavior so that appender accumulation is no longer additive by setting the additivity flag of a logger to false.

2).每一个指定可用的logger将会向前继承当前Logger的层次更高的Logger的所有appender样式。也就是说:appender会累加来自更高的Logger的appender样式。

例如:一个在root(注意:在Logger中root是最高的,相当于java中的Object对象,是所有的父类)添加了一个输出到控制器上的Appender,那么所有的Logger将会至少在控制台打印日志信息,如果一个输出到文件的Appender定义在了一个名字为L的Logger中,然后L和L的所有的孩子将会将日志信息输出到文件(这个是L自己配置的)中和控制器(这个是root配置的)。如果不想使用累加功能也是可以的,将logger中的additivity属性设置为false。默认值是true。

****注意****经过验证。这个属性是不会继承的,除非你设置这个logger的additivity的属性为false,否则就是true。


3).他的日志中也有说明:

名字为L的Logger的日志输出状态将会包含L本身上的所有AppenderL的超类(就是所有L的父类)的Appender类型。这就是Appender的累加意义。但是,如果L的有一个父类叫做P的话,并且P的additivity的值为false,那么L的输出日志状态就会是L上的所有Appender从L到P父类(包含P)所有的Appender类型,但是不再包含P的父类的Appender类型

Logger的addivitity的默认属性为true。

4).看一张图片更为清楚



6.Layout:


1).在打印日志时,不止会出现我们输出的信息,还会输出时间等等信息,如果我们不想使用它的默认格式,想自己配置打印的格式,那就在logger中配置。

2).layout是属于appender标签下的子标签,主要功能就是设置用户想要的输出日志格式信息。类似于C语言中的printf功能。


7.打印日志的效率问题:


1).在打印日志时,我们可以使用下面的代码:
l ogger.debug("Entry Number :"+ i + " is "+String.valueOf(entry[i]));
这样做的效率比较低。因为他会遭受到【变量i】和【entry】转换成一个字符串,并且再加上字符串的拼接。这些时间不管你打印不打印这些日志都会消耗。
即有可能你讲DEBUG的模式打印的日志的功能关闭了,但是上面那就话还是会消耗时间。

2).但是如果变成下面的代码,就不会消耗时间了:
if(logger.isDebugEnabled()) { 
  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
如果debug模式关闭,就不会消耗时间,如果debug模式是开放的,就会消耗时间。从而提高了效率

3).使用Logback中的字符串的占位符
在logback中占位符是一对花括号:【{}】.
对于:
Object entry = new SomeObject(); 
logger.debug("The entry is {}.", entry);
如果日志需要的打印的话,就会将{}变成对应的变量的值。如果不需要打印的话,他也不会消耗时间。如同加上了
if(logger.isDebugEnabled()) { 
这句话。提高了效率。

4)当然也可有多个变量的值:
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
Object[] paramArray = {newVal, below, above};
logger.debug("Value {} was inserted between {} and {}.", paramArray);

5)所以,在打印日志时:为了提高效率:有两种方式:
①加上logger.isDebugEnabled()或者logger.isInfoEnable()等等
②使用占位符。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值