首頁  >  文章  >  Java  >  利用Log4j將不同Package的日誌輸出到不同檔案的方法

利用Log4j將不同Package的日誌輸出到不同檔案的方法

高洛峰
高洛峰原創
2017-01-18 12:42:241251瀏覽

前言

隨著專案規模的越來越大,會不斷的引入新的模組,不同的模組都會列印自己的日誌,最後就造成日誌根本沒法查看,例如我自己的專案中,就存在以下這些日誌:

接收外界訊息的日誌、對外傳送訊息的日誌;

後台常駐執行緒的處理日誌;

外部介面存取的參數、傳回結果等介面日誌;

Service存取資料庫產生的SQL日誌存取資料庫產生的SQL ;

這其中,訊息日誌和後台執行緒的日誌資料量非常龐大,如果所有日誌都印在一個檔案中,使用tail -f log.log文件,會發現日誌在快速的捲動,根本無法查看甚至定位某一個具體的SQL或者Service訪問日誌。

解決方法就是可以將不同的日誌加以分類輸出,這樣相互的日誌不影響,尤其重要的介面存取日誌,能夠很方便的定位和排查問題。

步驟1:在log4j.properties中配置

先貼一下我自己所有的log4j.properties配置:

log4j.rootLogger=INFO, console, file
  
log4j.appender.console=net.czt.log.AsyncConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p crazyant-web %-17c{2} (%13F:%L) %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} - %m%n
log4j.appender.console.bufferSize=10000
log4j.appender.console.encoding=UTF-8
  
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.file=/home/work/apache-tomcat-6.0.39/logs/crazyant.log
log4j.appender.file.MaxBackupIndex=5
log4j.appender.file.MaxFileSize=1GB
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-5p] crazyant-web %d{yyyy-MM-dd HH:mm:ss,SSS} %X{USER_ID}|%X{USER_IP}|%X{SERVER_ADDRESS}|%X{SERVER_NAME}|%X{REQUEST_URI}|%X{SESSION_ID} method:%l%n%m%n
log4j.appender.file.bufferSize=10000
log4j.appender.file.encoding=UTF-8
  
log4j.logger.net.czt.crazyant.msg=DEBUG, message
log4j.additivity.net.czt.crazyant.msg=false
log4j.appender.message=org.apache.log4j.RollingFileAppender
log4j.appender.message.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_message.log
log4j.appender.message.Append=true
log4j.appender.message.MaxFileSize=1GB
log4j.appender.message.MaxBackupIndex=5
log4j.appender.message.layout=org.apache.log4j.PatternLayout
log4j.appender.message.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.message.encoding=UTF-8
  
log4j.logger.net.czt.crazyant.async.service=DEBUG, async
log4j.additivity.net.czt.crazyant.async.service=false
log4j.appender.async=org.apache.log4j.RollingFileAppender
log4j.appender.async.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_async.log
log4j.appender.async.Append=true
log4j.appender.async.MaxFileSize=1GB
log4j.appender.async.MaxBackupIndex=5
log4j.appender.async.layout=org.apache.log4j.PatternLayout
log4j.appender.async.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.async.encoding=UTF-8
  
log4j.logger.net.czt.orm.mybatis.SqlMonitorManager=DEBUG, showsql
log4j.additivity.net.czt.orm.mybatis.SqlMonitorManager=false
log4j.logger.net.czt.transaction.interceptor.SmartTransactionInterceptor=DEBUG, showsql
log4j.additivity.net.czt.transaction.interceptor.SmartTransactionInterceptor=false
log4j.appender.showsql=org.apache.log4j.RollingFileAppender
log4j.appender.showsql.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_sql.log
log4j.appender.showsql.Append=true
log4j.appender.showsql.MaxFileSize=1GB
log4j.appender.showsql.MaxBackupIndex=5
log4j.appender.showsql.layout=org.apache.log4j.PatternLayout
log4j.appender.showsql.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.showsql.encoding=UTF-8
  
