Logback學習筆記1


 

Logback介紹

Logback 分為三個模塊:CoreClassic AccessCore模塊是其他兩個模塊的基礎。 Classic模塊擴展了core模塊。 Classic模塊相當於log4j的顯著改進版。Logback-classic 直接實現了 SLF4J API

要引入logback,由於Logback-classic依賴slf4j-api.jarlogback-core.jar,所以要把slf4j-api.jarlogback-core.jarlogback-classic.jar添加到要引入Logbac日志管理的項目的class path.

 

Logback的配置

LoggerAppender Layout

Logback建立於三個主要類之上:LoggerAppender LayoutLogger類是logback-classic模塊的一部分,而AppenderLayout接口來自logback-core。作為一個多用途模塊,logback-core 不包含任何 logger

Logger作為日志的記錄器,把它關聯到應用的對應的context上后,主要用於存放日志對象,也可以定義日志類型、級別。Appender主要用於指定日志輸出的目的地,目的地可以是控制台、文件、遠程套接字服務器、 MySQL PostreSQL Oracle和其他數據庫、 JMS和遠程UNIX Syslog守護進程等。Layout 負責把事件轉換成字符串,格式化的日志信息的輸出。

 

Logger context

各個logger 都被關聯到一個 LoggerContextLoggerContext負責制造logger,也負責以樹結構排列各 logger

如果 logger的名稱帶上一個點號后是另外一個 logger的名稱的前綴,那么,前者就被稱為后者的祖先。如果 logger與其后代 logger之間沒有其他祖先,那么,前者就被稱為子logger 之父。比如,名為 "com.foo"" logger 是名為"com.foo.Bar"之父。root logger 位於 logger 等級的最頂端,root logger 可以通過其名稱取得,如下所示:

Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

其他所有logger也通過org.slf4j.LoggerFactory 類的靜態方法getLogger取得。 getLogger方法以 logger 名稱為參數。用同一名字調用LoggerFactory.getLogger 方法所得到的永遠都是同一個logger對象的引用。

    

有效級別與級別繼承

Logger 可以被分配級別。級別包括:TRACEDEBUGINFOWARN ERROR,定義於 ch.qos.logback.classic.Level類。如果 logger沒有被分配級別,那么它將從有被分配級別的最近的祖先那里繼承級別。root logger 默認級別是 DEBUG

 

打印方法與基本選擇規則

打印方法決定記錄請求的級別。例如,如果 L 是一個 logger 實例,那么,語句 L.info("..")是一條級別為 INFO 的記錄語句。記錄請求的級別在高於或等於其 logger 的有效級別時被稱為被啟用,否則,稱為被禁用。

記錄請求級別為 p,其 logger的有效級別為 q 只有則當 p>=q時, 該請求才會被執行。

該規則是 logback 的核心。級別排序為: TRACE < DEBUG < INFO < WARN < ERROR

 

LoggerAppenderslayouts的關系

一個 logger 可以被關聯多個 appender 方法 addAppender() 為指定的 logger 添加一個 appender 對於 logger 的每個啟用了的記錄請求,都將被發送到 logger 里的全部 appender 及更高等級的 appender。換句話說,appender疊加性地繼承了 logger 的層次等級。

Logger L的記錄語句的輸出會發送給 L及其祖先的全部 appender。如果 logger L的某個祖先 P設置疊加性標識為 false,那么,L的輸出會發送給L P之間(含P)的所有 appender,但不會發送給P的任何祖先的appender

Logger 的疊加性默認為 true。如果希望定制輸出格式。這時為 appender 關聯一個 layout 即可。Layout 負責根據用戶意願對記錄請求進行格式化,appender 負責將格式化化后的輸出發送到目的地。

例如,轉換模式"%-4relative [%thread] %-5level %logger{32} - %msg%n" PatternLayout里會輸出形如:

176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.

第一個字段是自程序啟動以來的逝去時間,單位是毫秒。

第二個地段發出記錄請求的線程。

第三個字段是記錄請求的級別。

第四個字段是與記錄請求關聯的 logger 的名稱。

"-"之后是請求的消息文字。

 

Logback的默認配置

如果配置文件 logback-test.xml logback.xml 都不存在,那么 logback 默認地會調用BasicConfigurator ,創建一個最小化配置。最小化配置由一個關聯到根 logger ConsoleAppender 組成。輸出用模式為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n PatternLayoutEncoder 進行格式化。root logger 默認級別是 DEBUG

logback配置文件

Logback 配置文件的語法非常靈活。正因為靈活,所以無法用 DTD XML schema 進行定義。盡管如此,可以這樣描述配置文件的基本結構:以<configuration>開頭,后面有零個或多個<appender>元素,有零個或多個<logger>元素,有最多一個<root>元素。

 

Logback默認配置的采用的步驟

1. 嘗試在 classpath 下查找文件 logback-test.xml

2. 如果文件不存在,則查找文件 logback.xml

3. 如果兩個文件都不存在,logback Bas icConfigurator 自動對自己進行配置,這會導致記錄輸出到控制台。

 

假設配置文件 logback-test.xml logback.xml 都不存在,那么 logback 默認地會調用BasicConfigurator ,創建一個最小化配置。最小化配置由一個關聯到根 logger ConsoleAppender 組成。輸出用模式為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n PatternLayoutEncoder 進行格式化。還有,根 logger 默認級別是 DEBUG

最簡單的配置方法就是使用默認配置。 以下是logbackBasicConfigurator 配置的簡單例子:

package com.ttpod.chapters.configuration;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class MyApp1 {

final static Logger logger = LoggerFactory.getLogger(MyApp1.class);

public static void main(String[] args) {

logger.info("Entering application.");    //進行另一個application

Foo foo = new Foo();

foo.doIt();        //執行其它中的日志輸出方法

logger.info("Exiting application.");    //退出另一個application

}

}

該類定義了一個靜態變量 logger,然后實例化一個 Foo 對象。Foo 類如下

package com.ttpod.chapters.configuration;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class Foo {

static final Logger logger = LoggerFactory.getLogger(Foo.class);

public void doIt() {

logger.debug("Did it again!");    //定義一個debug級別的日志輸出

}

    …………

}

 

自動打印警告和錯誤消息

當解析配置文件有警告或出錯時,logback 會在控制台上自動打印狀態數據。如果沒有警告或錯誤,還是想檢查 logback 的內部狀態的話, 可以調用 StatusPrinter print()方法。示例如下:

final static Logger logger = LoggerFactory.getLogger(MyApp2.class);

public static void main(String[] args) {

// 在當前環境中假設 SLF4J 已經被綁定到logback

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();

// 打印logback的內部狀態

StatusPrinter.print(lc);

…………

}

}

對應的配置文件:

<?xml version="1.0" encoding="UTF-8" ?>

<configuration>

<!--定義一個名為STDOUTappender,並將其關聯到ch.qos.logback.core.ConsoleAppender-->

<appender name="STDOUT"

class="ch.qos.logback.core.ConsoleAppender">

<!-- encoders 作用是將logger事件轉換成字節數組,並將字節數組寫入到輸出流-->

<encoder>

    <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度

%msg:日志消息,%n是換行符-->

<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>

</encoder>

</appender>

<root level="debug">    <!-- root logger,定義級別為debug-->

<appender-ref ref="STDOUT" />    <!--將名為STDOUTappender添加到root logger-->

</root>

</configuration>

控制台輸出結果如下:

…………

20:12:33,359 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]

20:12:33,359 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]

20:12:33,359 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/D:/Workspaces/MyEclipse%208.5/logback_test/WebRoot/WEB-INF/classes/logback.xml]

20:12:33,484 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]

20:12:33,484 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]

20:12:33,500 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property

20:12:33,593 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG

20:12:33,593 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]

20:12:33,593 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.

20:12:33,593 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@cb6009 - Registering current configuration as safe fallback point

…………

 

Logback自定義配置

配置root logger

<root>元素配置根 logger。該元素有一個 level屬性。沒有 name 屬性,因為已經被命名為"ROOT" Level 屬性的值大小寫無關,其值為下面其中一個字符串:TRACEDEBUGINFOWARNERRORALL OFF。注意不能設置為"INHERITED" "NULL" <logger>元素可以包含零個或多個<appender-ref>元素。<logger>元素類似,聲明<root>元素后,會先關閉然后移除全部當前 appender,只引用聲明了的 appender。如果 root 元素沒有引用任何 appender,就會失去所有 appender

假設我們不想看到"com.ttpod.file"包里的任何組件的任何 DEBUG 信息,可以設置如下:

<?xml version="1.0" encoding="UTF-8" ?>

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

    <!-- 設置configuration下的logger的級別為INFO,默認是繼承root loggerdebug級別 -->

    <logger name="chapters.configuration" level="INFO" />

    <!-- 嚴格來說, root logger level屬性沒有必要設置,因為 -->

    <!-- root logger的級別被默認設置為DEBUG -->

    <root level="DEBUG">

        <!--

         root標簽內沒有引入chapters.configuration,所有在此包下不會

        顯示任何組件的任何 DEBUG 信息

        -->

        <appender-ref ref="STDOUT" />    <!-- appender引入到root logger -->

    </root>

</configuration>

注意:由名為"chapters.configuration.Foo" logger 生成的 DEBUG 級別的信息都被屏蔽了.同樣,也可以為任意數量的 logger 設置級別。

配置 Appenders

Appender <appender>元素配置,該元素必要屬性 name class name 屬性指定 appender 的名稱,class 屬性指定 appender 類的全限定名。 <appender>元素可以包含零個或多個<layout>元素、零個或多個<encoder>元素和零個或多個<filter>元素。除了這三個常用元素之外,還可以包含 appender 類的任意數量的 javabean

屬性。下圖演示了常用結構,注意對 javabean 屬性的支持在圖中不可見。

 

記錄輸出到多個 appender 很簡單,先定義各種 appender,然后在 logger 里進行引用,就行了。如下面的配置文件所示:

<configuration>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">

        <file>myApp.log</file>

<!-- encoders are assigned by default the type

ch.qos.logback.classic.encoder.PatternLayoutEncoder -->

<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,輸出了日期、級別、線程名、logger 名、文件名及記錄請求的行號、消息和行分隔符。 "STDOUT"這個 appender 把記錄輸出到控制台,它的 encoder 只是輸出消息和行分隔符。 myApp.log文件內容如下:

2011-12-25 16:56:48,593 INFO [main] c.t.c.c.MyApp3 [MyApp3.java:48] Entering application.

2011-12-25 16:56:48,593 DEBUG [main] c.t.c.c.Foo [Foo.java:24] Did it again!

2011-12-25 16:56:48,593 INFO [main] c.t.c.c.MyApp3 [MyApp3.java:52] Exiting application.

    注意每個 appender 都有自己的 encoderEncoder 通常不能被多個 appender 共享,layout也是。所以,logback 的配置文件里沒有共享 encoder layout 的語法。

Appender累積

默認情況下,appender 是可累積的: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>

輸出結果如下:

20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Entering application.

20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Entering application.

20:53:29.328 [main] DEBUG com.ttpod.chapters.configuration.Foo - Did it again!

