天天看點

Java單體應用 - 常用架構 - 04.Log4jLog4j

原文位址: http://www.work100.net/training/monolithic-frameworks-log4j.html 更多教程: 光束雲 - 免費課程

Log4j

請參照如上

章節導航

進行閱讀

1.概述

一個完整的軟體,日志是必不可少的。

程式從開發、測試、維護、運作等環節,都需要向控制台或檔案等位置輸出大量資訊。

這些資訊的輸出, 在很多時候是使用

System.out.println()

無法完成的。

日志資訊根據用途與記錄内容的不同,分為:

調試日志

運作日志

異常日志

等。

Log4j

的全稱為

Log for java

,即專門用于 Java 語言的日志記錄工具。

2.日志級别

為了友善對于日志資訊的輸出顯示,對日志内容進行了分級管理。日志級别由高到低,共分 6 個級别:

  • fatal(緻命的)
  • error
  • warn
  • info
  • debug
  • trace(堆棧)

為什麼要對日志進行分級?

無論是将日志輸出到控制台,還是檔案,其輸出都會降低程式的運作效率。但由于調試、運作維護的需要,客戶的要求等原因,需要進行必要的日志輸出。這時就必須要在代碼中加入日志輸出語句。

這些輸出語句若在程式運作時全部執行, 則勢必會降低運作效率。例如, 使用

System.out.println()

将資訊輸出到控制台,則所有的該輸出語句均将執行。會大大降低程式的執行效率。而要使其不輸出,唯一的辦法就是将這些輸出語句逐個全部删除。這是個費時費力的過程。

将日志資訊進行分級管理,便可友善的控制資訊輸出内容及輸出位置:哪些資訊需要輸出,哪些資訊不需要輸出,隻需在一個日志輸出控制檔案中稍加修改即可。而代碼中的輸出語句不用做任何修改。

從這個角度來說,代碼中的日志編寫,其實就是寫大量的輸出語句。隻不過,這些輸出語句比較特殊,它們具有級别,在程式運作期間不一定被執行。它們的執行是由另一個控制檔案控制。

3.日志輸出

3.1.日志輸出簡介

Log4j 的日志輸出控制檔案,主要由三個部分構成:

  • 日志資訊的輸出位置:控制日志資訊将要輸出的位置,是控制台還是檔案等。
  • 日志資訊的輸出格式:控制日志資訊的顯示格式,即以怎樣的字元串形式顯示。
  • 日志資訊的輸出級别:控制日志資訊的顯示内容,即顯示哪些級别的日志資訊。

有了日志輸出控制檔案,代碼中隻要設定好日志資訊内容及其級别即可,通過控制檔案便可控制這些日志資訊的輸出了。

3.2.日志屬性配置檔案

日志屬性檔案

log4j.properties

是專門用于控制日志輸出的。其主要進行三方面控制:

  • 輸出位置:控制日志将要輸出的位置,是控制台還是檔案等。
  • 輸出布局:控制日志資訊的顯示形式。
  • 輸出級别:控制要輸出的日志級别。

日志屬性檔案由兩個對象組成:

日志附加器

根日志

根日志,即為 Java 代碼中的日志記錄器,其主要由兩個屬性構成:日志輸出級别與日志附加器。

日志附加器,則由日志輸出位置定義,由其它很多屬性進行修飾,如輸出布局、檔案位置、檔案大小等。

3.3.什麼是日志附加器?

所謂日志附加器,就是為日志記錄器附加上很多其它設定資訊。附加器的本質是一個接口,其定義文法為:

log4j.appender.appenderName = 輸出位置

常用的附加器實作類

附加器實作類 說明

org.apache.log4j.ConsoleAppender

日志輸出到控制台

org.apache.log4j.FileAppender

日志輸出到檔案

org.apache.log4j.RollingFileAppender

當日志檔案大小到達指定尺寸的時候将産生一個新的日志檔案

org.apache.log4j.DailyRollingFileAppender

每天産生一個日志檔案

3.4.常用布局類型

布局類型

org.apache.log4j.HTMLLayout

網頁布局,以 HTML 表格形式布局

org.apache.log4j.SimpleLayout

簡單布局,包含日志資訊的級别和資訊字元串

org.apache.log4j.PatternLayout

比對器布局,可以靈活地指定布局模式。其主要是通過設定 PatternLayout 的 ConversionPattern 屬性值來控制具體輸出格式的 。

列印參數: Log4J 采用類似 C 語言中的 printf 函數的列印格式格式化日志資訊

格式化編碼

%m

輸出代碼中指定的消息

%p

輸出優先級,即:

DEBUG

INFO

WARN

ERROR

FATAL

%r

輸出自應用啟動到輸出該 log 資訊耗費的毫秒數

