log4j2使用介紹


工作中,用到了log4j2,以前只接觸過log4j,也沒有太過深入,這次就稍微系統的學習了以下log4j2.

一.引入pom.xml

使用maven作為項目的構建環境,pom.xml使用slf4j,slf4j是一個抽象層,可以使用任意的日志記錄.這里就不展開描述了,只需要知道,引入pom.xml后,配置依然和log4j2一樣,但是獲取到Logger對象稍有不同.只使用log4j2的話,一般是使用LogManager去獲取的,但是如果使用slf4j的話,使用LoggerFactory去獲取.(后面會講解)

<properties>
<!-- spring版本號 -->
<spring.version>4.3.2.RELEASE</spring.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.7.12</slf4j.version>
<log4j.version>2.1</log4j.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- spring核心包 -->
<!-- springframe start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!--log4j相關配置開始-->
<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>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${log4j.version}</version>
<scope>runtime</scope>
</dependency>
<!--log4j相關配置結束-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>

二.日志級別

  log4j2也有五種日志隔離級別,分別為:

  trace:追蹤,是最低的日志級別,相當於追蹤程序的執行,一般不怎么使用

  debug:一般在開發中,都將其設置為最低的日志級別.

  info:輸出感興趣的信息,我在開發中一般都會用info去輸出.

  warn:警告.有些時候,雖然程序不會報錯,但是還是需要告訴程序員的.

  error:錯誤,這個在開發中也挺常用的,,

  fetal:極其重大的錯誤,這個一旦發生,程序基本上也要停止了,,目前限於開發經驗,我還沒有碰到要碰到它的地方.

 

  日志通過Logger對象輸出,Logger對象的獲取見下文,輸出的API基本如下:Logger對象.日志級別("日志內容");例如:

 

  

 

  當日志級別設置為某個值的時候,低於它的日志信息將不會被輸出到appender中(稍后會講解),只有高於設置的級別的信息會被輸出到appender中.例如上例中,如果日志級別定義為error,那么這條信息將不會輸出.

三.appender和logger

  log4j2是用xml去定義需要的配置的,其中涉及到兩個重要的標簽,appenders和loggers.appenders顧名思義,代表將其信息輸出到哪里,在這個標簽內部定義了輸出位置的相關信息.appenders標簽內部可以有多個appender,表示可以輸出到多個位置.這些appender用具體的標簽去標識,例如<console>表示輸出到控制台的appender,<file>表示輸出到文件中.appender內部可以定義輸出的格式(用<pattern>標簽去標識.),可以定義在達到某個日志級別的時候才給予輸出,其余情況攔截(用<ThreadSholdFilter>標簽去標識.).

  loggers標簽則是定義了一些必要的logger,logger代表用於輸出日志信息的具體對象.logger內部有appender,指定這些對象輸出的具體位置.可以定義多個appender,其中,logger的定義比較特殊,因為它涉及到了繼承,可以結合log4j2的配置文件來看一看.注意log4j2.xml放在classpath下,不需要任何配置就可以加載.