log4j.logger.net.czt.crazyant.service=DEBUG, service
log4j.additivity.net.czt.crazyant.service=false
log4j.appender.service=org.apache.log4j.RollingFileAppender
log4j.appender.service.File=/home/work/apache-tomcat-6.0.39/logs/crazyant_service.log
log4j.appender.service.Append=true
log4j.appender.service.MaxFileSize=1GB
log4j.appender.service.MaxBackupIndex=5
log4j.appender.service.layout=org.apache.log4j.PatternLayout
log4j.appender.service.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p][%c{1}] [%t] - %m%n
log4j.appender.service.encoding=UTF-8

在設定檔的下方,可以方便的看到,我將message(訊息)、async(後端線程)、showsql(資料庫日誌)、service(介面呼叫)分別輸出到了不同的日誌檔案。

其中的一些解釋:

log4j.rootLogger=INFO, console, file

log4j有一個rootLogger和普通Logger的概念,默認情況下我們只需要一個rootLogger,就是所有的日誌只會輸出到這一個日誌文件中。

看一下普通Logger的設定(以介面日誌service為例):

1、log4j.logger.net.czt.crazyant.service=DEBUG, service

   service”,表示該普通logger日誌配置生效的package的完全路徑

      其中色service,表示該普通logger的名字

2、log4j.additivity.net.czt..Lan

2、log4j.additivity.net.czt..Lan


2、log4j.additivity.net.czt..的”net.czt.crazyant.service”,和上面的相同,表示該配置項針對的package


      該句配置的意思,是不要將該package的日誌輸出到rootLogger日誌中,只輸出到自己配置的日誌就行了;


3、log4j.appender.service=org.apache.log4j.RollingFileAppender,以及該組態段下面的設定項


       這裡的」service”設定,和上面的第一個配置項目的」service」相同,表示對該普通Logger的設定;


       下方的設定項和rootLogger相同,表示每天輸出檔案、編碼UTF8、分片規則、每行的輸出模式等等

我自己遇到的問題,是上面的log4j.properties配置好以後,發現各個日誌檔創建了,但是裡面都沒有內容,這是為啥呢?來看下面第二個注意的地方;

步驟2、輸出日誌時需要設定日誌物件對應的具體Class

什麼意思呢?上面的設定項中,有一個」net.czt.crazyant.service」的package字串,那麼我們自己想一下,log4j是怎樣將不同package中的logger日誌輸出到不同檔案呢,想一下會有兩種方法:


1、採用intercepter或aop的方式,log4j自己偵測日誌輸出,偵測到日誌產生於哪個package,就將其輸出到對應檔案中;


2、由使用者傳一個Class參數,log4j取得該Class對應的Package,以此為準,來定位不同的日誌檔;

看一下程式碼,顯然log4j用的是後一種簡單直接的方式:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
  
public class MyClassImpl implements MyClass {
 /**
  * loger
  */
 private static final Log logger = LogFactory.getLog(MyClassImpl.class);
  
 /**
  * my func
  */
 public void myfunc() {
  logger.info("call method myfunc.");
 }
}

在logger = LogFactory.getLog(MyClassImpl. class)中,傳入了使用該logger的Class參數,而該Class被反射取到的package位址,就是log4j用來輸出日誌的package位址。

這種做法也有強大的地方,方便邏輯上的日誌歸類,例如很多程式碼不屬於一個package,但是它們邏輯上屬於一起的,舉個例子,訊息的處理不只是介面呼叫Service這個package,可能也會呼叫發送msg的操作,如果想把msg的package中一些日誌也輸出到Service,那麼在這個msg的logger初始化的時候,傳入一個Serivice的Class就行了。

或對於某一類的所有日誌來說,它們所有的logger對象,都來自封裝好的單一對象實例即可,而這個單一對象實例傳入的參數只有一個,用於標識這個邏輯歸類即可。

總結

在Log4j.properties中,支援package或具體class的日誌單獨輸出,但是也需要程式碼中logger初始化的時候,能和日誌配置中的package對應上。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。

更多利用Log4j將不同Package的日誌輸出到不同檔案的方法相關文章請關注PHP中文網! 🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn