Java中的日志管理


日志是應用程序運行中不可缺少的一部分,JAVA中有很多已經成熟的方案,盡管記錄日志是應用開發中並不可少的功能,在 JDK 的最初版本中並不包含日志記錄相關的 API 和實現。相關的 API(java.util.logging 包,JUL)和實現,直到 JDK 1.4 才被加入。因此在日志記錄這一個領域,社區貢獻了很多開源的實現。其中比較流行的包括 log4j 及其后繼者 logback。除了真正的日志記錄實現之外,還有一類與日志記錄相關的封裝 API,如 Apache Commons Logging 和 SLF4J。這類庫的作用是在日志記錄實現的基礎上提供一個封裝的 API 層次,對日志記錄 API 的使用者提供一個統一的接口,使得可以自由切換不同的日志記錄實現。比如從 JDK 的默認日志記錄實現 JUL 切換到 log4j。這類封裝 API 庫在框架的實現中比較常用,因為需要考慮到框架使用者的不同需求。在實際的項目開發中則使用得比較少,因為很少有項目會在開發中切換不同的日志記錄實現。

日志的實現

JAVA 中都有 java.util.logging, log4j ,logback,log4j2 等日志實現。其中logback是log4j作者覺得log4j已經太爛不想再改了,重新寫的一個實現。Log4j本來一統江湖好好的,后來被人說方法上太多同步修飾符,在高並發下性能太爛。Netflix的blitz4j就重新實現了一次log4j項目,去掉了大量的同步修飾符,不過其負責人自己說,新項目還是建議直接用logback。不過,后來apache社區感覺slf4j和logback都是log4j作者開的qos.ch公司的產品,日志是件很重要的事情,不應該操控在一家公司手里。所以又以純社區驅動搞了log4j2,參考了logback,也做了一些自己的改動。

SLF4J

http://www.slf4j.org/manual.html
SLF4J,即簡單日志門面(Simple Logging Facade for Java),不是具體的日志解決方案,它只為各種日志實現提供一個簡單統一的接口,從而使得最終用戶能夠在部署的時候配置自己希
望的實現。slf4j只是一個日志外殼,需要你加入slf4j-jdk14.jar, slf4j-log4j12.jar或logback.jar,將日志調用轉發到實際的日志框架。在classpath中有哪個jar包,slf4j就會選擇哪個實現。如果錯誤的同時存在多個jar包。比如:選擇JDK自帶的日志系統,則只需要將slf4j-api-xxx.jar和slf4j- jdk14-xxx.jar放置到classpath中即可,如果中途無法忍受JDK自帶的日志系統了,想換成log4j的日
志系統,僅需要用slf4j-log4j12-xxx.jar替換slf4j-jdk14-xxx.jar即可(當然也需要log4j的jar及配置文件)。
替換默認的common-logging
有些第三方的工具包,已經直接使用了log4j, common-logging 或 java.util.logging。如果我們最后決定使用log4j做最終輸出,則需要放一個jcl-over-slf4j.jar和 jul-to-slf4j.jar來替換common-logging或java.util.logging的api,將日志請求轉發給 slf4j,slf4j再轉發給log4j,此時還需要保證,classpath里沒有common-logging.jar。 而原本直接使用log4j的就不需要做任何改動。
Maven中使用SLF4J替換Common-logging(比如默認的Spring就依賴Common-logging)

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
          <exclusions>
              <exclusion>
                  <artifactId>commons-logging</artifactId>
                  <groupId>commons-logging</groupId>
              </exclusion>
          </exclusions>
      </dependency>
則可以把Common-logging排除掉后,使用Jcl-over-slf4j來替代綁定關系
  
  
  
          
      <!--slf4j-->
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>jcl-over-slf4j</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
      <!--spring-->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
          <exclusions>
              <exclusion>
                  <artifactId>commons-logging</artifactId>
                  <groupId>commons-logging</groupId>
              </exclusion>
          </exclusions>
      </dependency>
如果slf4j找不到對應的綁定關系,就會提示如下錯誤

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

綁定關系對應表

As mentioned previously, SLF4J supports various logging frameworks. The SLF4J distribution ships with several jar files referred to as "SLF4J bindings", with each binding corresponding to a supported framework.

slf4j-log4j12-1.7.9.jar
Binding for log4j version 1.2 , a widely used logging framework. You also need to place log4j.jar on your class path.
slf4j-jdk14-1.7.9.jar
Binding for java.util.logging, also referred to as JDK 1.4 logging
slf4j-nop-1.7.9.jar
Binding for NOP , silently discarding all logging.
slf4j-simple-1.7.9.jar
Binding for Simple implementation, which outputs all events to System.err. Only messages of level INFO and higher are printed. This binding may be useful in the context of small applications.
slf4j-jcl-1.7.9.jar
Binding for Jakarta Commons Logging . This binding will delegate all SLF4J logging to JCL.
logback-classic-1.0.13.jar (requires logback-core-1.0.13.jar)
Native implementation There are also SLF4J bindings external to the SLF4J project, e.g. logback which implements SLF4J natively. Logback's ch.qos.logback.classic.Logger class is a direct implementation of SLF4J's org.slf4j.Logger interface. Thus, using SLF4J in conjunction with logback involves strictly zero memory and computational overhead.

concrete-bindings

log4j

http://logging.apache.org/log4j/1.2/ 

log4j與slf4j是最常見的一種方式

image
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.7.10</version>
      </dependency>

log4j.properties

#Log4j
log4j.rootLogger=info,console

# 控制台日志設置
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#log4j.appender.console.layout.ConversionPattern=%p %d{HH:mm:ss.SSS} [%X{ip}] - %l %m%n
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss.SSS} %-5p [%F\:%L]%x %m%n

# 文件日志設置
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.file.file=/opt/logs/test.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss.SSS} %-5p [%F\:%L]%x %m%n

web.xml

    <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>Log4j</param-value>
    </context-param>
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.properties</param-value>
    </context-param>
    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>10000</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

JUnit
運行單元測試時,報以下錯誤
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See
http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
原因是找不到默認的log4j配置文件,可手動指定,如:
Log4jConfigurer.initLogging("classpath:log4j.test.properties");
log4j.test.properties是為執行單元測試類使用的一個配置文件

log4j2

http://logging.apache.org/log4j/2.x/  log4j2 是log4j的升級版

logback

http://logback.qos.ch/  logback是對slf4j的原生實現
Logstash

Refer:
Java 日志管理最佳實踐
http://www.ibm.com/developerworks/cn/java/j-lo-practicelog/
為什么要使用SLF4J而不是Log4J
http://www.importnew.com/7450.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM