logback

logback的初始化步骤开始

1、Logback试图在类路径中找到名为logback-test.xml 的文件 。

2、如果找不到这样的文件,logback会尝试在类路径中找到名为logback.groovy 的文件 。

3、如果找不到这样的文件,它会检查类路径中的文件 logback.xml

4、找不到则会使用ServiceLoader来查找实现com.qos.logback.classic.spi.Configurator 接口

5、如果以上都不成功,logback将自动使用BasicConfigurator自动配置,将日志打印到控制台。

 

Basic configuration file

<configuration debug="true"> 开启logback的debug模式

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

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

OnConsoleStatusListener

状态监听器进行状态输出

有助于诊断logback问题

<configuration>
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />  

  ... the rest of the configuration file  
</configuration>

 

当scan 为true时,ReconfigureOnChangeTask会在一个新线程内运行并定时检查是否更改文件

<configuration scan="true" scanPeriod="30 seconds" >  热加载配置文件,扫描周期为30s
  ...
</configuration>

 

JoranConfigurator

Logback依赖于Joran的配置库,Logback的默认配置机制会调用 JoranConfigurator它在类路径上找到的默认配置文件。可以JoranConfigurator直接调用来覆盖logback的默认配置机制。

 

配置文件语法

配置文件的基本结构可以被描述为<configuration>元素,它包含零个或多个<appender>元素,后面是零个或多个<logger>元素,后面是最多一个<root>元素。下图说明了这个基本结构。

åºæ¬è¯­æ³

从0.9.17以来,与显式规则有关的标签名称不区分大小写,<logger><Logger>和 <LOGGER>等价。

<logger>

记录器使用该<logger> 元素进行配置。一个<logger>元素只需要一个必需的name属性,一个可选的 level属性和一个可选的additivity属性,允许值为 truefalse

additivity 是子Logger 是否继承 root的Logger 的 输出源(appender) 的标志位。

具体说,默认情况下子Logger会继承root的Logger的appender,也就是说子Logger会在root的Logger的appender里输出。

1.若是additivity设为false,则子Logger只会在自己的appender里输出,不会在root的logger的appender里输出(个人可以理解为additivity设为false后,子Logger会覆盖掉root的logger)。

2.若是additivity设为true,则子Logger不止会在自己的appender里输出,还会在root的logger的appender里输出

level属性的值允许输入一个不区分大小写的字符串值TRACE,DEBUG,INFO,WARN,ERROR,ALL或OFF。

<logger>元素可能包含零个或多个 <appender-ref>元素

<root>

<root>元素配置根记录器。它支持一个属性,即level属性。它不允许任何其他属性

<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <logger name="chapters.configuration" level="INFO"/> chapters.configuration 包下的级别为Info

  <!-- Strictly speaking, the level attribute is not necessary since -->
  <!-- the level of the root level is set to DEBUG by default.       -->
  <root level="DEBUG">       默认debug    
    <appender-ref ref="STDOUT" />
  </root>  
  
</configuration>

 

 

<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" level="INFO" />
  <logger name="chapters.configuration.Foo" level="DEBUG" />

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>

</configuration>
Logger nameAssigned LevelEffective Level
rootDEBUGDEBUG
chapters.configurationINFOINFO
chapters.configuration.MyApp3nullINFO
chapters.configuration.FooDEBUGDEBUG

 

Appenders

该元素具有两个强制属性name 和class。class 为类的全限定名称。

<appender>元素可能包含零个或一个<layout>元素,零个或多个 <encoder>元素以及零个或多个 <filter>元素。

<appender>元素可以包含与appender类的JavaBean属性相对应的任意数量的元素。

Appender语æ³

<layout> 也要一个class属性来指定布局类的全限定名。默认为PatternLayout

<encoder> 指定一个encoder类默认为PatternLayoutEncoder;

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

FILE appender把日志记录到myApp.log,FILE appender的encoder是PatternLayoutEncoder,输出了日期,级别,线程名称,记录器名称,文件名和行号,消息和行分隔符。

appender通过appender-ref元素中的名字引用它们,以连接到根记录器。请注意,每个appender都有自己的encoder。encoder通常不会被多个appender共享。layout也是如此。

 

logger将记录到附属于自身的appender(如果有的话)以及所有附属于其祖先的appender。因此,将同一appender附加到多个logger会导致记录重复输出。

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" />
  </logger>

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

 

<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" />   chapters.configuration的日志会在>myApp.log
  </logger>

  <root level="debug">
    <appender-ref ref="STDOUT" />  控制台单独打印 但是chapters.configuration的日志也会出现在控制台中
  </root>
</configuration>

 

<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"> 只会出现在myapp.log 文件中 控制台无chapters.configuration.Foo的日志
    <appender-ref ref="FILE" />
  </logger>

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

 

定义变量

<configuration>
  
  <property name="USER_HOME" value="/home/sebastien" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${USER_HOME}/myApp.log</file>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

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

或者使用

java -DUSER_HOME="/home/sebastien" MyApp2

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${USER_HOME}/myApp.log</file>

变量较多时可以使用properties文件 logback会去读取

<configuration>

  <property file="src/main/java/chapters/configuration/variables1.properties" />
  <property resource = “resource1.properties” />   classpath 引用资源
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
     <file>${USER_HOME}/myApp.log</file>
     <encoder>
       <pattern>%msg%n</pattern>
     </encoder>
   </appender>

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

 

条件处理

条件处理需要Janino库

针对不同环境(如开发,测试和生产)的多个logback配置文件之间进行交流

   <!-- if-then form -->
   <if condition="some conditional expression">
    <then>
      ...
    </then>
  </if>
  
  <!-- if-then-else form -->
  <if condition="some conditional expression">
    <then>
      ...
    </then>
    <else>
      ...
    </else>    
  </if>

 

<configuration debug="true">

  <if condition='property("HOSTNAME").contains("torino")'>
    <then>
      <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <pattern>%d %-5level %logger{35} - %msg %n</pattern>
        </encoder>
      </appender>
      <root>
        <appender-ref ref="CON" />
      </root>
    </then>
  </if>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${randomOutputDir}/conditional.log</file>
    <encoder>
      <pattern>%d %-5level %logger{35} - %msg %n</pattern>
   </encoder>
  </appender>

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

 

使用键“k”访问属性的值,可以编写property("k")或等价 p("k")。如果具有键“k”的属性未定义,那么属性方法将返回空字符串,而不是空值。这避免了需要检查空值。

isDefined()方法可用于检查属性是否已定义。例如,要检查属性“k”是否已定义,您将编写isDefined("k") 类似的,如果您需要检查属性是否为空,isNull()则提供该 方法。例如: isNull("k")

File inclusion

<configuration>
  <include file="src/main/java/chapters/configuration/includedConfig.xml"/>
  file 可以使用相对路径 作为resource 使用classpath 路径 url 使用url
  <root level="DEBUG">
    <appender-ref ref="includedConsole" />
  </root>

</configuration>

 

Appenders

接口

public interface Appender<E> extends LifeCycle, ContextAware, FilterAttachable {

  public String getName();
  public void setName(String name);
  void doAppend(E event);
  
}

 

public abstract class AppenderBase<E> extends ContextAwareBase implements Appender<E> {
    protected volatile boolean started = false;
    private boolean guard = false;
    protected String name;
    private FilterAttachableImpl<E> fai = new FilterAttachableImpl();
    private int statusRepeatCount = 0;
    private int exceptionCount = 0;
    static final int ALLOWED_REPEATS = 5;

    ******

    public synchronized void doAppend(E eventObject) {  线程安全
        if (!this.guard) {  确保该doAppend()方法不会递归调用自己 在append()方法之外的地方调用的组件需要记录一些东西。它的调用可以被引导到刚刚调用它的同一个appender,导致无限循环和堆栈溢出。
            try {
                this.guard = true;
                if (!this.started) { Appender对象实现了LifeCycle接口,一旦appender关闭,就不可能写入
                    if (this.statusRepeatCount++ < 5) {
                        this.addStatus(new WarnStatus("Attempted to append to non started appender [" + this.name + "].", this));
                    }

                    return;
                }

                if (this.getFilterChainDecision(eventObject) != FilterReply.DENY) {
                    this.append(eventObject);
                    return;
                }
            } catch (Exception var6) {
                if (this.exceptionCount++ < 5) {
                    this.addError("Appender [" + this.name + "] failed to append.", var6);
                }

                return;
            } finally {
                this.guard = false;
            }

        }
    }

    ****** 
}

如果不想使用同步方法还有UnsynchronizedAppenderBase  可以使用

 

ConsoleAppender

输出在控制台上System.out或 System.err

<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
    </encoder>
  </appender>

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

FileAppender

记录到文件中

RollingFileAppender

RollingFileAppender 扩展FileAppender了日志文件的功能。RollingFileAppender一旦满足某个条件,就将其日志记录目标更改为另一个文件。

两个重要的子组件与之交互 1、RollingFileAppender即 RollingPolicy2、 RollingFileAppender,即 TriggeringPolicy

 

TimeBasedRollingPolicy

TimeBasedRollingPolicy的配置需要一个必需的fileNamePattern属性和几个可选属性。

