Logback介紹
Logback 分為三個模塊:Core、Classic 和 Access。Core模塊是其他兩個模塊的基礎。 Classic模塊擴展了core模塊。 Classic模塊相當於log4j的顯著改進版。Logback-classic 直接實現了 SLF4J API。
要引入logback,由於Logback-classic依賴slf4j-api.jar和logback-core.jar,所以要把slf4j-api.jar、logback-core.jar、logback-classic.jar,添加到要引入Logbac日志管理的項目的class path中.
Logback的配置
Logger、Appender和 Layout
Logback建立於三個主要類之上:Logger、Appender 和 Layout。Logger類是logback-classic模塊的一部分,而Appender和Layout接口來自logback-core。作為一個多用途模塊,logback-core 不包含任何 logger。
Logger作為日志的記錄器,把它關聯到應用的對應的context上后,主要用於存放日志對象,也可以定義日志類型、級別。Appender主要用於指定日志輸出的目的地,目的地可以是控制台、文件、遠程套接字服務器、 MySQL、 PostreSQL、 Oracle和其他數據庫、 JMS和遠程UNIX Syslog守護進程等。Layout 負責把事件轉換成字符串,格式化的日志信息的輸出。
各個logger 都被關聯到一個 LoggerContext,LoggerContext負責制造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 可以被分配級別。級別包括:TRACE、DEBUG、INFO、WARN 和 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。
Logger、Appenders及layouts的關系
一個 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。
最簡單的配置方法就是使用默認配置。 以下是logback用BasicConfigurator 配置的簡單例子:
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>
<!--定義一個名為STDOUT的appender,並將其關聯到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" /> <!--將名為STDOUT的appender添加到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 屬性的值大小寫無關,其值為下面其中一個字符串:TRACE、DEBUG、INFO、WARN、ERROR、ALL和 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 logger的debug級別 -->
<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 設置級別。
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 都有自己的 encoder。Encoder 通常不能被多個 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.
它和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\n,log4j推薦使用這個轉換符,而不是\r或者\r\n |
p |
輸出調用的日志的級別,如我是調用logger.debug方法,那么級別就是debug |
r |
輸出自應用啟動后第一次調用logger的日志輸出方法,到輸出該log信息耗費的毫秒數 |
t |
輸出所在線程的名字 |
x |
輸出產生的日志事件的線程的NDC(嵌套診斷上下文) |
X |
輸出與生成的日志事件的線程關聯的MDC(映射診斷上下文)。X轉換符括號之間放置了一個key,就像在%X {clientNumber}中的clientNumberkey 一樣。在MDC correspondingvalue將被輸出。 |
% |
寫上%%后將直接輸出一個%符號 |
如給定的一個格式:%-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 依賴Joran,Joran是 logback-core 的一部分,是個配置類庫。Logback 的默認配置機制是調用JoranConfigurator對classpath上的默認配置文件進行處理。 不管出於什么理由,如果你想重新實現 logback 的默認配置機制的話,你可以直接調用 JoranConfigurator。下面程序 MyApp1 就調用了 JoranConfigurator 對作為參數傳入的配置文件進行處理。
示例1
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 Aguments:src/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"); // 定義一個名為SystemOut的logger
final Logger logErr = LoggerFactory.getLogger("SystemErr"); // 定義一個名為SystemErr的logger
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">
<!-- 每觸發一次,自動壓縮日志文件,%i在1-3之間循環變化 -->
<FileNamePattern>${USER_HOME}/SystemOut_%i.log.zip</FileNamePattern>
<MinIndex>1</MinIndex> <!-- %i的最小值為1-->
<MaxIndex>3</MaxIndex> <!-- %i的最大值為3-->
</rollingPolicy>
<!-- 觸發策略,通常rollingPolicy與triggeringPolicy聯合使用 -->
<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設置日志級別做鋪墊 -->
<!-- 分別將STDOUT與FILE 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},可以輸出MDC中test對應的值
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><!--%i在1-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.zip、testFile.2.log.zip、testFile.3.log.zip,testFile.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" />
<!-- 目的指定向email的appender -->
<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 被默認分配一個 OnErrorEveluator(ch.qos.logback.classic.boolex.OnErrorEvaluator)實例,當遇到級別為 ERROR 或更高級別
的事件后,觸發 email 傳輸。此處最后一條消息是一個error級別的記錄,觸發了郵件的發送。
另外,還可以將日志寫入數據庫要把記錄事件寫入數據庫,依賴於DBAppender ,DBAppender把記錄事件寫入數據庫的三張表。三張表分別是 logging_event、logging_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 學習記錄