%c

輸出所屬的類目,通常就是所在類的全名

%t

輸出産生該日志事件的線程名

%n

輸出一個回車換行符,Windows 平台為

/r/n

,Unix 平台為

/n

%d

輸出日志時間點的日期或時間,預設格式為

ISO8601

也可以在其後指定格式,比如:

%d{yyy MMM dd HH:mm:ss , SSS}

輸出類似:

2002年10月18日 22:10:28,921

%l

輸出日志事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。

舉例:

Testlog4.main(TestLog4.java: 10)

4.SLF4J

slf4j 的全稱是

Simple Loging Facade For Java

,即它僅僅是一個為 Java 程式提供日志輸出的統一接口,并不是一個具體的日志實作方案,就比如 JDBC 一樣,隻是一種規則而已。

是以單獨的

slf4j

是不能工作的,必須搭配其他具體的日志實作方案,比如 apache 的

org.apache.log4j.Logger

,JDK 自帶的

java.util.logging.Logger

以及

log4j

5.執行個體

仍然以

hello-spring

項目進行代碼示範。

5.1.更新POM

修改

pom.xml

檔案,增加

org.slf4j:slf4j-log4j12

依賴,代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.work100.training.stage2</groupId>
    <artifactId>hello-spring</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>
</project>           

5.2.建立 log4j.properties 配置檔案

src/main/resources

目錄下建立名為

log4j.properties

的屬性配置檔案,代碼如下:

log4j.rootLogger=INFO, console, file

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=logs/log.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.MaxFileSize=1024KB
log4j.appender.A3.MaxBackupIndex=10
log4j.appender.file.layout.ConversionPattern=%d %p [%c] - %m%n           

日志配置相關說明:

配置節

log4j.rootLogger

根日志,配置了日志級别為

INFO

,預定義了名稱為

console

file

兩種附加器

log4j.appender.console

console

附加器,日志輸出位置在控制台

log4j.appender.console.layout

console

附加器,采用比對器布局模式

log4j.appender.console.layout.ConversionPattern

console

附加器,日志輸出格式為:

日期

日志級别

[類名]

消息

換行符

log4j.appender.file

file

附加器,每天産生一個日志檔案

log4j.appender.file.File

file

附加器,日志檔案輸出位置

logs/log.log

log4j.appender.file.layout

file

log4j.appender.A3.MaxFileSize

日志檔案最大值

log4j.appender.A3.MaxBackupIndex

最多紀錄檔案數

log4j.appender.file.layout.ConversionPattern

file

日期

日志級别

[類名]

消息

5.3.測試日志輸出

建立一個測試類

Log4jTest.java

,并測試日志輸出效果,代碼如下:

package net.work100.training.stage2.hello.spring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>Title: Log4jTest</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-12 17:01
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-12   liuxiaojun     初始建立
 * -----------------------------------------------
 */
public class Log4jTest {
    public static final Logger logger = LoggerFactory.getLogger(Log4jTest.class);

    public static void main(String[] args) {
        logger.info("slf4j for info");
        logger.debug("slf4j for debug");
        logger.error("slf4j for error");
        logger.warn("slf4j for warn");

        String message = "Hello SLF4J";
        logger.info("slf4j message is : {}", message);
    }
}           

運作程式,此時控制台顯示為:

2020-02-12 17:03:43,734 INFO [net.work100.training.stage2.hello.spring.Log4jTest] - slf4j for info
2020-02-12 17:03:43,734 ERROR [net.work100.training.stage2.hello.spring.Log4jTest] - slf4j for error
2020-02-12 17:03:43,734 WARN [net.work100.training.stage2.hello.spring.Log4jTest] - slf4j for warn
2020-02-12 17:03:43,736 INFO [net.work100.training.stage2.hello.spring.Log4jTest] - slf4j message is : Hello SLF4J           

項目根目錄下也會多出

logs/log.log

目錄及檔案

5.4.占位符說明

打日志的時候使用了

{}

占位符,這樣就不會有字元串拼接操作,減少了無用 String 對象的數量,節省了記憶體。

并且,記住,在生産最終日志資訊的字元串之前,這個方法會檢查一個特定的日志級别是不是打開了,這不僅降低了記憶體消耗而且預先降低了 CPU 去處理字元串連接配接指令的時間。

6.執行個體源碼

執行個體源碼已經托管到如下位址:

上一篇:

JUnit

下一篇:

綜合執行個體
如果對課程内容感興趣,可以掃碼關注我們的

公衆号

QQ群

,及時關注我們的課程更新
Java單體應用 - 常用架構 - 04.Log4jLog4j
Java單體應用 - 常用架構 - 04.Log4jLog4j