20:53:29.328 [main] DEBUG com.ttpod.chapters.configuration.Foo - Did it again!

20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Exiting application.

20:53:29.328 [main] INFO c.t.chapters.configuration.MyApp2 - Exiting application.

 

覆蓋默認的累積行為

如果你覺得默認的累積行為不合適,可以設置疊加性標識為 false 以關閉它。 這樣的話,logger 樹里的某個分支可以輸出到與其他 logger 不同的 appender

示例:疊加性標識

<configuration>

    …………

    <logger name="com.ttpod.chapters.configuration.Foo" additivity="false">

        <appender-ref ref="FILE" />

    </logger>

    <root level="debug">

        <appender-ref ref="STDOUT" />

    </root>

</configuration>

輸出結果:

Entering application.

Exiting application.

此例中,logger"chapters.configuration.Foo"關聯 appender"FILE",它的疊加性標記為false,這樣它的記錄輸出僅會被發送到 appender"FILE",不會被發送到更高 logger 等級關聯的 appender。其他 logger 不受此影響。 additivityFlag.xml 配置 MyApp3 由"chapters.configuration.MyApp3"產生的記錄。而 logger" chapters.configuration.Foo"將且僅僅將輸出到文件 foo.log

Layout格式化輸出日志

配置自定義 layout

配置自定義layout與配置其他layout是一樣的。 FileAppender和其子類需要一個encoder。如鏈接中的例子:http://logback.qos.ch/xref/chapters/layouts/MySampleLayout.html

    此類中定義了一個處理格式的輸出類,為了滿足自定義的格式化的輸出,把包裹了 MySampleLayout LayoutWrappingEncoder 實例傳遞給FileAppender。下面是配置文件:

<configuration debug="true">

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">

     <!—自定義的格式化輸出處理類-->

<layout class="com.ttpod.chapters.layouts.MySampleLayout" />

</encoder>

</appender>

<root level="DEBUG">

<appender-ref ref="STDOUT" />

</root>

</configuration>

輸出結果如下:

250 DEBUG [main] com.ttpod.chapters.introduction.HelloWorld1 - Hello world.

 

layout轉換符

它和C語言的printf方法非常類似。格式轉換由普通字符和轉換字符組合而成。轉換字符由%開始,緊跟着的是可選的格式修飾符和轉換字符標示。使用%前綴的表示符號將被轉換到實際的內容。如name, level, date, thread name.可用的轉換符有:

轉換符

描述

c 

調用日志事件的所在記錄器的名字,如一個logger的名字是my.test.bbb.ccc,調用的是WARN級別的日志輸出,那么輸出的是輸出my.test.bbb.ccc,可以在其右邊指定了精度,如%c{2}那么輸出的是bbb.ccc

C 

調用日志事件的所在的類名,和c轉換符一樣,可以在右邊指定寬度,如%C{2}輸出%C{2}

d 

日志調用所發生的時間,日期格式在其后跟着的大括號內的格式指定如%d{yyyy-MM-dd HH:mm:ss},我現在輸出的結果是2011-07-11 21:05:22,推薦使用的是log4j本身提供的日期格式,如%d{ISO8601}%d{ABSOLUTE}%d{DATE}

F 

所處所在文件名,如上面說C轉換符的例子,輸出結果是LayoutTest.java

l 

是的日志事件發生的位置信息,這個和虛擬機的實現有點關系,一般境況下能得到類,方法,行數源文件等信息,

L 

只是輸出觸發日志事件代碼所在的行號,性能損耗會小很多。

m 

顯示應用給日志提供的其他信息,如消息。logger.warn("Message 2");那么%m將得到的是Message 2

M 

輸出調用者所在的方法名

n 

換行,和\r \r\n有相同功能,能識別系統的換行符,自動轉換成\r或者\r\nlog4j推薦使用這個轉換符,而不是\r或者\r\n

p 

輸出調用的日志的級別,如我是調用logger.debug方法,那么級別就是debug

r 

輸出自應用啟動后第一次調用logger的日志輸出方法,到輸出該log信息耗費的毫秒數

t 

輸出所在線程的名字

x 

輸出產生的日志事件的線程的NDC(嵌套診斷上下文)

X 

輸出與生成的日志事件的線程關聯的MDC(映射診斷上下文)。X轉換符括號之間放置了一個key,就像在%X {clientNumber}中的clientNumberkey 一樣。在MDC correspondingvalue將被輸出。

% 

寫上%%后將直接輸出一個%符號

 

layout格式修飾符

如給定的一個格式:%-5p [%t]: %m%n中,並沒有明確的分隔轉換字符和普通文本的字符存在。PatternLayout能自己區分普通文本和轉換字符。其中%-5p是日志的調用級別。事件是左對齊的,5個字符寬度。

格式修飾符,放在%和轉換符之間。 第一個可選的格式修飾符是左對齊(-);第二個可選的格式修飾符是字段最小寬度。一個整數。表示輸出的最小字符數。如果數據未達到指定最小大小,那么它將以左填充(默認)或者右填充方式(左對齊情況下只能使用右填充了)。用空格填充,直到達到最小寬度。如果大於指定最小寬度,不會被截斷 。當然可以指定最大字符數,使用.符號加數字表示最大字符數。如果大於指定長度,多余的字符會被刪除。它是從前面刪除,而不是從后面刪除的。如最大字符是8個,數據有10個字符,那么前面兩個字符會被刪除。 

%20c 右對齊,最少20字符,沒有左邊用空格填充 

%-20c 左對齊,最少20字符,沒有右邊用空格填充 

%.30c 右對齊,最多30字符,超過左邊的截取掉 

