1. 程式人生 > >Log4j2與Slf4j的最佳實踐

Log4j2與Slf4j的最佳實踐

前言

日誌對於專案的重要性不言而喻,現在市面上的日誌框架多種多樣:Log4j、Log4j2、Slf4j、JDKLog、Logback等等,如果沒有真正深入瞭解過,可能會被搞得眼花繚亂。本文將介紹目前Java專案中最常見的Log4j2 + Slf4j的使用組合,這也是我自己專案中目前使用的。

另外,由於現在專案基本都是Servlet 3.0及以上版本,因此本文針對Servlet 3.0及更高的版本,如果使用的是Servlet 2.5可以參考官方文件進行適當的調整。

如何檢視Servlet版本?

檢視web.xml檔案中<web-app>標籤中的version欄位即可。

關於Log4j2

在上面提到的日誌框架中,以Log4j + Slf4j的使用組合最為常見,但是我們知道Log4j目前已經停止更新了。Apache推出了新的Log4j2來代替Log4j,Log4j2是對Log4j的升級,與其前身Log4j相比有了顯著的改進,並提供了許多Logback可用的改進,同時解決了Logback體系結構中的一些固有問題。因此,Log4j2 + Slf4j應該是未來的大勢所趨。

Log4j2的效能

Log4j2最牛逼的地方在於非同步輸出日誌時的效能表現,Log4j2在多執行緒的環境下吞吐量與Log4j和Logback的比較如下圖。下圖比較中Log4j2有三種模式:1)全域性使用非同步模式;2)部分Logger採用非同步模式;3)非同步Appender。可以看出在前兩種模式下,Log4j2的效能較之Log4j和Logback有很大的優勢。

Log4j2使用的幾個點

  1. 在Web專案中需要新增 log4j-web jar包。
  2. Log4j允許使用log4jConfiguration引數在web.xml中指定配置檔案位置。Log4j將通過以下方式搜尋配置檔案:
    1. 如果配置了路徑(log4jConfiguration引數配置),Log4j將去搜索這個位置。
    2. 如果未配置路徑,Log4j將搜尋WEB-INF目錄中“log4j2”開頭的檔案。如果找到多個檔案,並且存在以“log4j2-name”開頭的檔案,其中name是Web應用程式的名稱,則會使用它。否則,將使用第一個檔案。
    3. 在resources目錄下搜尋配置檔案,規則同b。
  3. Log4j2不支援Servlet 2.4及更老的的Web應用程式。

第2點講的簡單點就是:Log4j2的配置檔名以“log4j2”開頭時(例如常見的log4j2.xml),放在WEB-INF和resources的根路徑時不需要在web.xml中配置路徑,放在其他位置時需要配置路徑。

基本的使用(同步模式)

1.maven依賴

<!--
log4j2核心包--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> <!-- Web專案需新增 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>2.9.1</version> </dependency> <!--用於與slf4j保持橋接--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.9.1</version> </dependency> <!-- slf4j核心包--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency>

2.在resources根路徑下新增log4j2.xml配置檔案(無需配置路徑)

logj2.xml檔案內容:將info及以上級別的日誌輸出到Console和指定路徑的檔案中。

3.web.xml配置log4j2配置檔案的路徑

如果log4j2.xml放在WEB-INF和resources根路徑則不需要。

<!-- log4j2.xml路徑 -->
<context-param>
    <param-name>log4jConfiguration</param-name>
    <param-value>/config/log4j2.xml</param-value>
</context-param>

4.如果是從Log4j等其他日誌轉的Log4j2 + Slf4j的,記得把Mavne中原來日誌框架的依賴去掉或exclusion掉

常見的有:log4j和slf4j-log4j12,如下。

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

5.程式碼中使用

import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * @Author joonwhee
 * @Date 2018/3/31
 */
@Controller
@RequestMapping("/user")
public class UserController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
    @RequestMapping("/userList")
    public String userList(HttpServletRequest request, Model model) {
        LOGGER.info("Test log4j2 info");
        LOGGER.warn("Test log4j2 warn");
        LOGGER.error("Test log4j2 error");
        return "userList";
    }
}

