1. 程式人生 > >基於log4j實現統一日誌管理

基於log4j實現統一日誌管理

背景:
       一般作業系統級的告警有相關的軟體,但我們應用級日誌往往無法統一監控、分析。因為最近的專案是比較大的一個平臺,有七、八個子系統,weblogic域也有三、四個。如果使用者自身能夠實時監控到應用級致命異常日誌 如OutOfMemory,執行緒掛死、應用介面無法連結等等。那麼我們監控維護人員工作就大大簡化,不然要檢視所有域的日誌資訊,只需集中看一處,系統故障也能夠更快的解決,恢復正常。
       使用者的需求是要求我們將日誌輸出到一個第三方廠家的日誌Server。

設想:
        weblogic platform域的日誌輸出是可配置的,在$bea/weblogic/common/lib/workshopLogCfg.xml, 原先的一個專案所有的日誌輸出均在此檔案中配置。其他中介軟體本人很少使用,相信也有類似的功能,log4j日誌框架支援統一日誌管理功能,簡單實現原理(啟動一個SocketServer,處理各個客戶端機器連線的Socket輸入,
而每個應用列印日誌使用Socket方式將日誌內容輸出到SocketServer端)。如果能將重要的的中介軟體異常日誌以及應用異常日誌到統一日誌伺服器,實時分析,這樣就方便日常監控,有點類似於裝置告警的功能,如果再開發出相關日誌分析軟體,個人覺得會是平臺級產品的一個亮點,正如《少林足球》說的有點搞頭。

實踐:
    實踐證明現實和理想總歸有一定的差距,呵呵。下面描述驗證、學習心得:
    首先描述log4j是如何實現統一日誌管理該功能的。
    核心類:
    一、org.apache.log4j.net.SocketServer 
    主要功能:
                      1、啟動SocketServer
                      2、接受Socket請求
                      3、初始化對應Socket的日誌輸出配置,如沒有,就採用通用配置
                      4、另啟執行緒處理客戶端Socket和服務端互動
    一個比較標準的多執行緒處理實現。
     啟動Server需要有三個執行引數:埠號、log4j配置檔案、客戶端日誌在Server端輸出配置檔案目錄
     執行命令如下:
                     java -classpath ../lib/log4j-1.2.8.jar;.; test.logserver.FixSocketServer   8088   server.properties  d:/temp
     說明:
              a、客戶端日誌在Server端輸出配置檔案命名規則 $ip.lcf ,    如 10.21.11.10.lcf  
                        該類在解析該配置檔案的程式碼中 應該存在個bug(版本1.2.9)
                                           程式碼176 行   String key = s.substring(0,i);改為:   String key = s.substring(i+1);
              b、配置檔案內容和一般log4j配置內容雷同,categories、appenders、layouts 
     二、org.apache.log4j.net.SocketAppender
             該類繼承於AppenderSkeleton,如果我們需要自定義Appender,可以繼承AppenderSkeleton類,實現方法:

protectedvoid append(LoggingEvent event);

    主要功能: 
                     1、連線到SocketServer,並建立一個到SocketServer的物件輸出例項
                     2、如果連線失敗,會啟動一個守護執行緒,每隔三十秒鐘重新連線
                     3、日誌輸出時,將日誌事件物件輸出到SocketServer
     相對應的日誌配置:
        

log4j.appender.mysocket=test.logserver.SocketAppender 
log4j.appender.mysocket.RemoteHost
=10.243.17.85 
log4j.appender.mysocket.Port
=8088 
log4j.appender.mysocket.LocationInfo
=true 
log4j.appender.mysocket.layout
=org.apache.log4j.PatternLayout 
log4j.appender.myConsole.layout.ConversionPattern
=%5p [%t] (%F:%L) -%m%n


      三、org.apache.log4j.net.SocketNode
              該類相對簡單,一個執行緒類
     主要功能:
                     負責接收客戶端對應輸出物件,根據對應的配置,輸出相關日誌。

      可以看出是通過物件進行傳輸的,如果第三方不是採用java語言的,實際解決時只需改寫SocketAppender的append方法,輸出日誌內容就可。對方實現SocketServer功能就可(程式語言基本都支援該功能)。

       遺憾的是在weblogic 一般server域中我沒有找到可以改變日誌輸出的地方(上次看到weblogic9.0中有日誌服務,不知道能不能改變),所以實際差距還是比較大的,關於效能問題,因為是重要的日誌(warning、error、fetal)才輸出,採用socket方式問題應該不大。

篇外話:               
           檢視程式碼中無意中發現log4j框架一部分原始碼都是一些人捐獻的。雖然程式碼不復雜,但感覺為自己喜歡的框架很熱心,希望它變的越來越好,真的希望我們國內也能有一些優秀的開源專案,並且大家都去支援它,發展它。
           實際我在專案中使用log4j使用的都是一些基本功能,對它的設計、結構不是很清楚,誰有相關學習文件,請給我一份,不甚感激(使用手冊已有)。