%20.30c 右對齊,最少20字符,最多30字符,填充或截取規則略

%-20.30c 左對齊,最少20字符,最多30字符,填充或截取規則略 

 

在程序里啟用logback記錄

三個必須步驟:

1. 配置 logback 環境。

2. 在每個需要執行記錄的類里,調用 org.slf4j.LoggerFactory 類的 getLogger()方法獲

取一個 Logger 實例,以當前類名或類本身作為參數。

3. 調用取得的 logger 實例的打印方法,即 debug()info()warn() error(),把記錄

輸出到配置里的各 appender

直接調用JoranConfigurator

Logback 依賴JoranJoran logback-core 的一部分,是個配置類庫。Logback 的默認配置機制是調用JoranConfiguratorclasspath上的默認配置文件進行處理。 不管出於什么理由,如果你想重新實現 logback 的默認配置機制的話,你可以直接調用 JoranConfigurator。下面程序 MyApp1 就調用了 JoranConfigurator 對作為參數傳入的配置文件進行處理。

示例1

(com/ttpod/file/ MyApp1.java)

package com.ttpod.file;

import org.slf4j.Logger;                //用於聲明Logger

import org.slf4j.LoggerFactory;     //用於獲取Logger以及LoggerContext

import ch.qos.logback.classic.LoggerContext;         //用於聲明LoggerContext

import ch.qos.logback.classic.joran.JoranConfigurator; //用於定義Logback的配置機制

import ch.qos.logback.core.joran.spi.JoranException; //用於定義JoranException

import ch.qos.logback.core.util.StatusPrinter; //用於打印logback的內部狀態

public class MyApp1 {

final static Logger logger = LoggerFactory.getLogger(MyApp1.class);    //定義一個全局的記錄器,通過LoggerFactory獲取

public static void main(String[] args) {

    //通過getILoggerFactory()方法得到logger上下文件環境,logback默認獲得當前應用的logger context

LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();    //得到當前應用中logger上下文

try {

JoranConfigurator configurator = new JoranConfigurator();    //定義一個(JoranConfigurator)配置器

configurator.setContext(context);    //將當前應用的logger context的關聯到到configurator對象

context.reset();                        //清除以前的配置器中的所有內容

//configurator.doConfigure(args[0]);    //接收從命令行傳入的參數,加載配置文件,並設置到配置器

configurator.doConfigure("src/com/ttpod/file/MyApp1Config.xml");

//配置文件的路徑:src/com/ttpod/file/MyApp1Config.xml

} catch (JoranException je) {

logger.error("JoranException occur at:"+je.getMessage());    //將此處異常也記錄到日志

je.printStackTrace();    //在控制打印出異常跟蹤信息

}

//打印出logger context中的error和供氣ing,在此處作用相當於catch中的je.printStackTrace();

StatusPrinter.printInCaseOfErrorsOrWarnings(context);    

//流程進入有日志生成的類中

logger.info("Entering application.demo class Foo >>>");    

Foo foo = new Foo();

foo.doIt();    //執行foo中的一個生成了日志的方法,輸出日志

logger.info("Exiting application. demo class Foo <<<");

}

}

其它類Foo類,代碼如下:

(com/ttpod/file/ Foo.java)

package com.ttpod.file;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class Foo {

static final Logger logger = LoggerFactory.getLogger(Foo.class);

public void doIt() {

logger.debug("test logger in other class!");

}

public void createLoggingRequest() {

     subMethodToCreateRequest();

     }

     //這個方法執行后創建一條異常信息

private void subMethodToCreateRequest() {

logger.error("error-level request", new Exception("test exception"));

}

}

此程序通過參數傳配置文件的名字,對程序的日志輸出配置,本例如下:

(com/ttpod/file/ MyApp1Config.xml)

<configuration>

<!-- 指定屬性文件路徑 -->

<property file="src/com/ttpod/file/variables.properties" />

 

<!-- 指定日志輸出到文件-->

<appender name="FILE" class="ch.qos.logback.core.FileAppender">

<file>${destination}</file>

<encoder>

<!-- %msg表示日志信息,%n表示換行 -->

<pattern>%msg%n</pattern>

</encoder>

</appender>

 

<root level="debug">

<appender-ref ref="FILE" /><!—添加到根logger-->

</root>

</configuration>

對應的properties文件,嵌套的設置了日志文件的輸出路徑及文件名,如下:

(com/ttpod/file/ variables.properties)

#指定USER_HOME目錄

USER_HOME=./log

 

#指定日志文件名

fileName=myApp.log

 

#生成日志文件的目的地

destination=${USER_HOME}/${fileName}

配置好后,右鍵MyApp3 -> run as… -> run configurations -> 選擇MyApp3,arguments ->

配置program Agumentssrc/com/ttpod/MyApp1Config.xml,以指定配置文件,然后運行即可,即可在當前就應用的/log文件夾下生成myApp.log ,輸出如下:

Entering application.demo class Foo >>>

test logger in other class!

Exiting application. demo class Foo <<<

 

運用滾動策略與觸發策略

RollingFileAppender 繼承 FileAppender,能夠滾動記錄文件。例如,RollingFileAppender能先記錄到文件"log.txt",然后當符合某個條件時,變成記錄到其他文件。 RollingFileAppender 有兩個與之互動的重要子組件。第一個是RollingPolicy,負責滾動。第二個是 TriggeringPolicy,決定是否以及何時進行滾動。所以,RollingPolicy 負責"什么", TriggeringPolicy 負責"何時"。

要想 RollingFileAppender 起作用,必須同時設置 RollingPolicy TriggeringPolicy。不過,如果 RollingPolicy 也實現了 TriggeringPolicy 接口,那么只需要設置 RollingPolicy

示例2

如下測試程序應用滾動與觸發策略,來處理日志文件。

com/ttpod/file/MyApp2.java

package com.ttpod.file;

import java.util.Date;

public class MyApp2 {

    static Timer t;

    public static void main(String[] args) {

        // 調用LoggerFactory 類的靜態方法getLogger取得一個Logger實例,

        final Logger logOut = LoggerFactory.getLogger("SystemOut"); // 定義一個名為SystemOutlogger

        final Logger logErr = LoggerFactory.getLogger("SystemErr"); // 定義一個名為SystemErrlogger

        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();

        try {

            JoranConfigurator configurator = new JoranConfigurator();

            configurator.setContext(lc);

            lc.reset();

            //configurator.doConfigure(args[0]);

            configurator.doConfigure("src/com/ttpod/file/logback.xml");

        } catch (JoranException je) {

            je.printStackTrace();

        }

        // 打印logback的內部狀態

        StatusPrinter.print(lc);    //固定部分

        t = new Timer(); // 定義一個定時器

        TimerTask tt = new TimerTask() { // 用定義器執行計划(schedule),並定義一個繼承了TimerTask的匿名內部類

            @Override

            public void run() {

                for (int i = 100; i > 0; i--) {

                    // Timer t=null;

                    MyApp2.t.cancel();

                    logOut.info("測試Logback日志的使用"); // 定義了一個info級別的日志消息

                    logErr.error("發生錯誤"); // 定義了一個error級別的日志消息

                }

                System.out.println("~~~~~~~~~~~~~ ");

            }

        };

        t.schedule(tt, new Date(), 50); // 從當前系統時間開始,每50毫秒執行一次計划

    }

}

 

// 沒有自定義它的logback所需的配置文件,程序啟動時會自動加載classpath目錄下的查找

// logback-test.xml;如果沒找到則logback-test.xml,則繼續在classpath下查找lobback.xml

此測試類,在定時器中定義了一個執行計划,按照執行計划生成日志文件。在file包中添加相的logback配置文件,如下:

(com/ttpod/file/logback.xml)

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration>

<configuration>

<jmxConfigurator />

<!-- 配置文件路徑 -->

<property file="src/com/ttpod/file/variables.properties" />

<!--logback的版本必須是0.9.21以上才支持-->

<timestamp key="byDay" datePattern="yyyyMMdd"/>

<!-- 控制台輸出日志 -->

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

<layout class="ch.qos.logback.classic.PatternLayout">

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>

</layout>

</appender>

<!-- 文件輸出日志 (文件大小策略進行文件輸出,超過指定大小對文件壓縮(.zip)備份)-->

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

    <!-- 文件的路徑及文件名 -->

<File>${USER_HOME}/SystemOut.log</File>

<!-- 定義窗口滾動策略 -->

<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">

    <!-- 每觸發一次,自動壓縮日志文件,%i1-3之間循環變化 -->

<FileNamePattern>${USER_HOME}/SystemOut_%i.log.zip</FileNamePattern>

<MinIndex>1</MinIndex> <!-- %i的最小值為1-->

<MaxIndex>3</MaxIndex> <!-- %i的最大值為3-->

</rollingPolicy>

<!-- 觸發策略,通常rollingPolicytriggeringPolicy聯合使用 -->

<triggeringPolicy

class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

<MaxFileSize>10KB</MaxFileSize>

</triggeringPolicy>

<!-- 格式化輸出 -->

<!-- %d表示日期,格式為:yyyy-MM-dd HH:mm:ss.SSS ;%thread:線程名;

    %-5level:從左邊以5個字符的寬度顯示級別; %logger:顯示logger;%msg:日志消息;%n:換行

<layout class="ch.qos.logback.classic.PatternLayout">

<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>

</layout>

-->

<!-- 或者用下面的形式格式(推薦)-->

<encoder>

        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}%relative%thread%mdc%level%logger%msg</pattern>

        </encoder>

<!-- html文件輸出 -->

<!--

<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">

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

            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}%relative%thread%mdc%level%logger%msg</pattern>

        </layout>

        </encoder>

-->

</appender>

<!-- 輸出ERROR級別的日志到文件(同樣采用文件大小策略進行文件輸出,超過指定大小對文件壓縮(.zip)備份) -->

<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">

<filter class="ch.qos.logback.classic.filter.LevelFilter">

<level>ERROR</level> <!-- 指定要對級別為ERROR日志信息過濾 -->

<OnMismatch>DENY</OnMismatch>     <!-- 如果不匹配,則拒絕處理 -->

<OnMatch>ACCEPT</OnMatch>         <!-- 如果匹配,則立即處理 -->

</filter>

<File>${USER_HOME}/SystemErr.log</File> <!-- 文件名即路徑 -->

<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">

<FileNamePattern>${USER_HOME}/SystemErr_%i.log.zip</FileNamePattern>

<MinIndex>1</MinIndex>

<MaxIndex>3</MaxIndex>

</rollingPolicy>

<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

<MaxFileSize>10KB</MaxFileSize>

</triggeringPolicy>

<!-- 格式化輸出 -->

<!--

<layout class="ch.qos.logback.classic.PatternLayout">

<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>

</layout>

-->

<encoder>

        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}%relative%thread%mdc%level%logger%msg</pattern>

        </encoder>

</appender>

<!--這里指定logger name 是為jmx設置日志級別做鋪墊 -->

<!-- 分別將STDOUTFILE appender都添加到自定義的logger中,否則將不會輸出到appender指定的 目的地-->

<logger name="SystemOut" level="INFO">

<appender-ref ref="STDOUT" />

<appender-ref ref="FILE" />

</logger>

<logger name="SystemErr" level="INFO">

<appender-ref ref="STDOUT" />

<appender-ref ref="FILE-ERROR" />

</logger>

</configuration>

執行以上程序,在控制台也會不斷的輸出以下日志信息:

14:42:34.875 [Timer-0] INFO SystemOut - 測試Logback日志的使用

14:42:34.875 [Timer-0] ERROR SystemErr - 發生錯誤

14:42:34.937 [Timer-0] INFO SystemOut - 測試Logback日志的使用

14:42:34.937 [Timer-0] ERROR SystemErr - 發生錯誤

14:42:35.000 [Timer-0] INFO SystemOut - 測試Logback日志的使用

14:42:35.000 [Timer-0] ERROR SystemErr - 發生錯誤

14:42:35.062 [Timer-0] INFO SystemOut - 測試Logback日志的使用

14:42:35.062 [Timer-0] ERROR SystemErr - 發生錯誤

生成的日志文件如下圖:

 

FixedWindowRollingPolicy當發生滾動時,FixedWindowRollingPolicy 根據如下固定窗口(window)算法重命名文件。 選項"fileNamePattern"代表歸檔(滾動)記錄文件的文件名模式。該選項是必需的,且必需在模式的某處包含標志"%i"。如示例3中的MyApp3-RollingFixedWindow.xml

TimeBasedRollingPolicy 或許是最受流行的滾動策略。它根據時間來制定滾動策略,例如根據日或月。TimeBasedRollingPolicy 既負責滾動也負責觸發滾動。實際上,TimeBasedRollingPolicy 同時實現了 RollingPolicy 接口和 TriggeringPolicy 接口。和 FixedWindowRollingPolicy一樣,TimeBasedRollingPolicy 也支持自動壓縮文件。如果"fileNamePattern"選項以".gz"或".zip"結尾,就表示需要壓縮。如示例3中的MyApp3-RollingTimeBased.xml

SizeAndTimeBasedFNATP按照日期進行歸檔的同時限制每個記錄文件的大小,特別是當后處理工具對記錄文件大小有限制時。Logback 為此提供了 SizeAndTimeBasedFNATP ,它是TimeBasedRollingPolicy 的子組件,FNATP 代表"FNATP stands for File Naming And Triggering Policy"。 下面的例子MyApp3-sizeAndTime.xml演示了基於大小和時間的記錄文件歸檔。

 

示例3

(com/ttpod/file/MyApp3.java)

package com.ttpod.file;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.slf4j.MDC;

 

import ch.qos.logback.classic.LoggerContext;

import ch.qos.logback.classic.joran.JoranConfigurator;

import ch.qos.logback.core.joran.spi.JoranException;

import ch.qos.logback.core.util.StatusPrinter;

import com.ttpod.file.Foo;;

 

public class MyApp3 {

public static void main(String[] args) throws InterruptedException {

Logger logger = (Logger) LoggerFactory.getLogger(MyApp3.class);

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();

try {

JoranConfigurator configurator = new JoranConfigurator();

configurator.setContext(lc);

lc.reset();

configurator.doConfigure(args[0]);

} catch (JoranException je) {

je.printStackTrace();

}    //固定部分

 

//打印logback的內部狀態

StatusPrinter.print(lc);

logger.debug("**Hello {}", new Foo());

//客戶端的每個記錄請求添加唯一戳(uniquely stamp,運用MDC(Mapped Diagnostic Context)

//在分布式應用程序中,可以區分並處理不同客戶端的記錄輸出,而不增加logger的開銷

MDC.put("testKey", "testValueFromMDC");        //appender中用%X{testKey},可以輸出MDCtest對應的值

MDC.put("testKey2", "value2");

for (int i = 0; i < 10; i++) {

logger.debug("logging statement " + i);

Thread.sleep(100);

}

Foo foo = new Foo();

foo.createLoggingRequest();

}

}

配置文件:

(com/ttpod/file/MyApp3-RollingFixedWindow.xml)

<configuration>

<!-- 指定屬性文件路徑 -->

<property file="src/com/ttpod/file/variables.properties" />

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<file>${USER_HOME}/testFile.log</file>

<!--滾動策略-->

<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">

<!—自動壓縮備份-->

<fileNamePattern>${USER_HOME}/testFile.%i.log.zip</fileNamePattern>

<minIndex>1</minIndex>

<maxIndex>3</maxIndex><!--%i1-3之間循環變化-->

</rollingPolicy>

<!—觸發策略-->

<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

<!--日志文件大小限制在5kB以內,否則就觸發滾動-->

<maxFileSize>5kB</maxFileSize>

</triggeringPolicy>

<encoder><!--格式化輸出-->

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

</encoder>

</appender>

<root level="DEBUG">

<appender-ref ref="FILE" />

</root>

</configuration>

多次運行MyApp3,logback配置參數傳入MyApp3-RollingFixedWindow.xml,即可發現在當前應用的log目錄下生成了如:testFile.1.log.ziptestFile.2.log.ziptestFile.3.log.ziptestFile.log文件。備份的壓縮文件中的日志文件的文件名默認后綴跟了歸檔日期,如下圖:

 

(com/ttpod/file/MyApp3-RollingTimeBased.xml)

<configuration>

<!-- 指定屬性文件路徑 -->

<property file="src/com/ttpod/file/variables.properties" />

 

<!-- 基於時間的滾動策略 -->

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">

<file>${USER_HOME}/logFile.log</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!-- 每天滾動

<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

-->

 

<!-- 每分鍾滾動 -->

<fileNamePattern>${USER_HOME}/logFile.%d{yyyy-MM-dd_HH-mm}.log</fileNamePattern>

 