<!-- status為不記錄log4j本身的日志 -->
<configuration status="OFF">
<properties>
<property name="LOG_HOME">C:/logs</property>
<property name="FILE_NAME">mylog</property>
</properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<!-- ThresholdFilter相當於攔截器.info以上的命令不會被攔截. -->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</Console>
<File name="Error" fileName="${LOG_HOME}/error.log">
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<RollingFile name="RollingFile" fileName="${LOG_HOME}/${FILE_NAME}.log"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10 MB"/>
</Policies>
</RollingFile>
</appenders>
<loggers>
<root level="info">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
<appender-ref ref="Error" />
</root>
<Logger name="com.hlhdidi.servlet" additivity="false">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
</Logger>
<Logger name="com.hlhdidi.service" level="error" additivity="true">
<appender-ref ref="Console"/>
</Logger>
</loggers>
</configuration>

  <properties>標簽定義了在配置文件上下文可能會用到的鍵值對的信息(類似於maven).重點看看<loggers>標簽,首先是root標簽.在log4j2默認所有的日志輸出對象(Loggger)都支持<root>標簽的相關配置.描述起來可能有些晦澀,但是只要看看Logger對象是如何在類中獲取就比較簡單了.下面代碼是在類中獲取Logger對象的方式(如果只使用log4j2使用LoggerManager去獲取,參數和返回值都是一樣的,就不介紹它了):

  這個參數是傳入Class對象,並且返回一個Logger.實際上還可以傳入一個字符串,如下:

  但是實際上我們傳入的參數是各種各樣的,log4j2怎么知道我們需要返回什么樣的Logger呢?實際上所有的Logger默認都繼承一個配置,就是<root>.log4j2根據name去配置文件依次與各個logger的name互相匹配,尋找對應的logger配置信息.當我們傳入的參數為Class對象的時候,實際上name為該Class對象的全類名,如果找到了,則采用該<logger>的配置信息,如果沒有找到,則采用默認的配置信息,也就是<root>中定義的配置信息,可以看出,我們在<root>中可以將日志信息輸出到三個位置.此外,在配置文件中定義name也是有"講究"的,前面提到,在Logger對象沒有在xml中找到匹配的name的時候,會采用<root>中定義的配置信息,實際上在我們定義<Logger>標簽的配置的時候,它默認也是繼承<root>中的配置信息的,也就是說,某個具體的<Logger>標簽在默認情況下會繼承<root>的所有配置.可以設置additivity為false,就可以不使用父類的配置信息.此外,Logger標簽相互之間也是有繼承的關系的.也就是一個Logger標簽的配置信息可以繼承另外一個<Logger>標簽內部的配置信息.這個log4j2通過name去實現.當一個logger的name是另外一個logger的name的前綴的時候,則稱該Logger是另外一個Logger的"父".例如:"com.hlhdidi.web"為name的<Logger>的配置可以繼承"com.hlhdidi"為name的<logger>的配置信息.同樣也可以使用additivity屬性指定不繼承.此外,也可以在<Logger>標簽上指定level屬性.它表示指定該Logger輸出日志的最低日志級別.但是有一種特殊情況需要注意:考慮下面的情況:定義了一個<Logger>它的日志級別為info,設置輸出到console,<root>的日志級別也定義為info,設置輸出到console.當我們使用.info輸出信息的時候,如果匹配到此<Logger>,那么根據繼承的關系,此時控制台上同一個信息會被輸出兩遍.這時候,如果我們將<root>的日志級別改為error,繼續使用.info輸出信息,(使用的Logger依然能匹配到配置文件上的一個具體的<Logger>)那么信息將會輸出幾次呢?通過輸出發現還是兩次.我推測可能是log4j內部只要匹配到一個<Logger>,在繼承的時候,將不會再次去判斷是否符合父類的日志級別.

四.使用

  說了那么多,其實使用log4j2還是很簡單的.實際上遵循以下步驟即可使用:

1.寫pom.xml/拷jar包

  log4j的核心jar包只有兩個,如下:

2.建立配置文件/書寫配置文件

  通常將log4j2.xml放在classpath下,這樣子在項目啟動的時候,就會加載.

3.在類中獲取Logger對象,使用Logger對象輸出信息

  Logger對象將根據匹配到的<Logger>里的內容輸出到指定的appender中.

@WebServlet("/MyWebServlet")
public class MyWebServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private Logger logger=LoggerFactory.getLogger(MyWebServlet.class);
    
    public MyWebServlet() {
        logger.error("myservlet初始化了,請做好准備!");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.error("調用了Get方法的哦");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.error("調用了post方法,即將被轉接到get方法中去");
    }

}

 五.SpringBoot整合log4j2

SpringBoot也是我非常喜歡的技術,它整合log4j2非常簡單:

1.書寫pom.xml

需要注意在springboot-starter-web中去掉log4j2的依賴

 <!--默認繼承父類去實現-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
        </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.7</java.version>
    </properties>
    <!-- 添加springboot的web模板 -->
   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions><!-- 去掉默認配置 -->  
                <exclusion>  
                    <groupId>org.springframework.boot</groupId>  
                    <artifactId>spring-boot-starter-logging</artifactId>  
                </exclusion>  
                </exclusions>  
        </dependency>
        <dependency> <!-- 引入log4j2依賴 -->  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-log4j2</artifactId>  
        </dependency>  
    </dependencies>
   <build>
        <plugins>
            <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

2.classpath下建立log4j2.xml以及application.properties文件

在application.properties中指定log4j2.xml的位置:

log4j2.xml省略,應該是和上文相似的配置

3.在Controller中去獲取Logger對象,並且打印日志

@Controller
public class WebController {
    
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @RequestMapping("/index")
    @ResponseBody
    public String index() {
        logger.info("hello world!!");
        return "hello world!";
    }
}

 


免責聲明!

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



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