先說兩句體會:
俗話說:知己知彼,百戰不殆. 感覺飄遠了..
道理卻真是這麼個理兒~
知己:
osgi要集成log4j,首先就要搞清楚osgi環境的狀況,每個bundle是由不同的類加載器加載的,不同bundle之間如何共享log4j這個bundle的功能,如果用fragment 的方式將分裝好的log4j fragment bundle 附加在需要使用它的bundle上,這種方式,如果要修改日誌級別怎麼辦?
應該是log4j的日誌文件,放置在bundle ja包的外面會比較好~
怎麼做呢?
知彼:
log4j是怎麼工作的?它的工作原理是怎麼樣的?怎麼才能把日誌放在bundle外面,但是bundle內部的log4j功能又能正常使用?
答案是去了解log4j的工作原理。不用把源碼翻一遍,估計也沒那個時間,也沒有必要,百度一下,文章很多,下面轉載一篇,如下:
轉載部分分割線,轉載自:http://blog.csdn.net/forwayfarer/article/details/2882929
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
把log4j.properties或是log4j.xml放在src根下(ClassPath路徑中),這個文件在第一次調用log4j時會在類路徑下找到該文件並加載.
1. log4j的意義
在應用程序中添加日誌記錄總的來說基於三個目的:(1)監視代碼中變量的變化情況,週期性的記錄到文件中供其他應用進行統計分析工作;(2)跟蹤代碼運行時軌跡,作爲日後審計的依據;(3)擔當集成開發環境中的調試器的作用,向文件或控制檯打印代碼的調試信息。
最普通的做法就是在代碼中嵌入許多的打印語句,這些打印語句可以輸出到控制檯或文件中,比較好的做法就是構造一個日誌操作類來封裝此類操作,而不是讓一系列的打印語句充斥了代碼的主體。
2. log4j的作用
我們可以控制日誌信息輸送的目的地是控制檯、文件等;
我們也可以控制每一條日誌的輸出格式;
通過定義每一條日誌信息的級別,我們能夠更加細緻地控制日誌的生成過程。
3. log4j的構成
log4j包含三個組件,分別是 Loggers(記錄器)、Appenders(輸出源)、Layouts(日誌佈局)。可分別簡單理解爲"日誌類別"、"日誌要輸出的地方"和"日誌以何種形式輸出"。
Loggers: Logger組件負責產生日誌,能夠對日誌進行篩選,控制什麼樣的日誌可以被輸出,什麼樣的日誌應該被忽略。Loggers組件在此係統中被分爲五個級別:DEBUG、INFO、WARN、ERROR和FATAL(都在org.apache.log4j.Level類中定義)。這五個級別是有順序的,DEBUG < INFO < WARN < ERROR < FATAL,分別用來指定這條日誌信息的重要程度,明白這一點很重要,這裏Log4j有一個規則:假設Loggers級別爲P,如果在Loggers中發生了一個級別Q比P高,則可以啓動,否則屏蔽掉。假設你定義的級別是info,那麼error和warn的日誌可以顯示而比他低的debug信息就不顯示了。日誌級別的作用:當程序編寫完成以後當不再需要調式信息時,將日誌級別調到最高即可。程序員可以定義多個Logger組件,每個Logger組件都有唯一的名字,logger組件之間通過名字來表明Logger組件之間的隸屬關係。最高層次的Logger組件是:org.apache.log4j.Logger類中。使用此類中的靜態方法:getRootLogger()來得到它。例子
- private Logger logger = null;
- public UserDAOImpl() {
- logger = Logger.getLogger(this.getClass().getName());//建立Logger的一個實例
- logger.setLevel(Level.INFO);//設置logger的級別。通常不在程序中設置logger的級別。一般在配置文件中設置。
- logger.warn("warnTest");//這個請求可輸出Logger信息,因爲WARN >= INFO
- logger.info("infoTest");//這個請求可輸出Logger信息,因爲INFO >= INFO
- logger.debug("debugTest");//這個請求不可輸出Logger信息,因爲DEBUG < INFO
- }
在對Logger實例進行命名時,沒有限制,可以取任意自己感興趣的名字。一般情況下建議以類的所在位置來命名Logger實例,這是目前來講比較有效的Logger命名方式(edu.hust.dao.impl.UserDAOImpl.java, 即this.getClass().getName()。這樣可以使得每個類建立自己的日誌信息,便於管理。
Appenders: 禁用與使用日誌請求只是Log4j其中的一個小小的地方,Log4j日誌系統允許把日誌輸出到不同的地方,如控制檯(Console)、文件(Files)、根據天數或者文件大小產生新的文件、以流的形式發送到其它地方等等。在Log4j中,日誌信息通過Appender組件輸出到目的地,一個Appender實例就代表了一個目的地。一個記錄器(Logger)可以擁有多個Appender。
其語法表示爲:
org.apache.log4j.ConsoleAppender --> 控制檯org.apache.log4j.FileAppender --> 文件
org.apache.log4j.DailyRollingFileAppender --> 按照指定的日期或時間頻率滾動產生日誌文件
org.apache.log4j.RollingFileAppender --> 當文件到達一定長度時,備份文件即產生一個新的文件
org.apache.log4j.WriterAppender --> 將日誌信息以流格式發送到任意指定的地方
配置時使用方式爲:
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
......
log4j.appender.appenderName.optionN = valueN
Layouts: 有時用戶希望根據自己的喜好格式化自己的日誌輸出。Log4j可以在Appenders的後面附加Layouts來完成這個功能。Layouts提供了四種日誌輸出樣式,如根據HTML樣式、自由指定樣式、包含日誌級別與信息的樣式和包含日誌時間、線程、類別等信息的樣式等等。Layout組件負責格式化輸出日誌信息,一個Appender只能有一個Layout組件。
其語法表示爲:
org.apache.log4j.HTMLLayout --> 以HTML網頁表格的形式輸出日誌信息(.html)
org.apache.log4j.PatternLayout --> 程序員根據一系列的格式化標籤,類似C中的printf()函數的輸出
org.apache.log4j.SimpleLayout --> 由日誌級別 + “-” + 消息 組成 例如:DEBUG–錯誤
org.apache.log4j.TTCCLayout --> 由時間(time),線程(thread),類別(category),和嵌套的上下文(context)信息組成。(TTCC有上述四個英文單詞組成)(.log)
配置時使用方式爲:
log4j.appender.appenderName.layout =fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
......
log4j.appender.appenderName.layout.optionN = valueN
4. log4j的配置
(1)建立Logger實例
語法表示:public static Logger getLogger( String name)
實際使用:static Logger logger = Logger.getLogger(ServerWithLog4j.class.getName ()) ;
(2)讀取配置文件
獲得了Logger的實例之後,接下來將配置Log4j使用環境:
語法表示:
BasicConfigurator.configure():自動快速地使用缺省Log4j環境。
PropertyConfigurator.configure(String configFilename):讀取使用Java的特性文件編寫的配置文件。
DOMConfigurator.configure(String filename):讀取XML形式的配置文件。
實際使用:
PropertyConfigurator.configure("log4j.properties");
(3)插入日誌信息
完成了以上連個步驟以後,下面就可以按日誌的不同級別插入到你要記錄日誌的任何地方了。
語法表示:
Logger.debug(Object message);//調試信息
Logger.info(Object message);//一般信息
Logger.warn(Object message);//警告信息
Logger.error(Object message);//錯誤信息
Logger.fatal(Object message);//致命錯誤信息
實際使用:log.debug("delete successful"); log.error("delete failed", e);
5. log4j的配置過程
在實際編程時,要使Log4j真正在系統中運行事先還要對配置文件進行定義。定義步驟就是對Logger、Appender及Layout的分別使用。Log4j支持兩種配置文件格式,一種是XML格式的文件,一種是java properties(key=value)【Java特性文件(鍵=值)】
下面我們介紹使用Java特性文件做爲配置文件的方法
(1)配置根Logger,其語法爲:
log4j.rootLogger = [level], appenderName1, appenderName2, …
level: 是日誌記錄的優先級,分爲OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定義的級別。Log4j建議只使用四個級別,優先級從高到低分別是ERROR、WARN、INFO、DEBUG。通過在這裏定義的級別,您可以控制到應用程序中相應級別的日誌信息的開關。比如在這裏定 義了INFO級別,則應用程序中所有DEBUG級別的日誌信息將不被打印出來。
appenderName: 就是指定日誌信息輸出到哪個地方。您可以同時指定多個輸出目的地。
例如:log4j.rootLogger=info,A1,B2,C3
(2)配置日誌信息輸出目的地,其語法爲:
log4j.appender.appenderName = fully.qualified.name.of.appender.class //"fully.qualified.name.of.appender.class" 可以指定下面五個目的地中的一個:
org.apache.log4j.ConsoleAppender(控制檯)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天產生一個日誌文件)
org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件)
org.apache.log4j.WriterAppender(將日誌信息以流格式發送到任意指定的地方)
ConsoleAppender選項
Threshold=WARN: 指定日誌消息的輸出最低層次。
ImmediateFlush=true: 默認值是true,意謂着所有的消息都會被立即輸出。
Target=System.err:默認情況下是:System.out,指定輸出控制檯
FileAppender選項
Threshold=WARN: 指定日誌消息的輸出最低層次。
ImmediateFlush=true: 默認值是true,意謂着所有的消息都會被立即輸出。
File=mylog.txt: 指定消息輸出到mylog.txt文件。
Append=false: 默認值是true,即將消息增加到指定文件中,false指將消息覆蓋指定的文件內容。
DailyRollingFileAppender選項
Threshold=WARN: 指定日誌消息的輸出最低層次。
ImmediateFlush=true: 默認值是true,意謂着所有的消息都會被立即輸出。
File=mylog.txt: 指定消息輸出到mylog.txt文件。
Append=false: 默認值是true,即將消息增加到指定文件中,false指將消息覆蓋指定的文件內容。
DatePattern='.'yyyy-ww: 每週滾動一次文件,即每週產生一個新的文件。當然也可以指定按月、周、天、時和分。即對應的格式如下:
1)'.'yyyy-MM: 每月
2)'.'yyyy-ww: 每週
3)'.'yyyy-MM-dd: 每天
4)'.'yyyy-MM-dd-a: 每天兩次
5)'.'yyyy-MM-dd-HH: 每小時
6)'.'yyyy-MM-dd-HH-mm: 每分鐘
RollingFileAppender 選項
Threshold=WARN: 指定日誌消息的輸出最低層次。
ImmediateFlush=true: 默認值是true,意謂着所有的消息都會被立即輸出。
File=mylog.txt: 指定消息輸出到mylog.txt文件。
Append=false: 默認值是true,即將消息增加到指定文件中,false指將消息覆蓋指定的文件內容。
MaxFileSize=100KB: 後綴可以是KB, MB 或者是 GB. 在日誌文件到達該大小時,將會自動滾動,即將原來的內容移到mylog.log.1文件。
MaxBackupIndex=2: 指定可以產生的滾動文件的最大數。
實際應用: log4j.appender.A1=org.apache.log4j.ConsoleAppender //這裏指定了日誌輸出的第一個位置A1是控制檯ConsoleAppender
(3)配置日誌信息的格式,其語法爲:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class //"fully.qualified.name.of.layout.class" 可以指定下面4個格式中的一個:
org.apache.log4j.HTMLLayout(以HTML表格形式佈局),
org.apache.log4j.PatternLayout(可以靈活地指定佈局模式),
org.apache.log4j.SimpleLayout(包含日誌信息的級別和信息字符串),
org.apache.log4j.TTCCLayout(包含日誌產生的時間、線程、類別等等信息)
HTMLLayout選項
LocationInfo=true: 默認值是false,輸出java文件名稱和行號
Title=my app file: 默認值是 Log4J Log Messages.
PatternLayout選項
ConversionPattern=%m%n: 指定怎樣格式化指定的消息。
實際應用: log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n
這裏需要說明的就是日誌信息格式中幾個符號所代表的含義:
-X號: X信息輸出時左對齊;
%p: 輸出日誌信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也可以在其後指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS}輸出類似:2002年10月18日 22:10:28,921
%r: 輸出自應用啓動到輸出該log信息耗費的毫秒數
%c: 輸出日誌信息所屬的類目,通常就是所在類的全名
%t: 輸出產生該日誌事件的線程名
%l: 輸出日誌事件的發生位置,相當於%C.%M(%F:%L)的組合,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10)
%x: 輸出和當前線程相關聯的NDC(嵌套診斷環境),尤其用到像java servlets這樣的多客戶多線程的應用中。
%%: 輸出一個"%"字符
%F: 輸出日誌消息產生時所在的文件名稱
%L: 輸出代碼中的行號
%m: 輸出代碼中指定的消息,產生的日誌具體信息
%n: 輸出一個回車換行符,Windows平臺爲"/r/n",Unix平臺爲"/n"輸出日誌信息換行
可以在%與模式字符之間加上修飾符來控制其最小寬度、最大寬度、和文本的對齊方式。如:
1)%20c:指定輸出category的名稱,最小的寬度是20,如果category的名稱小於20的話,默認的情況下右對齊。
2)%-20c:指定輸出category的名稱,最小的寬度是20,如果category的名稱小於20的話,"-"號指定左對齊。
3)%.30c:指定輸出category的名稱,最大的寬度是30,如果category的名稱大於30的話,就會將左邊多出的字符截掉,但小於30的話也不會有空格。
4)%20.30c:如果category的名稱小於20就補空格,並且右對齊,如果其名稱長於30字符,就從左邊交遠銷出的字符截掉。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
接下來,結合項目的情況集成吧,容易多了吧~