<!-- 限制文件最大保存時間為30-->

<maxHistory>30</maxHistory>

</rollingPolicy>

 

<encoder>

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

</encoder>

</appender>

 

<root level="DEBUG">

<appender-ref ref="FILE" />

</root>

</configuration>

<!--

運行:

java chapters.appenders.ConfigurationTester

src/com/ttpod/chapters/appenders/conf/logback-RollingTimeBased.xml

-->

多次運行MyApp3,logback配置參數傳入MyApp3-RollingTimeBased.xml,若設置一個執行計謀,程序不停止,則每分鍾可觸發一次日志備份,即可發現在當前應用的log目錄下生成了按配置的格式的文件,如:

 

(com/ttpod/file/MyApp3-sizeAndTime.xml)

<configuration>

<!-- 基於時間與大小的歸檔 -->

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

 

<!-- 指定屬性文件路徑 -->

<property file="src/com/ttpod/file/variables.properties" />

 

<!-- 基於時間與大小的歸檔 -->

<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">

<file>${USER_HOME}/mylog.txt</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!-- 每天滾動

<fileNamePattern>${USER_HOME}/mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>

-->

<minIndex>1</minIndex>

<maxIndex>3</maxIndex>

<!-- 每分鍾滾動 -->

<fileNamePattern>${USER_HOME}/mylog-%d{yyyy-MM-dd_HH-mm}.%i.txt</fileNamePattern>

 

<!-- 限制文件最大保存時間為30-->

<maxHistory>30</maxHistory>

<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">

<!-- 當文件大小超過5kB時觸發滾動,這里設置5kb只是便於測試 -->

<maxFileSize>5kB</maxFileSize>

</timeBasedFileNamingAndTriggeringPolicy>

</rollingPolicy>

<encoder>

<pattern>%msg%n</pattern>

</encoder>

</appender>

 

<root level="debug">

<appender-ref ref="ROLLING" />

</root>

</configuration>

運行時,logback配置參數傳入src/com/ttpod/file/MyApp3-sizeAndTime.xml即可。當日志文件超過5kB時,或到另一天時,程序又被執行了,則會觸發滾動,按照此前配置規則備原來的文件。輸出的文件如下圖所示:

 

 

以網頁形式輸出日志文件

HTMLLayout logback-classic 里的 HTMLLayout 相似。 默認情況下,PatternLayout 創建包含下列數據的表格:遠程IP;日期;請求的URL;狀態嗎;Content Length

    以下有個示例,演示以HTMLLayout格式化后,以htm文件輸出日志。如下:

示例4

(com/ttpod/html/HTMLTest1.java)

package com.ttpod.html;

 

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import ch.qos.logback.classic.LoggerContext;

import ch.qos.logback.classic.joran.JoranConfigurator;

import ch.qos.logback.core.joran.spi.JoranException;

import ch.qos.logback.core.util.StatusPrinter;

 

public class HtmlTest1 {

public static void main(String[] args) throws InterruptedException {

Logger logger = LoggerFactory.getLogger(HtmlTest1.class);

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();

 

try {

JoranConfigurator configurator = new JoranConfigurator();

configurator.setContext(lc);

lc.reset();

configurator.doConfigure(args[0]);

//configurator.doConfigure("./src/com/ttpod/html/htmlLayoutConfig1.xml");

} catch (JoranException je) {

    je.printStackTrace();    //固定部分

}

StatusPrinter.printInCaseOfErrorsOrWarnings(lc);

for (int i = 0; i < 6; i++) {

if (i % 5 == 0) {

logger.warn("a warning message " + i);    //聲明一條warn級別的日志消息

     //logger.info("a warning message " + i);

} else {

logger.debug("hello world number" + i);

}

}

logger.error("Finish off with fireworks", new Exception("Just testing"));

}

}

 

用以下配置文件格式化輸出到properties文件指向的目的地。

(com/ttpod/html/htmlLayoutConfig1.xml)

<configuration>

<!-- 指定屬性文件路徑 -->

<property file="src/com/ttpod/html/variables.properties" />

 

<!-- 指定日志輸出到文件-->

<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>${destination}</file>

</appender>

 

<root level="DEBUG">

<appender-ref ref="FILE" />

</root>

</configuration>

<!-- 以以下方式運行

java com.ttpod.html.HtmlTest1 src/com/ttpod/html/htmlLayoutConfig1.xml

-->

屬性文件內容如下:

(com/ttpod/html/ variables.properties)

#指定USER_HOME目錄

USER_HOME=./log

 

#指定日志文件名

fileName=htmlTest.htm

 

#生成日志文件的目的地

destination=${USER_HOME}/${fileName}

運行html/HTMLTest1,並傳入配置參數:src/com/ttpod/html/htmlLayoutConfig1.xml,可以發現在在當前應用的/log目錄下生成一個htmlTest.htm日志文件。輸出日志結果如下圖:

 

以郵件形式輸出日志

    以郵件形式輸出日志,依賴於SMTPAppender SMTPAppender在固定大小的緩沖里積累記錄時間,當用戶指定的事件發生后,就通過email發出這些事件。默認情況下,email發送是由級別為 ERROR 或更高級別的記錄事件觸發的。

    下面的演示程序 chapters.appenders.mail.EMail,生成大量記錄消息,然后生成一個錯誤消息。該程序有兩個參數,第一個是需要生成的記錄消息的數量,第二個是 logback 配置文件。該程序生成的最后一條記錄事件,即 ERROR 級別的事件,將觸發 email的發送。

示例5

(com/ttpod/mail/Email.java)

package com.ttpod.mail;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;