6.使用結果

呼叫該方法後,Console輸出:

在log4j2.xml檔案中配置的路徑下生成日誌檔案:

開啟日誌檢視輸出內容:

這裡Console輸出和日誌檔案輸出“字首”不完全一致是由於上面log4j2.xml中Console和RollingFile的PatternLayout配置不一致導致的。

至此,Log4j2整合Slf4j就完成了。

擴充套件測試

關於上面提到的Log4j2配置檔案存放路徑的問題,我們來做幾個簡單的測試:

場景1:log4j2.xml放在resources/config路徑下,在web.xml中配置log4jConfiguration指定路徑。

效果:日誌正常輸出。

結論:Log4j能找到配置檔案。

場景2:log4j2.xml放在resources/config路徑下,註釋掉web.xml中的log4jConfiguration配置。

效果:明顯看出我們的配置已經失效了,但是輸出了ERROR級別的日誌,可以推測這是Log4j在找不到配置檔案時的兜底策略。

結論:Log4j不能找到配置檔案。

場景3:log4j2.xml放在resources根路徑下,註釋掉web.xml中的log4jConfiguration配置。

效果:日誌正常輸出。

結論:Log4j能找到配置檔案。

場景4:log4j2.xml放在WEB-INF根路徑下,註釋掉web.xml中的log4jConfiguration配置。

效果:日誌正常輸出。

結論:Log4j能找到配置檔案。

看完測試結果,大家就可以根據自己的習慣將log4j2.xml放到自己喜歡的地方了。

進階使用(非同步模式)

非同步模式下,預設情況不會輸出位置資訊,因為輸出位置資訊會慢30-100倍。如果需要位置資訊,需要在所有相關記錄器(包括根記錄器)的配置中設定“includeLocation = true”。

例如以下程式碼:

<asyncRoot level="info" includeLocation="true">
    <AppenderRef ref="RandomAccessFile"/>
</asyncRoot>

什麼是位置資訊?

直接看下面兩張圖就很明顯了。

有位置資訊:

無位置資訊:

1.全域性使用非同步(在同步模式的基礎上修改)

1.maven增加disruptor依賴,Log4j2版本2.9及以上時需要disruptor-3.3.4.jar或更高版本;Log4j2版本2.9以下時需要disruptor-3.0.0.jar或更高版本。

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.4</version>
</dependency>

2.將系統屬性log4j2.contextSelector設定為org.apache.logging.log4j.core.async.AsyncLoggerContextSelector。

方式:新增一個名字為log4j2.component.properties的檔案,放到classpath下面,log4j2會在啟動的時候自動載入。如下:

3.log4j2.xml的配置修改成如下,跟同步模式的區別為RollingFile變成了RandomAccessFile。

2.部分Logger採用非同步方式(在同步模式的基礎上修改)

1.maven增加disruptor依賴,Log4j2版本2.9及以上時需要disruptor-3.3.4.jar或更高版本;Log4j2版本2.9以下時需要disruptor-3.0.0.jar或更高版本。

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.4</version>
</dependency>

2.使用<asyncRoot>或<asyncLogger>配置來指定需要非同步的記錄器。

<asyncRoot level="info">
    <AppenderRef ref="RandomAccessFile"/>
</asyncRoot>

3.log4j2.xml的配置修改成如下,跟同步模式的區別為:1)RollingFile變成了RandomAccessFile;2)loggers中使用了<asyncRoot>或<asyncLogger>。

注意:配置只能包含一個根記錄器(<root>或<asyncRoot>元素),但可以組合非同步和非非同步記錄器。例如,包含<asyncLogger>元素的配置檔案也可以包含同步記錄器的<Root>和<Logger>元素。

簡單效能測試

簡單的測試下以下三種模式的耗時:全域性使用非同步的Log4j2、部分Logger使用非同步的Log4j2、使用同步模式的Log4j2。

測試程式碼

1.測試例子很簡單,就是將之前的3行輸出外面加個64萬次的迴圈。

2.將輸出Console去掉,只輸出到檔案,同步模式下的Appenders為RollingFile;非同步模式下的Appenders為RandomAccessFile。

場景1:RollingFile + 同步模式不帶位置資訊

場景1的配置檔案主要內容如下

測試結果如下圖:總共耗時17678ms

場景2:RollingFile + 同步模式帶位置資訊

場景2的配置檔案主要內容如下,跟場景1只有includeLocation屬性值不同

測試結果如下圖:總共耗時257268ms

場景3:RandomAccessFile + 全域性使用非同步

場景3的配置檔案主要內容如下

測試結果如下圖:總共耗時2303ms

相關推薦

Log4j2Slf4j最佳實踐

前言日誌對於專案的重要性不言而喻,現在市面上的日誌框架多種多樣:Log4j、Log4j2、Slf4j、JDKLog、Logback等等,如果沒有真正深入瞭解過,可能會被搞得眼花繚亂。本文將介紹目前Jav

打造立體化監控體系APM最佳實踐系列

一、背景 年來在雲端計算、大資料等快速發展的時代下,產生了很多新的業務場景,同時很多企業傳統業務開始向網際網路的轉移。隨著企業業務的發展,規模擴大,業務越來越多,所採用的元件也越來越多開始走向分散式化,如微服務、訊息收發、分散式資料庫、分散式物件儲存、分散式快取、跨域呼叫等,這些元件共同構成了繁雜的

Atitit.angular.js 使用最佳實踐 原理常見問題解決列表顯示案例 attilax總結

依賴 實現 http dsi 概念 模板 style ctr net Atitit.angular.js 使用最佳實踐 原理與常見問題解決與列表顯示案例 attilax總結 1. 本文範圍 1 2. Angular的長處 1 2.1. 雙向數據綁定 1 2.2. d

《virtual san 最佳實踐》節選 Virtual SAN的發展現狀

改變 檢查 center ops 運行 對象 使用 qos 在線升級 Virtual SAN的發展與現狀Virtual SAN已經叠代更新到第四代,即Virtual SAN 6.2。通過三次主版本叠代,Virtual SAN已經成為一款非常成熟的軟件定義存儲軟件。在此,我們

微服務架構的兩大解耦利器最佳實踐

架構 微服務 沈劍 這幾年,微服務架構這個術語漸成熱門詞匯,但它不是一個全新架構,更不是一個包治百病的架構。那麽,微服務架構究竟能夠解決什麽問題,又帶來哪些痛點?本文將與大家談談這個問題,以及微服務架構的兩大解耦利器配置中心和消息總線的最佳實踐。微服務架構解決的問題與帶來的痛點一互聯網高可用架構為

《深入理解Java虛擬機:JVM高級屬性最佳實踐》讀書筆記(更新中)

pen 內存區域 深度 span 進化 ria 最短 描述 core 第一章:走進Java 概述 Java技術體系 Java發展史 Java虛擬機發展史 1996年 JDK1.0,出現Sun Classic VM HotSpot VM, 它是 Sun JDK 和 Open

php核心技術最佳實踐知識點(上)

mode roc url mys 修改 class null nbsp (上) 一.基礎 1.serialize:序列化一個類,只是保存了類的屬性,所以還需要反序列化unserialize的時候包含該類. 2.對於將array轉為object,這個轉換因為沒有具體的類,所以

php核心技術最佳實踐知識點(下)

清空 倒序 var 統計 apache this is_null 技術 其他 九.緩存 1.緩存三大要素:命中率, 緩存更新策略,緩存最大數據量 2.命中率(mysql為例):mysql提供了一系列的query cache的global status來提現數據庫緩存的情況:

《深入理解Java虛擬機:JVM高級特性最佳實踐》【PDF】下載

構建 實現原理 jvm內存 本地方法棧 人物 lvm 劃分 同時 棧溢出 《深入理解Java虛擬機:JVM高級特性與最佳實踐》【PDF】下載鏈接: https://u253469.pipipan.com/fs/253469-230062566 內容簡介 作為一位j

Celery學習--- Celery 最佳實踐django結合實現異步任務