Property NameTypeDescription
fileNamePatternStringThe mandatory fileNamePattern property defines the name of the rolled-over (archived) log files. Its value should consist of the name of the file, plus a suitably placed %d conversion specifier. The %d conversion specifier may contain a date-and-time pattern as specified by the java.text.SimpleDateFormatclass. If the date-and-time pattern is omitted, then the default patternyyyy-MM-dd is assumed. The rollover period is inferred from the value of fileNamePattern.

Note that the file property in RollingFileAppender (the parent ofTimeBasedRollingPolicy) can be either set or omitted. By setting the file property of the containing FileAppender, you can decouple the location of the active log file and the location of the archived log files. The current logs will be always targeted at the file specified by the file property. It follows that the name of the currently active log file will not change over time. However, if you choose to omit the file property, then the active file will be computed anew for each period based on the value of fileNamePattern. The examples below should clarify this point.

The date-and-time pattern, as found within the accolades of %d{} follow java.text.SimpleDateFormat conventions. The forward slash '/' or backward slash '\' characters anywhere within the fileNamePattern property or within the date-and-time pattern will be interpreted as directory separators.

Multiple %d specifiers

It is possible to specify multiple %d specifiers but only one of which can be primary, i.e. used to infer the rollover period. All other tokens must be marked as auxiliary by passing the 'aux' parameter (see examples below).

Multiple %d specifiers allow you to organize archive files in a folder structure different than that of the roll-over period. For example, the file name pattern shown below organizes log folders by year and month but roll-over log files every day at midnight.

/var/log/%d{yyyy/MM, aux}/myapplication.%d{yyyy-MM-dd}.log

TimeZone

Under certain circumstances, you might wish to roll-over log files according to a clock in a timezone different than that of the host. It is possible to pass a timezone argument following the date-and-time pattern within the %d conversion specifier. For example:

aFolder/test.%d{yyyy-MM-dd-HH, UTC}.log

If the specified timezone identifier is unknown or misspelled, the GMT timezone is assumed as dictated by the TimeZone.getTimeZone(String)method specification.

maxHistoryintThe optional maxHistory property controls the maximum number of archive files to keep, asynchronously deleting older files. For example, if you specify monthly rollover, and set maxHistory to 6, then 6 months worth of archives files will be kept with files older than 6 months deleted. Note as old archived log files are removed, any folders which were created for the purpose of log file archiving will be removed as appropriate.
totalSizeCapint

The optional totalSizeCap property controls the total size of all archive files. Oldest archives are deleted asynchronously when the total size cap is exceeded. The totalSizeCap property requires maxHistory property to be set as well. Moreover, the "max history" restriction is always applied first and the "total size cap" restriction applied second.

cleanHistoryOnStartboolean

If set to true, archive removal will be executed on appender start up. By default this property is set to false.

Archive removal is normally performed during roll over. However, some applications may not live long enough for roll over to be triggered. It follows that for such short-lived applications archive removal may never get a chance to execute. By setting cleanHistoryOnStart to true, archive removal is performed at appender start up.

TimeBasedRollingPolicy支持自动文件压缩。如果fileNamePattern选项的值以.gz 或.zip结尾,则启用此功能。 

 

/wombat/foo.%d  yyyy-MM-dd的默认模式,该模式对应于每日滚动

/wombat/%d{yyyy/MM}/foo.txt  在每个月初开始滚动。

/wombat/foo%d{yyyy-MM-dd_HH}.log 在每小时的顶部滚动。

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

SMTPAppender

属性名称类型描述
smtpHostStringSMTP服务器的主机名。该参数是强制性的。
SMTPPORTintSMTP服务器正在侦听的端口。默认为25。
toString收件人的电子邮件地址作为 模式。将触发事件重新评估为每个外发电子邮件的输入。可以通过用逗号分隔目标地址来指定多个收件人。或者,也可以使用多个<to> 元素指定多个收件人
fromStringSMTPAppender通常的电子邮件地址格式发送的电子邮件的发起人 。如果您希望包含发件人的姓名,请使用格式“Adam Smith&lt; smith@moral.org&gt;” 以便该消息显示为源自“Adam Smith <smith@moral.org>”。
subjectString

电子邮件的主题。它可以是PatternLayout被接受为有效转换模式的任何值。布局将在下一章讨论。

外发电子邮件消息将具有与在触发电子邮件消息的记录事件上应用模式相对应的主题行。

假设主题选项设置为“Log:%logger - %msg”,并且触发事件的记录器名为“com.foo.Bar”,并且包含消息“Hello world”,则外发电子邮件将具有主题行“日志:com.foo.Bar - Hello World“。

默认情况下,此选项设置为“%logger {20} - %m”。

