1、Apache通用日志接口(commons-logging.jar)介紹
Apache Commons包中的一個,包含了日志功能,必須使用的jar包。這個包本身包含了一個Simple Logger,但是功能很弱。在運行的時候它會先在CLASSPATH找log4j,如果有,就使用log4j,如果沒有,就找JDK1.4帶的java.util.logging,如果也找不到就用Simple Logger。commons-logging.jar的出現是一個歷史的的遺留的遺憾,當初Apache極力游說Sun把log4j加入JDK1.4,然而JDK1.4項目小組已經接近發布JDK1.4產品的時間了,因此拒絕了Apache的要求,使用自己的java.util.logging,這個包的功能比log4j差的很遠,性能也一般。后來Apache就開發出來了commons-logging.jar用來兼容兩個logger。因此用 commons-logging.jar寫的log程序,底層的Logger是可以切換的,你可以選擇log4j,java.util.logging或者它自帶的Simple Logger。不過我仍然強烈建議使用log4j,因為log4j性能很高,log輸出信息時間幾乎等于System.out,而處理一條log平均只需要5us。
Apache通用日志包提供一組通用的日志接口,用戶可以自由選擇實現日志接口的第三方軟件通用日志目前支持以下日志實現Log4j日志器JDK1.4LoggingSimpleLog日志器NoOpLog日志器
1.1、Log 接口Common-logging的應用程序編程接口主要在org.apache.commons.logging.log接口中定義,這個接口主要定義了兩類操作: 一類是級別判斷,用于減少不必要的日志操作的參數計算從而提高性能。另一類是日志登記,按照級別登記日志信息。通用日志包把日志消息分為6種級別Fatal,Error,Warn,Info,Debug和Trace
org.apache.commons.logging.Log接口代表日志器,它提供了一組輸出日志的方法,日志登記操作分又為兩小類:一個參數的日志信息登記操作和兩個參數的日志信息登記操作。前者對三類用戶都適用,后者用于打印日志登記處的出錯堆棧信息,所以更適用于開發人員調式與維護使用 fatal(Object message); error(Object message); warn (Object message); info (Object message); debug(Object message); trace(Object message);
debug(Object message, Throwable t); trace(Object message, Throwable t); ...... 這里需要注意的是,只有當輸出日志的級別大于等于日志器配置的日志級別時,這個方法才會真正被執行.例如日志器設置日志級別為Warn,那么程序中,它的 fatal(),error(),warn()方法會被執行,而info(),debug(),trace() 不會被執行. Log接口還提供了一組判斷是否允許輸出特定級別日志消息的方法
isFatalEnable(); isErrorEnable(); isWarnEnable(); isInfoEnable(); isDebugEnable(); isTraceEnable();1.2、LogFactory接口 org.apache.commons.logging.LogFactory接口提供了獲得日志器實例的兩個靜態方法 public static Log getLog(String name)throws LogConfigurationException public static Log getLog(Class class)throws LogConfigurationException public static Log getLog(Class class) { getLog(class.getName()); }
2、Log4J介紹
Log4j是Apache的一個開放源代碼項目,通過使用Log4j,我們可以控制日志信息輸送的目的地是控制臺、文件、GUI組件、甚至是套接口服務器、NT的事件記錄器、UNIX Syslog守護進程等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志信息的級別,我們能夠更加細致地控制日志的生成過程。這些可以通過一個配置文件來靈活地進行配置,而不需要修改應用的代碼。
2.1、Log4J配置說明:
log4j配置文件有三個主要的組件:Logger,Appender和Layout,分別為日志類型,日志輸出目的地,日志輸出格式. 跟PRoxool類似,log4j支持兩種類型的配置文件,xml和properties 。log4j.properties配置文件如下:(需要把log4j的配置文件放在classpath下)
2.1.1 log4j.rootLogger =INFO, stdout , R
此句為將等級為INFO的日志信息輸出到stdout和R這兩個目的地,其語法為:
log4j.rootLogger = [ level ] , appenderName, appenderName, …
其中,level 是日志記錄的優先級,分為OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定義的級別。Log4j建議只使用四個級別,優先級從高到低分別是ERROR、WARN、INFO、DEBUG。通過在這里定義的級別,您可以控制到應用程序中相應級別的日志信息的開關。比如在這里定義了INFO級別,只有等于及高于這個級別的才進行處理,則應用程序中所有DEBUG級別的日志信息將不被打印出來。ALL:打印所有的日志,OFF:關閉所有的日志輸出。 appenderName就是指定日志信息輸出到哪個地方。可同時指定多個輸出目的地。
2.1.2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
此句為定義名為stdout的輸出端是哪種類型
Appender 負責控制日志記錄操作的輸出。
其語法為:
log4j.appender.appenderName = fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.optionN = valueN
這里的appenderName為在①里定義的,可任意起名。
其中,Log4j提供的appender有以下幾種:
org.apache.log4j.ConsoleAppender(控制臺),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件),
org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件),可通過log4j.appender.R.MaxFileSize=100KB設置文件大小,還可通過 log4j.appender.R.MaxBackupIndex=1設置為保存一個備份文件。
org.apache.log4j.WriterAppender(將日志信息以流格式發送到任意指定的地方)
例如:log4j.appender.stdout=org.apache.log4j.ConsoleAppender
定義一個名為stdout的輸出目的地,ConsoleAppender為控制臺。
2.1.3配置日志信息的格式(布局)Layout
Layout 負責格式化Appender的輸出。
其語法為:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1 = value1
…
log4j.appender.appenderName.layout.optionN = valueN
其中,Log4j提供的layout有以下幾種:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
org.apache.log4j.TTCCLayout(包含日志產生的時間、線程、類別等等信息)
2.1.4格式化日志信息
Log4J采用類似C語言中的printf函數的打印格式格式化日志信息,打印參數如下:%m 輸出代碼中指定的消息
%p 輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL
%r 輸出自應用啟動到輸出該log信息耗費的毫秒數
%c 輸出所屬的類目,通常就是所在類的全名
%t 輸出產生該日志事件的線程名
%n 輸出一個回車換行符,Windows平臺為“rn”,Unix平臺為“n”
%d 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,比如:%d{yyyy MMM dd HH:mm:ss,SSS},輸出類似:2002年10月18日 22:10:28,921
%l 輸出日志事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數
2.2、關于Log4j比較全面的配置
2.2.1 應用于控制臺
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.Threshold=DEBUG log4j.appender.CONSOLE.Target=System.out log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n #log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n2.2.2應用于文件
log4j.appender.FILE=org.apache.log4j.FileAppender log4j.appender.FILE.File=file.log log4j.appender.FILE.Append=falselog4j.appender.FILE.layout=org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n # Use this layout for LogFactor 5 analysis2.2.3 應用于回滾文件
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
2.2.4應用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender log4j.appender.SOCKET.RemoteHost=localhost log4j.appender.SOCKET.Port=5001log4j.appender.SOCKET.LocationInfo=true# Set up for Log Facter 5log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n # Log Factor 5 Appender log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender log4j.appender.LF5_APPENDER.MaxNumberOfRecords=20002.2.5應用于郵件
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender log4j.appender.MAIL.Threshold=FATAL log4j.appender.MAIL.BufferSize=10log4j.appender.MAIL.From=web@www.wuset.com log4j.appender.MAIL.SMTPHost=www.wusetu.com log4j.appender.MAIL.Subject=Log4J Message log4j.appender.MAIL.To=web@www.wusetu.com log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n2.2.6應用于數據庫
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender log4j.appender.DATABASE.URL=jdbc:MySQL://localhost:3306/test log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver log4j.appender.DATABASE.user=root log4j.appender.DATABASE.passWord= log4j.appender.db.sql=INSERT INTO SS_LOG4J_LOG (PRIORITY,LOGDATE,CLASS,METHOD,MSG) VALUES('%p','%d{yyyy-MM-dd HH:mm:ss}','%C','%M','%m') log4j.appender.db.layout=org.apache.log4j.PatternLayout log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <pre name="code" class="java">3、Log4J的使用
3.1、在application中的使用:
將log4j.jar和common-logging.jar加入到build path中即可。
3.2 在web應用中使用log4j
3.2.1 創建一個集成httpservlet的servlet文件,在init中對log4j進行初始化
public class log4jInit extends HttpServlet {
@Override public void init() throws ServletException { Log log = LogFactory.getLog(this.getClass().getName()); //Logger logger = Logger.getLogger(this.getClass()); String prefix = this.getServletContext().getRealPath("/"); System.out.println(prefix); String file = this.getServletConfig().getInitParameter("log4j-init-file"); if(file!=null) PropertyConfigurator.configure(prefix+file); }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }
}
3.2.2 在web.xml中定義這個servlet,并在應用啟動時啟動
<servlet> <servlet-name>log4jInit</servlet-name> <servlet-class>com.highsoft.log4j.log4jInit</servlet-class> <init-param> <param-name>log4j-init-file</param-name> <param-value>/WEB-INF/classes/log4j1.properties</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet>
3.3 在spring中集成log4j
3.3.1 在web.xml中集成
<!--如果不設,默認為web.root,但最好設置,以免項目間沖突—>
<!--如果應用服務器下有不止一個的應用在使用spring的Log4jConfigListener,需要修改web環境中webAppRootKey值(這樣log4j的配置文件里就可以用${myAppfuse.root}來表示剛剛設進去的系統變量,例如:log4j.appender.logfile.File=${myAppfuse.root}/logs/mylog.log)。否則兩個默認值web.root在環境變量中就會有沖突導致第二個應用啟動失敗。—>
<context-param> <param-name>webAppRootKey</param-name> <param-value>myappfuse.root</param-value> </context-param>
<!--在這里定位配置文件,需要的是從root開始的絕對路徑—><context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/log4j.properties</param-value></context-param>
<!--Spring默認刷新Log4j配置文件的間隔,單位為millisecond--><context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60000</param-value></context-param>
<listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class></listener>
<!--這里用listener,也可以用下面的servlet—>
<servlet> <servlet-name>log4j</servlet-name> <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class> <load-on-startup>1</load-on-startup></servlet>
3.3.2 在代碼中使用Log4j
我們在需要輸出日志信息的類中做如下的三個工作:1、導入所有需的commongs-logging類:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
2、在自己的類中定義一個org.apache.commons.logging.Log類的私有靜態類成員:
private final Log log = LogFactory.getLog(getClass());
LogFactory.getLog()方法的參數使用的是當前類的class。
3、使用org.apache.commons.logging.Log類的成員方法輸出日志信息:
if (log.isDebugEnabled()){
log.debug("111");
}
if (log.isInfoEnabled()){
log.info("222");
}
if (log.isWarnEnabled()){
log.warn("333");
}
if (log.isErrorEnabled()){
log.error("444");
}
if (log.isFatalEnabled()){
log.fatal("555")
}
4、SLF4j介紹
準確的說,slf4j并不是一種具體的日志系統,而是一個用戶日志系統的facade,允許用戶在部署最終應用時方便的變更其日志系統。
4.1、使用方式: 在系統開發中,統一按照slf4j的API進行開發,在部署時,選擇不同的日志系統包,即可自動轉換到不同的日志系統上。比如:選擇JDK自帶的日志系統,則只需要將slf4j-api-1.5.10.jar和slf4j-jdk14-1.5.10.jar放置到classpath中即可,如果中途無法忍受JDK自帶的日志系統了,想換成log4j的日志系統,僅需要用slf4j-log4j12-1.5.10.jar替換slf4j- jdk14-1.5.10.jar即可(當然也需要log4j的jar及配置文件)4.2、使用場景: 我們開發的是類庫或者嵌入式組件,可以考慮使用slf4j,因為我們并不能決定用戶選擇哪種日志系統(不同軟件開發公司會鐘情于不同的日志系統);但是如果我們開發獨立應用,面向的是最終客戶,則無需考慮slf4j,因為最終客戶只關心功能實現,不會在意開發公司具體使用什么日志系統的。4.3、應用舉例: import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author chb * */ public class TestSlf4j { Logger log = LoggerFactory.getLogger(TestSlf4j.class); public void testLog(){ log.info("this is a test log"); } /** * @param args */ public static void main(String[] args) { TestSlf4j slf = new TestSlf4j(); slf.testLog(); } }
1>JDK自帶的log輸出 首先,我們在classpath中加入slf4j-api-1.5.10.jar和slf4j-jdk14-1.5.10.jar兩個包,然后運行main函數,輸出信息如下:view plaincopy to clipboardprint?2010-1-5 21:44:47 chb.test.slf4j.TestSlf4j testLog 信息: this is a test log 2010-1-5 21:44:47 chb.test.slf4j.TestSlf4j testLog信息: this is a test log 2>slg4j提供的simple log 然后,我們用slf4j-simple-1.5.10.jar替換slf4j-jdk14-1.5.10.jar,選擇使用slf4j提供的simple log,輸出信息如下:view plaincopy to clipboardprint?0 [main] INFO chb.test.slf4j.TestSlf4j - this is a test log 0 [main] INFO chb.test.slf4j.TestSlf4j - this is a test log 3>log4j日志輸出 再然后,我們再用slf4j-log4j12-1.5.10.jar替換slf4j-simple-1.5.10.jar(記得classpath也需要增加log4j依賴jar包),同時增加一個log4j.properties文件,我們再稍微修改一下main函數,加載一下log4j.properties,如;view plaincopy to clipboardprint?public static void main(String[] args) { PropertyConfigurator.configure("D://log4j.properties"); TestSlf4j slf = new TestSlf4j(); slf.testLog(); }
4.4、原理介紹--靜態綁定 大家看到要使用哪種日志系統,只需要將對應的日志系統所需要的jar包文件(包括slf4j提供的jar包和日志系統自身依賴的jar包,例如:slf4j-log4j12-1.5.10.jar和log4j.1.2.jar)放入classpath即可,slf4j可以自動探測具體使用哪種日志系統,這種技術被稱為靜態綁定。 在實際使用中,我們通過LoggerFactory.getLogger()獲得logger,查看LoggerFactory的源代碼會發現如下兩點,LoggerFactory通過StaticLoggerBinder.getSingleton().getLoggerFactory()獲得LogFactory,然后再通過該LogFactory來獲取logger的 但是StaticLoggerBinder類并不在slf4j-api-1.5.10.jar中,分析與具體日志系統相關的jar包,會發現每個jar包都有一個StaticLoggerBinder類的實現(如slf4j-log4j12-1.5.10.jar、slf4j-simple- 1.5.10.jar、slf4j-jdk14-1.5.10.jar均有StaticLoggerBinder類實現),這就很明白了,slf4j在啟動時會動態到classpath中查找StaticLoggerBinder類,找到之后就可以生成對應日志系統的日志文件了。 這里就有一個問題了,slf4j是如何將自己的通用日志格式轉成不同的日志系統的格式的呢? 我們再分析每個日志系統相關的源代碼,會發現不同日志系統包都會有一個Adapter,用來在slf4j和不同日志系統之間做轉換。
4.5、與common-logging的區別
Apache Common-Logging是廣泛使用的Java日志門面庫。我以前一直都使用它和log4j編寫日志。Apache Common-Logging通過動態查找的機制,在程序運行時自動找出真正使用的日志庫。Apache Common-Logging一直都運作得很好。直到最近,我寫OSGI插件時,它不能工作了。原因是Apache Common-Logging使用了ClassLoader尋找和載入底層的日志庫。而OSGI中,不同的插件使用自己的ClassLoader。一個線程的ClassLoader在執行不同的插件時,其執行能力是不同的。OSGI的這種機制保證了插件互相獨立,然而確使Apache Common-Logging無法工作!解決之道是使用新的日志門面庫Slf4j。Slf4j庫類似于Apache Common-Logging。但是,他在編譯時靜態綁定真正的Log庫。使用Slf4j時,如果你需要使用某一種日志實現,那么你必須選擇正確的Slf4j的jar包的集合。
-----------
# Properties for configuring Log4j
# Set logger level
log4j.rootLogger=CONSOLE
log4j.logger.org=CONSOLE
log4j.additivity.com.gm=false
log4j.additivity.com.eds=false
log4j.additivity.FrameworkLogging=false
log4j.additivity.com.gm.workbench.order.service.common.helper.mq=false
log4j.logger.com.gm=INFO,APP_LOG
#log4j.logger.com.gm.workbench.order.service.offline=CONSOLE
#log4j.logger.com.gm.workbench.order.service.online.elc=CONSOLE
log4j.logger.com.eds=CONSOLE
#log4j.logger.FrameworkLogging=CONSOLE
#log4j.logger.com.gm.workbench.order.service.common.helper.mq=CONSOLE
#log4j.logger.com.gm.workbench.order.service.online.elc=CONSOLE
#log4j.logger.com.gm.workbench.order.service.online.manageinventory=CONSOLE
#log4j.logger.com.gm.workbench.order.service.common.dataaccess=CONSOLE
#log4j.logger.com.gm.workbench.order.service.online.bulkorder=CONSOLE
# CONSOLE is set to be a ConsoleAppender
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{MM-dd@HH:mm:ss} %-5p %c{1}:(%13F:%L) %3x - %m%n
# APP_LOG is set to be a RollingFileAppender
log4j.appender.APP_LOG=org.apache.log4j.RollingFileAppender
log4j.appender.APP_LOG.MaxFileSize=5000KB
log4j.appender.APP_LOG.MaxBackupIndex=10
log4j.appender.APP_LOG.File =c:/log4j/app-logger.log
log4j.appender.APP_LOG.Append = true
log4j.appender.APP_LOG.layout=org.apache.log4j.PatternLayout
log4j.appender.APP_LOG.layout.ConversionPattern=%d{MM-dd@HH:mm:ss} %-5p %c{1}:(%13F:%L) %3x - %m%n
# AUD_LOG is set to be a RollingFileAppender
log4j.appender.AUD_LOG=org.apache.log4j.RollingFileAppender
log4j.appender.AUD_LOG.MaxFileSize=50000KB
log4j.appender.AUD_LOG.MaxBackupIndex=5
log4j.appender.AUD_LOG.File =c:/log4j/audit-logger_001.log
log4j.appender.AUD_LOG.Append = true
log4j.appender.AUD_LOG.layout=org.apache.log4j.PatternLayout
log4j.appender.AUD_LOG.layout.ConversionPattern=%d{MM-dd@HH:mm:ss} %-5p %c{1}:(%13F:%L) %3x - %m%n
新聞熱點
疑難解答