tar load modules bin min sta 版本差異 status linux django 可以輕松跟celery結合實現異步任務,只需簡單配置即可 同步執行和異步執行 註意:即使Celery的任務沒有執行完成,但是已經創建了任務ID。可以利用前臺的定時

Spring Boot 最佳實踐(二)集成Jsp生產環境部署

內容 tro conf 相關 安裝 packaging exc 詳細介紹 更新 一、簡介 提起Java不得不說的一個開發場景就是Web開發,也是Java最熱門的開發場景之一,說到Web開發繞不開的一個技術就是JSP,因為目前市面上仍有很多的公司在使用JSP,所以本文就來介紹

Istio技術實踐03:最佳實踐之sidecar自動註入

初始 aml emp tco git master oct 介紹 bec Istio通過對serviceMesh中的每個pod註入sidecar,來實現無侵入式的服務治理能力。其中,sidecar的註入是其能力實現的重要一環(本文主要介紹在kubernetes集群中的註入方

JavaScript - undefinednull的區分及最佳實踐

操作 boolean 強調 特殊屬性 fine 高級 不同 erro javascrip 主要參考 《JavaScript高級程序設計》 ECMAScript中的六種數據類型 ECMAScript中包含六種數據類型: Undefined Null Boolean

互動參與的最佳實踐

這些課程教你如何通過實現 Android 的最佳互動模式來吸引和留住你的使用者。例如, 為了幫助使用者快速發現您的應用程式中的內容, 您的應用程式應該符合他們對 Android 上使用者互動的期望。為了讓您的使用者回來, 您應該利用平臺功能來顯示和開啟您的內容, 而不需要使用者通過應用程式啟

Ansible自動化運維:技術最佳實踐

資深運維人員聯手打造。 掌握大規模叢集運維管理的必備參考。 詳細講解Ansible自動化運維方式與技巧。 Ansible是DevOps語言之一,是第一款可以讀/寫跨平臺的“Infrastructure-as-code”工具,從系統管理者到開發者,都可使用Ansible自動化部署並

學習筆記1:深入理解Java虛擬機器——JVM高階特性最佳實踐_OOM(記憶體溢位)_虛擬機器引數設定_MAT

eclipse中設定debug標籤頁的vm引數 1,Run->Debug configurations->Java Application 2,選中已經寫好的專案 3,Arguments->VM arguments 4,在VM arguments 裡面就可以對虛擬機器的

學習筆記1:深入理解Java虛擬機器——JVM高階特性最佳實踐_走進java_java記憶體區域記憶體溢位異常

第一部分:走進java Java虛擬機器 程式碼在華章下載 jdk釋出了六個命令列工具和兩個視覺化故障處理工具。 推薦書籍 設計原本 領域特定語言 現在著名的Java虛擬機器 hotspot vm(預設) jrockit vm j9 vm jdk sun jdk op

溫習《PHP 核心技術最佳實踐》這本書

匹配 9.4 表達式 穩定 處理 變量 mem 分布式 內容 再次看這本書,順手提煉了一下大致目錄,以便後續看見目錄就知道大概講的些什麽內容 PHP 核心技術與最佳實踐 1、面向對象思想的核心概念 1.1 面向對象的『形』與『本』 1.2 魔術方法的應用

MongoDB 應用場景、避坑事項最佳實踐

社群最近組織了交流活動,探討MongoDB適合的應用場景、避坑事項與最佳實踐。由社群專家劉誠傑根據交流內容整理成文,無論是MongoDB零基礎的小夥伴,還是正在應用中的朋友,在此均可以找到有價值的經驗和分享。 劉誠傑,專注於MongoDB、MySQL、Redis等開源資料庫的使用與研究,Mo

Python自動化運維 :技術最佳實踐 [劉天斯著] 完整版pdf 下載

本書在中國運維領域將有“劃時代”的重要意義:一方面,這是國內一本從縱、深和實踐角度探討Python在運維領域應用的著作;一方面本書的作者是中國運維領域的“偶像級”人物,本書是他在天涯社群和騰訊近10年工作經驗的結晶。因為作者實戰經驗豐富,所以能高屋建瓴、直指痛處,圍繞Python自動化運維這個