discriminatorDiscriminator

在Discriminator的帮助下, SMTPAppender可以根据鉴别器返回的值将传入事件分散到不同的缓冲区中。默认鉴别符总是返回相同的值,以便所有事件使用相同的缓冲区。

通过指定除默认值以外的鉴别符,可以接收包含与特定用户,用户会话或客户端IP地址有关的事件的电子邮件消息。

evaluator(类似与触发器)IEvaluator

这个选项是通过创建一个新<EventEvaluator/>元素来声明的 。用户希望作为使用的类的名字 SMTPAppenderEvaluator需要通过指定类 属性。

如果没有此选项,SMTPAppender 则会分配一个OnErrorEvaluator实例, 当它遇到级别为ERROR或更高级别的事件时触发电子邮件传输。

Logback附带有其他几个评估者,即OnMarkerEvaluator (下面将讨论)和一个强大的评估者JaninoEventEvaluator,在另一章中讨论。最近版本的logback ship配有一个更强大的评估器GEventEvaluator

cyclicBufferTrackerCyclicBufferTracker

正如名称所示,CyclicBufferTracker类的一个实例 跟踪循环缓冲区。它基于鉴别器返回的键(见上)。

如果不指定cyclicBufferTracker,实例CyclicBufferTracker 将自动创建。默认情况下,这个实例会将事件保存在一个大小为256的循环缓冲区中。您可以在bufferSize选项的帮助下更改大小(请参阅下文)。

usernameString在普通用户/密码认证期间使用的用户名值。默认情况下,此参数为空。
passwordString用于普通用户/密码身份验证的密码值。默认情况下,此参数为空。
STARTTLSboolean如果此参数设置为true,则此appender将发出STARTTLS命令(如果服务器支持它)导致连接切换到SSL。请注意,连接最初是未加密的。默认情况下,此参数设置为false。
SSLboolean如果此参数设置为true,则此appender将打开到服务器的SSL连接。默认情况下,此参数设置为false。
charsetEncodingString传出的电子邮件消息将被编码到指定的字符集中。默认的字符集编码是“UTF-8”,适用于大多数用途。
本地主机String如果SMTP客户端的主机名未正确配置,例如,如果客户端主机名未完全限定,某些SMTP服务器可能会拒绝客户端发送的HELO / EHLO命令。要解决此问题,可以将localhost 属性的值设置为客户端主机的完全限定名称。另请参阅com.sun.mail.smtp 包的文档中的“mail.smtp.localhost”属性。
asynchronousSendingboolean该属性确定电子邮件传输是否异步完成。默认情况下,asynchronousSending属性为'true'。但是,在某些情况下,异步发送可能不合适。例如,如果您的应用程序使用SMTPAppender发送警报来响应致命错误,然后退出,则相关线程可能没有时间发送警报电子邮件。在这种情况下,将asynchronousSending属性设置为'false'以进行同步电子邮件传输。
includeCallerDataboolean默认情况下,includeCallerData设置为false。你应该设置includeCallerData到true如果 asynchronousSending已启用,您希望包括在日志中呼叫者数据。
sessionViaJNDIbooleanSMTPAppender依靠 javax.mail.Session发送电子邮件。默认情况下,sessionViaJNDI被设置为 false使得javax.mail.Session 实例SMTPAppender由用户指定的属性自行构建。如果sessionViaJNDI属性设置为 true,则该javax.mail.Session对象将通过JNDI检索。另请参阅jndiLocation属性。

检索Session通过JNDI可以减少您需要配置/重新配置相同的信息名额,使您的应用。有关在Tomcat中配置资源的更多信息,请参阅JNDI资源操作指南。当心如该文档中所述,确保在从JNDI 获取JNDI 时,从Web应用程序WEB-INF / lib文件夹中 删除mail.jar 和activation.jar。 Session

jndiLocationStringjavax.mail.Session放置在JNDI中的位置。默认情况下,jndiLocation设置为“java:comp / env / mail / Session”。

SMTPAppender在循环缓冲区只保留最后256个日志事件,扔掉旧的事件时,它的缓冲区已满。因此,通过发送的任何电子邮件传递的日志记录事件的数量SMTPAppender上限为256. SMTPAppender依靠了JavaMail API

 

<configuration>   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>ADDRESS-OF-YOUR-SMTP-HOST</smtpHost>
    <to>EMAIL-DESTINATION</to>
    <to>ANOTHER_EMAIL_DESTINATION</to> <!-- additional destinations are possible -->
    <from>SENDER-EMAIL</from>
    <subject>TESTING: %logger{20} - %m</subject>
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%date %-5level %logger{35} - %message%n</pattern>
    </layout>       
  </appender>

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

 

<configuration>   
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <smtpHost>${smtpHost}</smtpHost>
    <to>${to}</to>
    <from>${from}</from>
    <subject>%logger{20} - %m</subject>
    <layout class="ch.qos.logback.classic.html.HTMLLayout"/>

    <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
      <!-- send just one log entry per email -->
      <bufferSize>1</bufferSize> 指定缓冲器大小
    </cyclicBufferTracker>
  </appender>

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

 

触发email事件

public class CounterBasedEvaluator extends ContextAwareBase implements EventEvaluator {

  static int LIMIT = 1024;
  int counter = 0;
  String name;

  public boolean evaluate(Object event) throws NullPointerException,
      EvaluationException {
    counter++;

    if (counter == LIMIT) {
      counter = 0;

      return true;
    } else {
      return false;
    }
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}
<configuration>
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <evaluator class="chapters.appenders.mail.CounterBasedEvaluator" />
    <smtpHost>${smtpHost}</smtpHost>
    <to>${to}</to>
    <from>${from}</from>
    <subject>%logger{20} - %m</subject>

    <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  </appender>

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

或者 (推荐下面的)

Marker notifyAdmin = MarkerFactory.getMarker("NOTIFY_ADMIN");
logger.error(notifyAdmin,
  "This is a serious an error requiring the admin's attention",
   new Exception("Just testing"));

 

<configuration>
  <appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
    <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
      <marker>NOTIFY_ADMIN</marker>
      <!-- you specify add as many markers as you want -->
      <marker>TRANSACTION_FAILURE</marker>
    </evaluator>
    <smtpHost>${smtpHost}</smtpHost>
    <to>${to}</to>
    <from>${from}</from>
    <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
  </appender>

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

DBAppender

<configuration>

  <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
      <driverClass>com.mysql.jdbc.Driver</driverClass>
      <url>jdbc:mysql://host_name:3306/datebase_name</url>
      <user>username</user>
      <password>password</password>
    </connectionSource>
  </appender>
  
  <root level="DEBUG" >
    <appender-ref ref="DB" />
  </root>
</configuration>
连接池
<configuration>

  <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
      <dataSource class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
        <serverName>${serverName}</serverName>
        <port>${port$</port>
        <databaseName>${dbName}</databaseName>
        <user>${user}</user>
        <password>${pass}</password>
      </dataSource>
    </connectionSource>
  </appender>
    
  <root level="DEBUG">
    <appender-ref ref="DB" />
  </root>
</configuration>

c3p0

<configuration>

  <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource
      class="ch.qos.logback.core.db.DataSourceConnectionSource">
      <dataSource
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <driverClass>com.mysql.jdbc.Driver</driverClass>
        <jdbcUrl>jdbc:mysql://${serverName}:${port}/${dbName}</jdbcUrl>
        <user>${user}</user>
        <password>${password}</password>
      </dataSource>
    </connectionSource>
  </appender>

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

Encoders

encoder interface

public interface Encoder<E> extends ContextAware, LifeCycle {

   /**
   * This method is called when the owning appender starts or whenever output
   * needs to be directed to a new OutputStream, for instance as a result of a
   * rollover.
   */
  void init(OutputStream os) throws IOException;

  /**
   * Encode and write an event to the appropriate {@link OutputStream}.
   * Implementations are free to defer writing out of the encoded event and
   * instead write in batches.
   */
  void doEncode(E event) throws IOException;


  /**
   * This method is called prior to the closing of the underling
   * {@link OutputStream}. Implementations MUST not close the underlying
   * {@link OutputStream} which is the responsibility of the owning appender.
   */
  void close() throws IOException;
}

LayoutWrappingEncoder

Layouts

负责将传入事件转换为String

Layout interface

public interface Layout<E> extends ContextAware, LifeCycle {

  String doLayout(E event);
  String getFileHeader();
  String getPresentationHeader();
  String getFileFooter();
  String getPresentationFooter();
  String getContentType();
}

PatternLayout

Conversion WordEffect
c{length
lo{length
logger{length
Outputs the name of the logger at the origin of the logging event.

This conversion word takes an integer as its first and only option. The converter's abbreviation algorithm will shorten the logger name, usually without significant loss of meaning. Setting the value of length option to zero constitutes an exception. It will cause the conversion word to return the sub-string right to the rightmost dot character in the logger name. The next table provides examples of the abbreviation algorithm in action.

Conversion specifierLogger nameResult
%loggermainPackage.sub.sample.BarmainPackage.sub.sample.Bar
%logger{0}mainPackage.sub.sample.BarBar
%logger{5}mainPackage.sub.sample.Barm.s.s.Bar
%logger{10}mainPackage.sub.sample.Barm.s.s.Bar
%logger{15}mainPackage.sub.sample.Barm.s.sample.Bar
%logger{16}mainPackage.sub.sample.Barm.sub.sample.Bar
%logger{26}mainPackage.sub.sample.BarmainPackage.sub.sample.Bar

Please note that the rightmost segment in a logger name is never abbreviated, even if its length is longer than the length option. Other segments may be shortened to at most a single character but are never removed.

C{length
class{length

Outputs the fully-qualified class name of the caller issuing the logging request.

Just like the %logger conversion word above, this conversion takes an integer as an option to shorten the class name. Zero carries special meaning and will cause the simple class name to be printed without the package name prefix. By default the class name is printed in full.

Generating the caller class information is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

contextName
cn
Outputs the name of the logger context to which the logger at the origin of the event was attached to.
d{pattern
date{pattern
d{patterntimezone
date{patterntimezone

Used to output the date of the logging event. The date conversion word admits a pattern string as a parameter. The pattern syntax is compatible with the format accepted by java.text.SimpleDateFormat.

You can specify the string "ISO8601" for the ISO8601 date format. Note that the %date conversion word defaults to the ISO 8601 date format in the absence of a pattern parameter.

Here are some sample parameter values. They assume that the actual date is Friday 20th of October, 2006 and that the author has returned to working on this document just after lunch.

Conversion PatternResult
%d2006-10-20 14:06:49,812
%date2006-10-20 14:06:49,812
%date{ISO8601}2006-10-20 14:06:49,812
%date{HH:mm:ss.SSS}14:06:49.812
%date{dd MMM yyyy;HH:mm:ss.SSS}20 oct. 2006;14:06:49.812

The second parameter specifies a timezone. For example, the '%date{HH:mm:ss.SSS, Australia/Perth} would print the time in the time zone of Perth, Australia, the world's most isolated city. Note that in the absence of the timezone parameter, the default timezone of the host Java platform is used. If the specified timezone identifier is unknown or misspelled, the GMT timezone is assumed as dictated by the TimeZone.getTimeZone(String) method specification.

COMMON ERROR Given that the comma ',' character is interpreted as the parameter separator, the pattern HH:mm:ss,SSS will be interpreted as the pattern HM:mm:ss and the timezone SSS. If you wish to include a comma in your date pattern, then simply enclose the pattern between quotes. For example, %date{"HH:mm:ss,SSS"}.

F / file

Outputs the file name of the Java source file where the logging request was issued.

Generating the file information is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

caller{depth}caller{depthStart..depthEnd}caller{depth, evaluator-1, ... evaluator-n}caller{depthStart..depthEnd, evaluator-1, ... evaluator-n}

Outputs location information of the caller which generated the logging event.

The location information depends on the JVM implementation but usually consists of the fully qualified name of the calling method followed by the caller's source, the file name and line number between parentheses.

A integer can be added to the caller conversion specifier's options to configure the depth of the information to be displayed.

For example, %caller{2} would display the following excerpt:

0    [main] DEBUG - logging statement 
Caller+0   at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1   at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)

And %caller{3} would display this other excerpt:

16   [main] DEBUG - logging statement 
Caller+0   at mainPackage.sub.sample.Bar.sampleMethodName(Bar.java:22)
Caller+1   at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)
Caller+2   at mainPackage.ConfigTester.main(ConfigTester.java:38)

A range specifier can be added to the caller conversion specifier's options to configure the depth range of the information to be displayed.

For example, %caller{1..2} would display the following excerpt:

0    [main] DEBUG - logging statement
Caller+0   at mainPackage.sub.sample.Bar.createLoggingRequest(Bar.java:17)

This conversion word can also use evaluators to test logging events against a given criterion before computing caller data. For example, using %caller{3, CALLER_DISPLAY_EVAL} will display three lines of stacktrace, only if the evaluator called CALLER_DISPLAY_EVAL returns a positive answer.

Evaluators are described below.

L / line

Outputs the line number from where the logging request was issued.

Generating the line number information is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

m / msg / message

Outputs the application-supplied message associated with the logging event.

M / method

Outputs the method name where the logging request was issued.

Generating the method name is not particularly fast. Thus, its use should be avoided unless execution speed is not an issue.

n

Outputs the platform dependent line separator character or characters.

This conversion word offers practically the same performance as using non-portable line separator strings such as "\n", or "\r\n". Thus, it is the preferred way of specifying a line separator.

p / le / levelOutputs the level of the logging event.
r / relativeOutputs the number of milliseconds elapsed since the start of the application until the creation of the logging event.
t / threadOutputs the name of the thread that generated the logging event.
X{key:-defaultVal
mdc{key:-defaultVal

Outputs the MDC (mapped diagnostic context) associated with the thread that generated the logging event.

If the mdc conversion word is followed by a key between braces, as in %mdc{userid}, then the MDC value corresponding to the key 'userid' will be output. If the value is null, then the default value specified after the :- operator is output. If no default value is specified than the empty string is output.

If no key is given, then the entire content of the MDC will be output in the format "key1=val1, key2=val2".

See the chapter on MDC for more details on the subject.

ex{depth
exception{depth
throwable{depth

ex{depth, evaluator-1, ..., evaluator-n} 
exception{depth, evaluator-1, ..., evaluator-n} 
throwable{depth, evaluator-1, ..., evaluator-n}

Outputs the stack trace of the exception associated with the logging event, if any. By default the full stack trace will be output.

The throwable conversion word can followed by one of the following options:

  • short: prints the first line of the stack trace
  • full: prints the full stack trace
  • Any integer: prints the given number of lines of the stack trace

Here are some examples:

Conversion PatternResult
%ex
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
  at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
  at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)
%ex{short}
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
%ex{full}
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
  at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)
  at mainPackage.ExceptionLauncher.main(ExceptionLauncher.java:38)
%ex{2}
mainPackage.foo.bar.TestException: Houston we have a problem
  at mainPackage.foo.bar.TestThrower.fire(TestThrower.java:22)
  at mainPackage.foo.bar.TestThrower.readyToLaunch(TestThrower.java:17)

This conversion word can also use evaluators to test logging events against a given criterion before creating the output. For example, using %ex{full, EX_DISPLAY_EVAL} will display the full stack trace of the exception only if the evaluator called EX_DISPLAY_EVAL returns a negative answer. Evaluators are described further down in this document.

If you do not specify %throwable or another throwable-related conversion word in the conversion pattern,PatternLayout will automatically add it as the last conversion word, on account of the importance of stack trace information. The $nopex conversion word can be substituted for %throwable, if you do not wish stack trace information to be displayed. See also the %nopex conversion word.

xEx{depth
xException{depth
xThrowable{depth

xEx{depth, evaluator-1, ..., evaluator-n} 
xException{depth, evaluator-1, ..., evaluator-n} 
xThrowable{depth, evaluator-1, ..., evaluator-n}

Same as the %throwable conversion word above with the addition of class packaging information.

At the end of each stack frame of the exception, a string consisting of the jar file containing the relevant class followed by the "Implementation-Version" as found in that jar's manifest will be added. This innovative technique was originally suggested by James Strachan. If the information is uncertain, then the class packaging data will be preceded by a tilde, i.e. the '~' character.

Here is an example:

java.lang.NullPointerException at com.xyz.Wombat(Wombat.java:57) ~[wombat-1.3.jar:1.3] at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.5.0_06] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.5.0_06] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.5.0_06] at java.lang.reflect.Method.invoke(Method.java:585) ~[na:1.5.0_06] at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) [junit-4.4.jar:na] at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98) [junit-4.4.jar:na] ...etc

Logback goes to great lengths to ensure that the class packaging information it displays is correct, even in arbitrarily complex class loader hierarchies. However, when it is unable to guarantee the absolute correctness of the information, then it will prefix the data with a tilde, i.e. the '~' character. Thus, it is theoretically possible for the printed class packaging information to differ from the real class packaging information. So, in the above example, given that packaging data for the Wombat class is preceded by a tilde, it is possible that the correct packaging data is in reality [wombat.jar:1.7].

Please note that given its potential cost, computation of packaging data is disabled by default. When computation of packaging data is enabled, PatternLayout will automatically assume the %xThrowable suffix instead of %throwable suffix at the end of the pattern string.

Feedback from users indicates that Netbeans chokes on packaging information.

nopex 
nopexception

Although it pretends to handle stack trace data, this conversion word does not output any data, thus, effectively ignoring exceptions.

The %nopex conversion word allows the user to override PatternLayout's internal safety mechanism which silently adds the %xThrowable conversion keyword in the absence of another conversion word handling exceptions.

marker

Outputs the marker associated with the logger request.

In case the marker contains children markers, the converter displays the parent as well as childrens' names according to the format shown below.

parentName [ child1, child2 ]

property{key}

Outputs the value associated with a property named key. The the relevant docs on how to define ion entitled define variables and variable scopes. If key is not a property of the logger context, then key will be looked up in the System properties.

There is no default value for key. If it is omitted, the returned value will be "Property_HAS_NO_KEY", expliciting the error condition.

replace(p){r, t}

Replaces occurrences of 'r', a regex, with its replacement 't' in the string produces by the sub-pattern 'p'. For example, "%replace(%msg){'\s', ''}" will remove all spaces contained in the event message.

The pattern 'p' can be arbitrarily complex and in particular can contain multiple conversion keywords. For instance, "%replace(%logger %msg){'\.', '/'}" will replace all dots in the logger or the message of the event with a forward slash.

rEx{depth
rootException{depth

rEx{depth, evaluator-1, ..., evaluator-n} 
rootException{depth, evaluator-1, ..., evaluator-n}

Outputs the stack trace of the exception associated with the logging event, if any. The root cause will be output first instead of the standard "root cause last". Here is a sample output (edited for space):

java.lang.NullPointerException
  at com.xyz.Wombat(Wombat.java:57) ~[wombat-1.3.jar:1.3]
  at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3]
Wrapped by: org.springframework.BeanCreationException: Error creating bean with name 'wombat': 
  at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:248) [spring-2.0.jar:2.0]
  at org.springframework.AbstractBeanFactory.getBean(AbstractBeanFactory.java:170) [spring-2.0.jar:2.0]
  at org.apache.catalina.StandardContext.listenerStart(StandardContext.java:3934) [tomcat-6.0.26.jar:6.0.26]

The %rootException converter admits the same optional parameters as the %xException converter described above, including depth and evaluators. It outputs also packaging information. In short, %rootException is very similar to %xException, only the order of exception output is reversed.

Tomasz Nurkiewicz, the author of %rootException converter, documents his contribution in a blog entry entitled "Logging exceptions root cause first".

 

格式修饰符

格式修饰符左对齐最小宽度最大宽度评论
%20logger20没有如果记录器名称长度小于20个字符,则留有空格。
%-20logger真正20没有如果记录器名称长度小于20个字符,请在空白处填写空格。
%.30loggerNA没有三十如果记录器名称长于30个字符,则从头开始截断。
%20.30logger20三十如果记录器名称短于20个字符,则留有空格。但是,如果记录器名称超过30个字符,则从头开始截断。
%-20.30logger真正20三十如果记录器名称少于20个字符,请在空白处填写空格。但是,如果记录器名称超过30个字符,则从头开始截断 。
%.- 30loggerNA没有三十如果记录器名称长于30个字符, 则从截断结束
格式修饰符记录器名称结果
[%20.20logger]main.Name
[main.Name]
[%-20.20logger]main.Name
[main.Name]
[%10.10logger]main.foo.foo.bar.Name
[o.bar.Name]
[%10.-10logger]main.foo.foo.bar.Name
[main.foo.f]

 Color

 

<configuration debug="true">
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- On Windows machines setting withJansi to true enables ANSI
         color code interpretation by the Jansi library. This requires
         org.fusesource.jansi:jansi:1.8 on the class path.  Note that
         Unix-based operating systems such as Linux and Mac OS X
         support ANSI color codes by default. -->
    <withJansi>true</withJansi>
    <encoder>
      <pattern>[%thread] %highlight(%-5level) %cyan(%logger{15}) - %msg %n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

ERROR的事件以粗体显示其子模式,以WARN显示红色,以INFO显示BLUE以及显示其他级别的默认颜色。

 

"%black", "%red", "%green","%yellow","%blue", "%magenta","%cyan", "%white", "%gray", "%boldRed","%boldGreen", "%boldYellow", "%boldBlue", "%boldMagenta""%boldCyan", "%boldWhite" ,"%highlight"

 

Evaluators

HTMLLayout

HTML格式生成日志

<configuration debug="true">
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
      <layout class="ch.qos.logback.classic.html.HTMLLayout">
        <pattern>%relative%thread%mdc%level%logger%msg</pattern>
      </layout>
    </encoder>
    <file>test.html</file>
  </appender>

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

Filter

LevelFilter

LevelFilter根据精确的级别匹配过滤事件。如果事件的级别等于配置的级别,则筛选器接受或拒绝该事件,具体取决于onMatch和onMismatch属性的配置

<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>INFO</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
      <pattern>
        %-4relative [%thread] %-5level %logger{30} - %msg%n
      </pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

ThresholdFilter

在低于指定阈值过滤器的事件。对于等于或高于阈值的事件,将在调用its ()方法时响应NEUTRAL 。但是,低于阈值的事件将被拒绝。

<configuration>
  <appender name="CONSOLE"
    class="ch.qos.logback.core.ConsoleAppender">
    <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>INFO</level>
    </filter>
    <encoder>
      <pattern>
        %-4relative [%thread] %-5level %logger{30} - %msg%n
      </pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

 

转载于:https://my.oschina.net/haloooooo/blog/1815673

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值