commons-logging log4j的联系区别
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.4Logging
SimpleLog日志器
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%n
2.2.2應用于文件
- log4j.appender.FILE=org.apache.log4j.FileAppender???
- log4j.appender.FILE.File=file.log???
- log4j.appender.FILE.Append=false
- log4j.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 analysis
2.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=5001
- log4j.appender.SOCKET.LocationInfo=true
- # Set up for Log Facter 5
- log4j.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=2000
2.2.5應用于郵件
- log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender???
- log4j.appender.MAIL.Threshold=FATAL???
- log4j.appender.MAIL.BufferSize=10
- log4j.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%n
2.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
?
轉載于:https://www.cnblogs.com/dangzhenjiuhao/p/5188343.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的commons-logging log4j的联系区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 5621 KK's Point(
- 下一篇: 信号的其它特性