import ch.qos.logback.classic.joran.JoranConfigurator;

import ch.qos.logback.core.util.StatusPrinter;

public class EMail {

static public void main(String[] args) throws Exception {

if (args.length != 2) {

usage("Wrong number of arguments.");

}

int runLength = Integer.parseInt(args[0]);

String configFile = args[1];

//int runLength = Integer.parseInt("300");

//String configFile="src/com/ttpod/mail/gmailSSL.xml";

//String configFile = "src/com/ttpod/mail/gmailSTARTTLS.xml";

//自定義配置文件,得到日志固定格式

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();

JoranConfigurator configurator = new JoranConfigurator();

lc.reset();

configurator.setContext(lc);

configurator.doConfigure(configFile);

Logger logger = LoggerFactory.getLogger(EMail.class);

for (int i = 1; i <= runLength; i++) {

if ((i % 10) < 9) {

logger.debug("This is a debug message. Message number: " + i);

} else {

logger.warn("This is a warning message. Message number: " + i);

}

}

//定義一條error級別的日志輸出

logger.error("At last an error.", new Exception("Just testing"));

//打印logger內部狀態

StatusPrinter.printInCaseOfErrorsOrWarnings(lc);

}

static void usage(String msg) {    //當參數傳入錯誤時,提供的處理慣例

System.err.println(msg);

System.err.println("Usage: java " + EMail.class.getName() +

" runLength configFile\n" +

" runLength (integer) the number of logs to generate\n" +

" configFile a logback configuration file in XML format." +

" XML files must have a '.xml' extension.");

System.exit(1);    //退出程序

}

}

 

如下配置文件從屬性文件中讀取發送郵件定義的屬性,配置由郵件輸出日志,如下:

<configuration>

<!-- 指定屬性文件的位置 -->

<property file="src/com/ttpod/mail/gmailSSL.properties" />

 

<!-- 目的指定向emailappender -->

<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">

<SMTPHost>${SMTPHOST}</SMTPHost><!-- 郵件服務器地址 -->

<SMTPPort>${SMTPPORT}</SMTPPort><!--SMTPPORT端口-->

<SSL>true</SSL>

<Username>${EMAIL_USERNAME}</Username><!-- 用戶名 -->

<Password>${EMAIL_PASSWORD}</Password><!-- 密碼 -->

 

<To>${EMAIL-DESTINATION}</To><!-- 目標接收人 -->

<To>${ANOTHER_EMAIL_DESTINATION}</To> <!-- additional destinations are possible -->

<From>${EMAIL_USERNAME}</From><!-- 發件人 -->

<Subject>TESTING: %logger{20} - %m</Subject><!-- 主題 -->

<encoder><!-- 一般采用這種方式格式化輸出 -->

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

        <!-- 采用什么渲染方式,這采取的是HTML方式 -->

        <Pattern>%date %-5level %logger - %message%n</Pattern>

    </layout>

</encoder>

<!--

<layout class="ch.qos.logback.classic.PatternLayout">

<Pattern>%date %-5level %logger - %message%n</Pattern>

</layout>

-->

</appender>

 

<!-- 輸出到控制台,以便將日志也打印到控制台-->

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

 

<!-- 輸出到文件,將日志記錄到本地文件-->

<appender name="FILE" class="ch.qos.logback.core.FileAppender">

<file>./log/mailtest.log</file>

<encoder>

<!-- %msg表示日志信息,%n表示換行 -->

<pattern>%msg%n</pattern>

</encoder>

</appender>

 

<root level="debug">

<appender-ref ref="EMAIL" />

<appender-ref ref="STDOUT" />

<appender-ref ref="FILE"></appender-ref>

</root>

</configuration>

屬性文件如下設置,以供自定的logback配置文件讀取。

SMTPHOST=smtp.gmail.com

SMTPPORT=465

EMAIL_USERNAME = someone123@gmail.com

EMAIL_PASSWORD = password123

EMAIL-DESTINATION = someone456@ttpod.com

ANOTHER_EMAIL_DESTINATION = some456@126.com

傳入配置文件參數,運行,當出現也error級別以及以上級別的日志時,就會觸發日志發送到郵件,但目前此測試例子,可能由於本地tomcat服務器緩存郵件,以致郵件無法發送到外網服務器,所以在這里沒給出具體發送成功的結果。但可以通過它生成對應的HTML文件,可以看到郵件內容,如下圖:

    如果未指定選項"Evaluator",則 SMTPAppender 被默認分配一個 OnErrorEveluatorch.qos.logback.classic.boolex.OnErrorEvaluator)實例,當遇到級別為 ERROR 或更高級別

的事件后,觸發 email 傳輸。此處最后一條消息是一個error級別的記錄,觸發了郵件的發送。

另外,還可以將日志寫入數據庫要把記錄事件寫入數據庫,依賴於DBAppender DBAppender把記錄事件寫入數據庫的三張表。三張表分別是 logging_eventlogging_event_property logging_event_exception。在使用 DBAppender 之前,這三張表必須已經被創建。關於將日志記錄寫入到數據庫中,更多可參考logback手冊中的DBAppender

    編寫此文檔參考了的以下的網站、博客。相關的chm api和參考文檔上傳在服務器\\192.168.1.201上。

Logback官方網站:http://logback.qos.ch/

Slf4j官方網站:http://www.slf4j.org/

參考博客:    Slfj + Logback 時,基本的 logback.xml 配置

            logback.xml配置如何按天輸出日志文件

            slf4j+logback配置方式,logback.groovy使用備忘

            SLF4J 的幾種實際應用模式--之二:SLF4J+Logback

            logback 學習記錄

            

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM