转载

logback官方文档阅读笔记(五)

前言

logback官方文档

本文关于官方文档第三章: Logback configuration 。

本文为官方文档第三章的第二份笔记,第三章第一份笔记请见: logback官方文档阅读笔记(四)

正文

配置文件(xml)的基本结构

As will be demonstrated over and over, the syntax of logback configuration files is extremely flexible. As such, it is not possible to specify the allowed syntax with a DTD file or an XML schema. Nevertheless, the very basic structure of the configuration file can be described as, <configuration> element, containing zero or more <appender> elements, followed by zero or more <logger> elements, followed by at most one <root> element. The following diagram illustrates this basic structure.

基本结构为 logback官方文档阅读笔记(五)

配置文件(xml)的注意事项:大小写

Since logback version 0.9.17, tag names pertaining to explicit rules are case insensitive. For example, <logger>, <Logger> and <LOGGER> are valid configuration elements and will be interpreted in the same way. Note that XML well-formedness rules still apply, if you open a tag as <xyz> you must close it as </xyz>, </XyZ> will not work. As for implicit rules, tag names are case sensitive except for the first letter. Thus, <xyz> and <Xyz> are equivalent but not <xYz>. Implicit rules usually follow the camelCase convention, common in the Java world. Since it is not easy to tell when a tag is associated with an explicit action and when it is associated with an implicit action, it is not trivial to say whether an XML tag is case-sensitive or insensitive with respect to the first letter. If you are unsure which case to use for a given tag name, just follow the camelCase convention which is almost always the correct convention.

简单来说,就是像logger,appender,filter这样的内置的有效指令元素的标签名不区分大小写。对于搞不清楚什么成分的,使用驼峰命名法。

配置文件(xml)的logger元素的配置语法

Configuring loggers, or the <logger> element

A logger is configured using the <logger> element. A <logger> element takes exactly one mandatory name attribute, an optional level attribute, and an optional additivity attribute, admitting the values true or false. The value of the level attribute admitting one of the case-insensitive string values TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF. The special case-insensitive value INHERITED, or its synonym NULL, will force the level of the logger to be inherited from higher up in the hierarchy. This comes in handy if you set the level of a logger and later decide that it should inherit its level.

配置logger的appender

The <logger> element may contain zero or more <appender-ref> elements; each appender thus referenced is added to the named logger. Note that unlike log4j, logback-classic does not close nor remove any previously referenced appenders when configuring a given logger.

<appender-ref>怎么写其实没说明白。通过在文档中以'appender-ref'为关键词搜索,就得到的例子,可以推测其使用方式如图:

logback官方文档阅读笔记(五)

再过几节有几段文字再度谈及了logger引用appender。

Configuring the root logger, or the <root> element

It supports a single attribute, namely the level attribute. It does not allow any other attributes because the additivity flag does not apply to the root logger. Moreover, since the root logger is already named as "ROOT", it does not allow a name attribute either. The value of the level attribute can be one of the case-insensitive strings TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF. Note that the level of the root logger cannot be set to INHERITED or NULL.

Appender并不能限制logger的输出

Let us note that the basic-selection rule depends on the effective level of the logger being invoked, not the level of the logger where appenders are attached. Logback will first determine whether a logging statement is enabled or not, and if enabled, it will invoke the appenders found in the logger hierarchy, regardless of their level.

这段话最后一句很有意思,'regardless of their level',这里的这个their中的它,指的最合句子结构和语境的,其实是Appender。也就是说Appender可能也有级别问题。

appender元素必需属性

An appender is configured with the <appender> element, which takes two mandatory attributes name and class. The name attribute specifies the name of the appender whereas the class attribute specifies the fully qualified name of the appender class to instantiate.

<appender>元素标签必需(mandatory)的两个属性为name和class。即要用appender标签,至少也会有这样的代码: <appender class="..." name="...">...</appender>

可选的增强appender的组件:layout,encoder,filter.

The <appender> element may contain zero or one <layout> elements, zero or more <encoder> elements and zero or more <filter> elements. Apart from these three common elements, <appender> elements may contain any number of elements corresponding to JavaBean properties of the appender class. Seamlessly supporting any property of a given logback component is one of the major strengths of Joran as discussed in a later chapter.

The <layout> element takes a mandatory class attribute specifying the fully qualified name of the layout class to instantiate. As with the <appender> element, <layout> may contain other elements corresponding to properties of the layout instance. Since it's such a common case, if the layout class is PatternLayout , then the class attribute can be omitted as specified by default class mapping rules.

The <encoder> element takes a mandatory class attribute specifying the fully qualified name of the encoder class to instantiate. Since it's such a common case, if the encoder class is PatternLayoutEncoder , then the class attribute can be omitted as specified by default class mapping rules.

这里官方文档不具体说一说两者的作用,也不提两者有专门的篇章——官方文档第五章,第六章——来说明它们,一个字,菜。

这里重复出现的

if the encoder class is .... , then the class attribute can be omitted as specified byrules.

点击URL查看,并结合接下来的例子,以及对这两个组件元素描述时,使用 mandatory 修饰 class 这个属性,就可以明白。这段反复出现的话就一个意思,其实 <encoder> `<layout>`的 class 属性不写全限定名甚至直接不赋值也行,我们有默认值的啦。

然后在打开的url中,迎面而来的表格有一个 parent class,乍一看看不懂。但回过头来看之后给的xml示例,发现appender元素必然有一个带类全限定名的class属性,比如 ch.qos.logback.core.FileAppender ,如果去翻阅 它的javadoc ,就会发现这个类是 ch.qos.logback.core.UnsynchronizedAppenderBase 的子类。看到这里,我想你心里已经有了一定猜测了。

Note that each appender has its own encoder. Encoders are usually not designed to be shared by multiple appenders. The same is true for layouts. As such, logback configuration files do not provide any syntactical means for sharing encoders or layouts.

这段文字在讲了一些关于logger引用appender的知识后才出现,这排布方式我也是服了。主要内容就是Encoder和Layout在设计时都没有把它们在多个Appender中复用的想法。

logger引用appender——appender-ref

Logging to multiple appenders is as easy as defining the various appenders and referencing them in a logger, as the next configuration file illustrates:

<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>

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

The appenders are attached to the root logger by referencing them by name within an appender-ref element.

logger在appender上的累进

By default, appenders are cumulative: a logger will log to the appenders attached to itself (if any) as well as all the appenders attached to its ancestors. Thus, attaching the same appender to multiple loggers will cause logging output to be duplicated.

logger会调用所有它能调用的appender,包括其自己引用的,其在开启addivity下所有上级logger的,都会被调用。

在此基础上,若一个appender被多个logger引用,可能导致重复日志记录的问题。

善用logger的additivity实现全软件控制台输出信息,特定类型的信息输出到文件。

For instance, you can configure logging such that log messages appear on the console (for all loggers in the system) while messages only from some specific set of loggers flow into a specific appender.

<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>

In this example, the console appender will log all the messages (for all loggers in the system) whereas only logging requests originating from the chapters.configuration logger and its children will go into the myApp.log file.

原文  https://segmentfault.com/a/1190000020766326
正文到此结束
Loading...