Tuesday, June 05, 2012編寫(xiě)
1、 如何替換現(xiàn)有的log4j 現(xiàn)有項(xiàng)目:
去掉slf4j-log4j.jar和log4j.jar,添加logback-core.jar、logback-classical.jar。然后刪除log4j.xml并且添加logback的配置文件logback.xml。(應(yīng)用中有加載log4j配置文件的需要去掉)
這里是針對(duì)項(xiàng)目中已經(jīng)使用了log4j+slf4j組合的情況。
如果現(xiàn)有項(xiàng)目只是使用了log4j,那么需要通過(guò)slf4j官方提供的工具修改項(xiàng)目源碼(工具就是slf4j下載文件夾下的slf4j-migrator.jar)。
工具使用方法:http://www.slf4j.org/migrator.html。
如果項(xiàng)目使用的是log4j.properties來(lái)配置的,那么可以通過(guò)logback官方的工具轉(zhuǎn)為logback.xml,但如果是log4j.xml,那么還是重新編寫(xiě)logback.xml比較好。
轉(zhuǎn)換工具地址:http://logback.qos.ch/translator/ ,
新項(xiàng)目:
直接添加logback-core.jar、logback-classical.jar和log4j-over-slf4j.jar三個(gè)jar包,編寫(xiě)logback.xml配置文件。
2、 重加載配置文件
配置如下:
<configuration scan="true" scanPeriod="30 seconds" >
...
</configuration>
如果不指定scanPeriod,默認(rèn)情況下是每分鐘重新讀取的配置文件。這里可以通過(guò)scanPeriod屬性配置時(shí)間間隔,單位有:milliseconds, seconds, minutes or hours,如上面的三十秒(數(shù)值跟單位中間空格隔開(kāi))。這里沒(méi)有指定單位的情況下默認(rèn)單位是milliseconds。
PS:
1- 根據(jù)官方文檔,當(dāng)scan設(shè)置為true,會(huì)自動(dòng)添加一個(gè)過(guò)濾器,這個(gè)過(guò)濾器在logger線程中被調(diào)用。也就是說(shuō),當(dāng)調(diào)用logger.debug(),這個(gè)方法執(zhí)行前,會(huì)先調(diào)用過(guò)濾器的方法。假如這時(shí)logger的級(jí)別被設(shè)置成了info,那么logger.debug()任然會(huì)被調(diào)用。
2- 自動(dòng)加載會(huì)影響性能。因此,所以在實(shí)現(xiàn)上,不是每次logger調(diào)用都會(huì)去判斷scanPeriod是否到期,默認(rèn)情況是沒(méi)16次調(diào)用會(huì)去檢查一下scanPeriod是否到期。所以說(shuō)這個(gè)重加載會(huì)有很小的延遲。(開(kāi)發(fā)環(huán)境中可以忽略)
3、 針對(duì)特定用戶(hù)輸入debug級(jí)別的日志。
這里通過(guò)turboFilter來(lái)實(shí)現(xiàn)這個(gè)工具,如:在logback.xml中加入
<turboFilter class="com.ztgame.test.logback.SampleFilter">
<key>id=11,</key>
<OnMatch>ACCEPT</OnMatch>
<OnMismatch>NEUTRAL</OnMismatch>
</turboFilter>
SimpleFilter.java文件:
public class SampleFilter extends TurboFilter {
private String key;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@Override
public FilterReply decide(Marker marker, Logger logger, Level level,
String format, Object[] params, Throwable t) {
if (format != null && format.contains(key)) {
return FilterReply.ACCEPT;
} else {
return FilterReply.DENY;
}
}
}
turboFilter是全局的,當(dāng)logger的事件產(chǎn)生的時(shí)候就去做過(guò)濾。假如設(shè)置了logger的級(jí)別是info,上面的代碼能讓id為11的用戶(hù)信息打印出來(lái)。
注意: 1. 寫(xiě)log的時(shí)候大家最好統(tǒng)一規(guī)范,潛規(guī)則是:
在什么【時(shí)間】,【人物】在【地點(diǎn)】做了【事件】【……】
【時(shí)間】:日志記錄的時(shí)間
【人物】:日志記錄的對(duì)象,如:userId=11
【地點(diǎn)】:輸入日志的方法
【事件】:具體做了什么,如:買(mǎi)了xxx
【……】:其他相關(guān)信息,如:rpc耗時(shí)等等
2. 單個(gè)信息后面加上固定分割符:如userId=11,(逗號(hào))
4、 區(qū)分開(kāi)發(fā)和生產(chǎn)環(huán)境
logback默認(rèn)加載配置文件的優(yōu)先級(jí)是:logback-test.xml > logback.xml。在開(kāi)發(fā)和測(cè)試階段提供logback-test.xml來(lái)達(dá)到區(qū)分生產(chǎn)環(huán)境與開(kāi)發(fā)環(huán)境的目的。
5、 為每個(gè)用戶(hù)生產(chǎn)一個(gè)日志文件
用SiftingAppender來(lái)實(shí)現(xiàn)
logback.xml
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<Key>userid</Key>
<DefaultValue>unknown</DefaultValue>
</discriminator>
<sift>
<appender
name="FILE-${userid}" class="ch.qos.logback.core.FileAppender">
<File>log/${userid}.log</File>
<Append>false</Append>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</Pattern>
</layout>
</appender>
</sift>
</appender>
Java文件:
logger.debug("Application started");
MDC.put("userid", "Alice");
logger.debug("Alice says hello");
MDC.put("userid", null);
logger.debug("Alice says hello2");
這里需要在每次記錄log之前設(shè)置用戶(hù)信息。(有點(diǎn)麻煩,可以簡(jiǎn)單封裝一下,適合新項(xiàng)目)
6、log文件的壓縮和自動(dòng)刪除
logback提供一套自動(dòng)壓縮和刪除的機(jī)制,具體配置查看logback_demos中的示例。
建議是這樣一種日志布局:
|---------log根目錄
|-----------------動(dòng)態(tài)log文件(當(dāng)前被使用)
|-----------------backup目錄(用于存放日志備份)
….
|------------------------日期目錄(存放壓縮好的備份日志,,過(guò)期的會(huì)被自動(dòng)刪除)
附件:
1. 附帶一些demos(eclipse項(xiàng)目) ,下載地址:logback_demos.zip
2. Logback官方中文手冊(cè),下載地址:Logback手冊(cè).pdf
posted on 2012-06-05 13:56
沖杯茶喝 閱讀(9232)
評(píng)論(0) 編輯 收藏