logback:logback和slf4j中的:appenderloggerencoderlayout

Posted 云潇洒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了logback:logback和slf4j中的:appenderloggerencoderlayout相关的知识,希望对你有一定的参考价值。

(1)appender

1.appender标签是logback配置文件中重要的组件之一。在logback配置文件中使用appender标签进行定义。可 以包含0个或多个appender标签。

2.appender主要作用就是:①控制打印日志的地方、②打印日志的输出格式。

3.appender语法结构:

1)属性:appender标签中包含两个强制需要的属性:①name、②class

①name:为这个appender起一个唯一标识的名称。与appender-ref中的值相对应。以引用appender。

②class:一个Appender类实例的完整类名称。

2)appender标签中可以包含0个或者1个【layout】标签。0个或者多个【encoder】标签,0个或者多个 【filter】标签。

3)除了上面3个公共标签之外,还可以包含任意多个与appender的class属性所在的类中的对应的属性标 签。准确的说是setXXX()的XXX标签。他就是利用了Java的反射机制。例如:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myApp.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>
  <root level="debug">
    <appender-ref ref="FILE" />
  </root>
</configuration>

 

在ch.qos.logback.core.FIleAppender类中有一个setFile(String file)的方法,所以就可以appender有任意数 量的<file>标签

4)下面图片展示了公共结构,注意没有支持的属性标签:

技术分享

5)其中layout标签有一个强制的属性名称为class,他的值为layout类对象实例的完整类名称。与 appender标签一样,layout标签可以包含layout class对应实例的属性标签(setXXX中的XXX标签)。

如果你的layout标签中class属性的值想为ch.qos.logback.classic.PatternLayout类的话,你可以选择不写, 因为有默认值会自动填入到class属性值中。

6)encoder标签有一个强制的属性名称为class,他的值为encoder类对象实例的完整类名称。 

如果你的encoder标签中class属性的值想为ch.qos.logback.classic.encoder.PatternLayoutEncoder 的类的话,你可以选择不写,因为有默认值会自动填入到class属相值中。

7)默认值图标如下:

技术分享

4.要想记录多个日志信息格式是很简单的,那就定义多个appender标签,然后将他们关联到一个logger上去。例 如:

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myApp.log</file><!--FileAppender中的一个SetFile方法。-->

    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>


  <root level="debug">
    <appender-ref ref="FILE" /><!--将日志输出到文件中-->
    <appender-ref ref="STDOUT" /><!--将日志输出到控制台中-->
  </root>
</configuration>

这个配置文件中定义两个appender标签,名称分别为FILE和STDOUT,其中FILE的appender将日志记录到 名字叫myApp.log日志中。这个encoder的实例为PatternLayoutEncoder。其中格式为<pattern>标签中的格 式样式。

两个appender标签都是与root元素通过【appender-ref】相关联的。

★★注意:每一个appender标签都有自己的encoder,encoder不能被多个appender所共享的。对于layout 也是一样的。所以在logback配置文件中没有任何语法提供让encoder或者layout可以被共享。

二、appender相关概念:

1.appender的累加(叠加):相关内容请看:logback和slf4j的使用之Logger使用:activity属性描述。

2.几个常用appender实例:

2.1.ConsoleAppender:

就想他的名字一样,将日志信息打印到控制台上,更加准确的说:使用System.out或者System.err方式输 出。

使用encoder标签设置输出的格式。

主要子标签有:

2.1.1encoder:设置打印日志信息的格式

2.1.2target:【String】设置一System.out还是System.err方式输出。默认值为System.out

2.2.FileAppender:

2.2.1.用于将日志信息输出到文件中。他有一个重要的标签:file标签。用于指定输出日志所在的文件。如果 日志不存在就会创建,如果存在,就会以【附加】或者【截断】的方式写入

2.2.2.主要的标签有:

append:【boolean】默认值为【true】。如果为true的话,就会以【附加】的方式写入到文件。

如果值为false。就会截断方式写入。

encoder:设置日志输出的格式信息

file:保存文件的路径。要注意【\】反斜杠的问题。如果你想要保存到【c:\temp\test.log】,你肯定不 想解释为【\t】为一个整体把。正确的做法是使用【c:/temp/test.log】或者【 c:\\temp\\test.log】两个中 的一个。

2.2.3独一无二的文件名称:

在应用开发或者短时间的项目中,一次运行项目都想创建一个新的日志文件信息,使用<timestamp> 标签可以很容易实现这个功能

例如:

<configuration>

  <!-- Insert the current time formatted as "yyyyMMdd‘T‘HHmmss" under
       the key "bySecond" into the logger context. This value will be
       available to all subsequent configuration elements. -->
  <timestamp key="bySecond" datePattern="yyyyMMdd‘T‘HHmmss"/>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <!-- use the previously created timestamp to create a uniquely
         named log file -->
    <file>log-${bySecond}.txt</file>
    <encoder>
      <pattern>%logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

2.3.RollingFileAppender

从名字我们就可以得出:FileAppender是RollingFileAppender的父类。即RollingFileAppender继承 FIleAppender类。功能:能够动态的创建一个文件。也就是说:到满足一定的条件,就会创建一个新的文 件,然后将日志写入到新的文件中。

2.3.1.有两个重要的标签与rolingFileAppender进行交互:

2.3.1.1.RollingPolicy:

2.3.1.2.TriggeringPolicy

注意:为了使用RollingFileAppender必须有RollingPolicy和triggerPolicy。但是如果RoolingFileAppender中 的RoolingPolicy同时也实现了TriggerPolicy接口的话,那么只要这一个模型就可以了。

2.3.2.RollingFileAppender的标签:

2.3.2.1 file:与FileAppender一样。只能是确定的名称,不能改变。

2.3.2.2 append:与FileAppender一样,用于附加还是截断

2.3.2.3 encoder:设置输出日志的格式,与FIleAppender一样

2.3.2.4 rollingPolicy:当转换文件时,他会告诉RollingFileAppender

2.3.2.5 triggerPolicy.

2.3.3一个重要的RollingPolicy:(TimeBaseRollingPolicy)

这个TimeBaseRollingPolicy可能是最常用的rolling policy。

他的转换文件名是依赖时间,例如可以设置天,或者月

TimeBaseRollingPolicy实现了RollingPolicy接口,又实现了TriggerPolicy接口。

2.3.3.1TimeBaseRollingPolicy有一个强制的标签和几个可选的标签:

2.3.3.1.1 fileNamePattern:这是一个强制的标签。他的值可以包含:文件的名称、适当的%d转 换说明符。这个%d说明符可以包含一个【日期和时间】的模式。其中【模式】类似于 【SimpleDateFormat】类。如果这个【模式】没有写的话,默认就是【yyyy-MM-dd】的模式。 转换文件的名称从fileNamePattern中得到

注意:在RollingFileAppender中有一个file标签,也是设置文件的名称的。file可以设置 也可以不设置。如果你设置了file标签的话,他就不会转换到新的文件中。所有的日志  信息将会输入到同一个文件中。如果file标签没有设置。文件的名称就会在每一个阶段 由filenamePattern计算得出。

其中【日期和时间】格式的形式;【%d{格式}】。注意:在fileNamePattern中无论是斜杠【/】 还是反斜杠【\】在fileNamePattern的任何位置或者在【日期时间】模式里面都作为文件分隔符。

在fileNamePattern中可以有多个%d的说明符,但是只能有一个主的%d说明付。其他的%d说明 符必须使用【aux】说明是从说明符。

2.3.3.1.2maxHistory:这是一个可选的标签。用于控制文件保持的最大时间。异步的删除删除旧 的文件。时间单位是月。如果你设置为6的话,那就是保持文件的时间是6个月。超过6个月的文 件将会被删除。

2.3.3.1.3totalSizeCap:这是所有日志文件的总大小空间。当日志文件的空间超过了设置的最大 空间数量,就会删除旧的文件。注意:这个标签必须和maxHistory标签一起使用。

2.3.4看看下面的例子

技术分享

2.3.5一个RollingFileAppender的完整例子:

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!-- keep 30 days‘ worth of history capped at 3GB total size -->
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>

    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

 

(2)logger 

一、logger标签描述:(了解logger标签之前先看看两个重要概念)

1.主要概念:★★级别继承(level inheritance)
1)root标签是所有logger的祖先元素,所有的logger都继承与root元素,相当于java中的object对象。
2)每一个logger标签都可以指定一个级别(TRACE,DEBUG,INFO,WARN,ERROR五种,他们是在ch.qos.logback.classic.Levelclass中定义的)。
3)如果一个指定的logger标签没有指定规则的话,就会继承离他最近的祖先的级别。
4)因为所有的logger都是继承root标签,所以为了确保所有的logger都有一个级别,root标签有一个默认的级别,默认值为DEBUG
5)看看下面四个例子:

技术分享技术分享技术分享技术分享


2.重要概念:★★基本选择规则(base selection rule):
1)任何一个logger对象都有五种级别,所以就对应有五种打印日志方法:logger.info(字符串),logger.debug(字符串)
2)如果使用logger.info(字符串)的话,那么logger打印级别就是INFO。
3)看看一个logger能不能打印出日志主要看两个因素:①打印方法时使用的级别(logger.info()),②logger对象的有效级别。第一个
重要概念所讲。
4)如何判断是否打印出日志:规则如下:
A log request of level p issued to a logger having an effective level q, is enabled if p >= q.
一个logger打印级别为P,而他的有效级别为q。如果p>=q的话,p对应的信息能打印出来。否则就不能打印出对应的信息。
记住:有效级别是最低级别,高于有效级别的信息都能打印出来,低于有效级别都不能打印出来。
5)级别大小规则:TRACE<DEBUG<INFO<WARN<ERROR。
6)例如:

技术分享


3.logger结构:
1)一个logger标签包含:一个强制的name属性,一个可选的level属性和一个可选的additivity属性(additivity的值有true和false)
2)level属性的值:可以是TRACE,DEBUG,INFO,WARN,ERROR,OFF,ALL中任何一个,并且不区分大小写。如果没有写的话就会继承离他最近的祖先的级别,就是第一个概念的内容。
3)其中name的值,很重要,并且是必须的。它主要是指定包名或者类名的全路径(包含包名)。所有的logger对象都是通过这个来确定祖先关系的。
4)logger标签可以包含0个或者多个appender-ref标签,所以每一个appender标签都可以关联到指定的logger中。

5)level默认是以覆盖的方式继承的。而appender-ref是附加的形式继承的。
1)覆盖方式:如果父亲的级别是DEBUG,如果在这个logger中设置了INFO,最终这个logger的级别就是INFO
2)附加方式:如果在父亲中有一个appender-ref(关联一个appender标签),在当前这个logger中也设置一个appender-ref,
那么当前的logger就有两个appender-ref的关联。如果想要改变默认的附加形式,那就要使用addtivity属性值。

二、logger中appender附加方式:

1.在默认情况下:appender是累加的方式进行操作的。即:一个logger对象将会记录:①与这个logger对象直接关联的appender日志格式,

是当前logger对象的祖先对象(所有祖先)的logger相关联的appender日志格式。因此:同一个appender对象绑定到多个logger对象上,就会造成日志输出多份。

2.例如:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <logger name="chapters.configuration">
    <appender-ref ref="STDOUT" /><!--STDOUT绑定到chapters.configuration上,这个logger的祖先是root-->
  </logger>

  <root level="debug"><!--在root上也绑定STDOUT的appender对象到root上。-->
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

如果在charpters.configuration的类的日志打印的话,就会打印两份。因为一份是charpters.configuration

的,一份是root的。所以就会打印两次:如下所示:

14:25:36.343 [main] INFO chapters.configuration.MyApp3 - Entering application.

14:25:36.343 [main] INFO chapters.configuration.MyApp3 - Entering application.

14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!

14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!

14:25:36.359 [main] INFO chapters.configuration.MyApp3 - Exiting application.

14:25:36.359 [main] INFO chapters.configuration.MyApp3 - Exiting application.

这个名字为STDOUT附加到两个logger对象上,root是任何logger对象的祖先。而chapters.configuration

又是MyApp3和Foo的祖先,所有打印两次。

3.appender的累加功能不想想对新用户造成困扰。而是对于日志记录非常的灵活。

1)例如:如果你想要配置日志文件以便形成:①对于所有的logger对象的日志信息都打印到控制台上。

②并且只有一部分的logger对象打印到日志文件中。那就如下配置logback文件

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myApp.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration">
    <appender-ref ref="FILE" />
  </logger>

  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

对于所有的日志对象都会打印日志信息到控制台上,但是对于chapters.configuration的日志对象还会记录到

文件中。

4.覆盖默认的appender的累加行为:

如果默认的累加行为不符合你的要求, 你可以通过设置【activity=false】来取消默认的行为(累加)

1)例如:

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>foo.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration.Foo" additivity="false">
    <appender-ref ref="FILE" />
  </logger>

  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

上面那个例子中:一个名字叫FILE的appender附加到chapters.configuration.Foo的logger对象上,

并且这个logger对象的activity的属性为false。这就意味着:Foo的日志信息将会按照名字叫FILE的

appender的样式输出,而不会附加任何一个祖先上的appender对象。但是,其他日志对象(不属于

chapters.configuration.Foo及其子类的logger)仍然以附加的形式继承appender对象。

(3)encoder和layout

一、encoder介绍:
1.encoder:主要工作有两个:①将一个event事件转换成一组byte数组,②将转换后的字节数据输出到文件中。
2.encoder组件是在0.9.19版本之后才引进来的。在以前的版本中,appender是使用layout(将一个event事件转换成一个字符串),然后使用【java.io.writer】对象将字符串写入到文件中。
3.自从0.9.19版本之后,Fileappender和他的子类是期望使用encoder,不再使用layout。
4.其中layout仅仅完成了将一个event事件转换成一个字符串这一个功能。此外,layout不能控制将字符串写出到文件。layout不能整合event事件到一组中。与encoder相比,不仅仅能按照格式进行转化,而且还能将数据写入到文件中。
5.其中patternLayoutEncoder是最常使用encoder,他包含了patternLayout大部分的工作。
6.几个重要的encoder:
6.1.LayoutWrappingEncoder:(不怎么用)
6.1.1.在0.9.19版本之前,都是使用layout来控制输出的格式。那就存在大量的layout接口(自定义)的代码。在0.9.19就变成了使用encoder来控制,如果我们想使用以前的layout怎么办?这个LayoutWrappingEncoder就是为了encoder能够操作内部layout存在的。即这个类在encoder与layout之间提供一个桥梁。这个类实现了encoder类,又包含了layout将evnet事件装换成字符串的功能。
6.1.2.原理:使用layout将输入的evnet事件转换成一个字符串,然后将字符串按照用户指定的编码转换成byte数组。最后将byte数据写入到文件中去。
6.1.3.在默认的情况下,输出流是立即刷新的。除非immediateFlush属性值为false,就不会立即刷新,但是为提高logger接入量。
	6.2.PatternLayoutEncoder:常用。他是LayoutWrappingEncoder的子类
6.2.1.考虑到PatternLayout是layout中最常用的组件,所以logback人员开发出了patternLayoutEncoder类,这个类是LayoutWrappingEncoder的扩展,这个类包含了PatternLayout。
6.2.2.immediateFlush标签与LayoutWrappingEncoder是一样的。默认值为【true】。这样的话,在已存在的项目就算没有正常情况下的关闭,也能记录所有的日志信息到磁盘上,不会丢失任何日志信息。因为是立即刷新。如果将【immediateFlush】设置为【false】,可能就是五倍的原来的logger接入量。但是可能会丢失日志信息在没有正常关闭项目的情况下。
6.2.3.例如:
<appender name="FILE" class="ch.qos.logback.core.FileAppender">   <file>foo.log</file>   <encoder><!--默认就是PatternLayoutEncoder类-->     <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>     <!-- this quadruples logging throughput -->     <immediateFlush>false</immediateFlush>   </encoder> </appender>
6.2.4.如果想在文件的开头打印出日志的格式信息:即打印日志的模式。使用【outputPatternAsHeader】标签,并设置为【true】.默认值为【false】。例如:

<appender name="FILE" class="ch.qos.logback.core.FileAppender">   <file>foo.log</file>   <encoder>     <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>     <outputPatternAsHeader>true</outputPatternAsHeader>   </encoder> </appender>

他就会在foo.log文件的开头有一句【#logback.classic pattern: %d [%thread] %-5level %logger{36} - %msg%n】然后才是打印日志的信息。

6.2.5.patternLayoutEncoder类既有layout将一个事件转化为字符串,又有将字符创写入到文件中的作用。他是encoder标签的默认类实例。

二、layout功能:
1.layout主要的功能就是:将一个event事件转化为一个String字符串。
2.一个重要的Layout实例:PatternLayout:
2.1.在所有的layout中,patternLayout是一个灵活的Layout实例,将一个event转化为一个String,而这个String的格式可以有我们自定义的转化模式得到。
2.2.patternLayout的转换模式与C语言的printf函数相类似。
2.3.一个转换模式有两部分组成:①普通的文本、②格式控制表达式(转换说明符)
2.4.转换说明符:
2.4.1.必须以【%】开头。(必须的)
2.4.2.【%】后面是一个格式修饰符:用于左对齐,右对齐,前或后截取等等。(可选的)
2.4.3.转换的关键字。(必须的)。用于控制转换成什么的数据字段。例如logger的name、level级别、日期、线程的名称等等。
2.4.4.在大括号【{}】中间的范围。(可选的)
2.5.在patternLayout中可以使用小括号【()】形成一组转换模式。如果想要【()】作为普通字符,就要转义。
3.下面看看几个重要的转换关键字(第三个):如果在一个表格中,表示是有相同作用的。

技术分享技术分享技术分享


4.如果想让【%】作为普通的字符串。需要使用转义字符【\】。即使用【\%】就会变成普通【%】插入
5.注意:限制普通字符串紧跟在【转换说明符】后面。
例如%nhello,就会报错。因为系统找不到nhello的关键字。所以要加上分割符【空格,-,等等】
6.格式说明符:可选的。是转换说明符的第二个:
6.1.作用:用于左右对齐(最小宽度问题),左右截取(最大宽度问题),
6.2.位置:在【%】和【转换关键字】之间。
6.3.几个说明符:
6.3.1.默认情况下是【右对齐】,如果想要【左对齐】,就是用减号【-】。然后就是一个十进制的【最小宽度】数字。如果数据内容小于最小宽度的数字,如果没有【-】就在前面填充空格,如果有【-】就在后面填充空格。直到到达最小宽度的值。如果数据内容超过最小宽度,会显示全部内容(在没有执行最大宽度的时候)。
6.3.2.指定最大宽度:使用点号【.】,后面加上一个十进制的数字。如果数据内容超过了【最大宽度】,默认情况下,会从【前面】截取数据。如果数据长度为10,最大宽度为8,就会去掉前面2个字符,以显示后面的8个字符数据。如果想从【后面截取】,就在【.】后面加上一个【-】,就会从后面截取。即【.-8】
6.3.3.注意:在及指定最小宽度,又指定最大宽度的时候,先指定最小宽度,指定最大宽度。
6.3.4.如果以【.】开头,只有最大宽度的时候,就没有左右对齐之说。
6.3.5.总结:数字可以接在一下说明符的后面:
6.3.5.1.【直接写数字】:标识最小宽度并且是右对齐
6.3.5.2.【-数字】:标识最小宽度,并且是左对齐
6.3.5.3.【.数字】:标识最大宽度。如果数据内容超过最大宽度,从前面截取数据
6.3.5.4.【.-数字】:标识最大宽度。如果数据内容超过最大宽度,从后面截取数据
6.4.例子:

技术分享

以上是关于logback:logback和slf4j中的:appenderloggerencoderlayout的主要内容,如果未能解决你的问题,请参考以下文章

Springboot中logback与slf4j冲突排坑

Spring Boot中的logback + slf4j

logback+slf4j 怎样将控制台输出输出到文件

利用logback+slf4j日志采集整合到SBA

slf4j 与 logback日志配置详解

如何 用slf4j logback 把日志异步记录到数据库中