当前位置:网站首页>Log4j2
Log4j2
2022-07-02 11:51:00 【xx985】
Log4j2簡介
Apache Log4j 2是對Log4j的昇級,它比其前身Log4j 1.x提供了重大改進,並提供了Logback中可用的許多改進,同時修複了Logback架構中的一些問題。被譽為是目前最優秀的Java日志框架。
Log4j2特征
性能提昇
Log4j2包含基於LMAX Disruptor庫的下一代异步記錄器。在多線程場景中,异步記錄器的吞吐量比Log4j 1.x和Logback高18倍,延遲低。自動重新加載配置
與Logback一樣,Log4j2可以在修改時自動重新加載其配置。與Logback不同,它會在重新配置發生時不會丟失日志事件。高級過濾
與Logback一樣,Log4j2支持基於Log事件中的上下文數據,標記,正則錶達式和其他組件進行過濾,此外,過濾器還可以與記錄器關聯。與Logback不同,Log4j2可以在任何這些情况下使用通用的Filter類。插件架構
Log4j使用插件模式配置組件。因此,您無需編寫代碼來創建和配置Appender,Layout,Pattern Converter等。在配置了的情况下,Log4j自動識別插件並使用它們。無垃圾機制
在穩態日志記錄期間,Log4j2 在獨立應用程序中是無垃圾的,在Web應用程序中是低垃圾。這减少了垃圾收集器的壓力,並且可以提供更好的響應性能。目前市面上最主流的日志門面就是SLF4J,雖然Log4j2 也是日志門面,因為它的日志實現功能非常强大,性能優越。所以我們一般情况下還是將 Log4j2 看作是日志的實現
SLF4j + Log4j2 的組合,是市場上最强大的日志功能實現方式,絕對是未來的主流趨勢。
异步日志
异步日志是log4j2最大的特色,其性能的提昇主要也是從异步日志中受益。
Log4j2提供了兩種實現日志的方式,一個是通過AsyncAppender,一個是通過AsyncLogger
注意這是兩種不同的實現方式,在設計和源碼上都是不同的體現。AsyncAppender方式
是通過引用別的Appender來實現的,當有日志事件到達時,會開啟另外一個線程來處理它們。需要注意的是,如果在Appender的時候出現异常,對應用來說是無法感知的。 AsyncAppender應該在它引用的Appender之後配置,默認使用 java.util.concurrent.ArrayBlockingQueue實現而不需要其它外部的類庫。 當使用此Appender的時候,在多線程的環境下需要注意,阻塞隊列容易受到鎖爭用的影響,這可能會對性能產生影響。這時候,我們應該考慮使用無鎖的异步記錄器(AsyncLogger)。AsyncLogger方式
AsyncLogger才是log4j2實現异步最重要的功能體現,也是官方推薦的异步方式。
它可以使得調用Logger.log返回的更快。你可以有兩種選擇:全局异步和混合异步。
全局异步:所有的日志都异步的記錄,在配置文件上不用做任何改動,只需要在jvm啟動的時候增加一個參數即可實現。
混合异步:你可以在應用中同時使用同步日志和异步日志,這使得日志的配置方式更加靈活。雖然Log4j2提供以一套异常處理機制,可以覆蓋大部分的狀態,但是還是會有一小部分的特殊情况是無法完全處理的,比如我們如果是記錄審計日志(特殊情况之一),那麼官方就推薦使用同步日志的方式,而對於其他的一些僅僅是記錄一個程序日志的地方,使用异步日志將大幅提昇性能,减少對應用本身的影響。混合异步的方式需要通過修改配置文件來實現,使用AsyncLogger標記配置。
<!-- log4j2 依賴 **********************************************-->
<!-- slf4j日志門面 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- log4j適配器 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
<!-- log4j2日志門面 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
<!-- log4j2日志實現 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
<!-- 异步日志依賴 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.7</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<!--
src/main/java/com/log4j2
配置全局通用屬性
-->
<properties>
<property name="logDir">D:</property>
</properties>
<!-- 配置appender -->
<Appenders>
<!-- 配置控制臺輸出 -->
<Console name="consoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>
</Console>
<!-- 配置文件輸出-->
<File name="fileAppender" fileName="${logDir}//log4j2.log">
<!-- 配置文件輸出格式 -->
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>
</File>
<!--
按照指定規則來拆分日志文件
fileName:日志文件的名字
filePattern:日志文件拆分後文件的命名規則
$${date:yyyy-MM-dd}:根據日期當天,創建一個文件夾
例如:2021-01-01這個文件夾中,記錄當天的所有日志信息(拆分出來的日志放在這個文件夾中)
2021-01-02這個文件夾中,記錄當天的所有日志信息(拆分出來的日志放在這個文件夾中)
rollog-%d{yyyy-MM-dd-HH-mm}-%i.log
為文件命名的規則:%i錶示序號,從0開始,目的是為了讓每一份文件名字不會重複
-->
<!-- <RollingFile name="rollingFile" fileName="${logDir}/rollog.log"-->
<!-- filePattern="${logDir}/$${date:yyyy-MM-dd}/rollog-%d{yyyy-MM-dd-HH-mm}-%i.log">-->
<!-- <!– 日志消息格式 –>-->
<!-- <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>-->
<!-- <Policies>-->
<!-- <!– 在系統啟動時,觸發拆分規則,產生一個日志文件 –>-->
<!-- <OnStartupTriggeringPolicy/>-->
<!-- <!– 按照文件的大小進行拆分 –>-->
<!-- <SizeBasedTriggeringPolicy size="10KB"/>-->
<!-- <!– 按照時間節點進行拆分 拆分規則就是filePattern–>-->
<!-- <TimeBasedTriggeringPolicy/>-->
<!-- </Policies>-->
<!-- <!– 在同一目錄下,文件的個數限制,如果超出了設置的數值,則根據時間進行覆蓋,新的覆蓋舊的規則–>-->
<!-- <DefaultRolloverStrategy max="30"/>-->
<!-- </RollingFile>-->
<!-- 配置异步日志 (不能和下面的自定義配置异步同時存在)-->
<!--<Async name="myAsync">
<!– 將控制臺輸出做异步的操作 –>
<AppenderRef ref="consoleAppender"/>
</Async>-->
</Appenders>
<!-- 配置logger -->
<Loggers>
<!-- 自定義logger,讓自定義的logger為异步logger -->
<!-- includeLocation="false"錶示去除日志記錄中的行號信息,這個行號信息非常的影響日志記錄的效率(生產中都不加這個行號)
嚴重的時候可能記錄的比同步的日志效率還有低
additivity="false" 錶示不繼承rootlogger -->
<AsyncLogger name="com.log4j2" level="trace"
includeLocation="false" additivity="false">
<!-- 將控制臺輸出consoleAppender,設置為异步打印 -->
<AppenderRef ref="consoleAppender"/>
<!-- 將控制臺輸出fileAppender,設置為异步打印 -->
<AppenderRef ref="fileAppender"/>
</AsyncLogger>
<!-- 配置rootlogger -->
<Root level="trace">
<!-- 引用Appender -->
<!--<AppenderRef ref="consoleAppender"/>-->
<AppenderRef ref="fileAppender"/>
<!--<AppenderRef ref="rollingFile"/>-->
<!--<AppenderRef ref="myAsync"/>-->
<AppenderRef ref="consoleAppender"/>
</Root>
</Loggers>
</Configuration>
package com.log.log4j2;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log4j2Test {
@Test
public void test01(){
/*--------------------------------------------------------
入門案例
單純的使用Log4j2的 門面+實現
默認為error級別信息的打印
不過目前最主流的日志使用搭配方式:slf4j+log4j2
*/
/*---------------------使用配置文件-----------------------------------
使用配置文件
log4j2是參考logback創作出來的,所以配置文件也是使用xml
log4j2同樣是默認加載類路徑(resources)下的log4j2.xml文件中的配置
根標簽,所有日志相關信息,都是在根標簽中進行配置
<Configuration status="debug" monitorInterval="數值"></Configuration>
在根標簽中,可以加屬性
status="debug" 日志框架本身的日志輸出級別
monitorInterval="5" 自動加載配置文件的間隔時間,不低於5秒
*/
/*--------------------------------------------------------
雖然log4j2也是日志門面,但是現在市場的主流趨勢仍然是slf4j
所以我們仍然需要使用slf4j作為日志門面,搭配log4j2强大的日志實現功能,進行日志的相關操作
接下來我們配置的就是當今市場上的最强大,最主流的日志使用搭配方式:
slf4j+log4j2
1.導入slf4j的日志門面
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
2.導入log4j2的適配器
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
3.導入log4j2的日志門面
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
4.導入log4j2的日志實現
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
執行原理:slf4j門面調用的是log4j2的門面,再由log4j2的門面調用log4j2的實現
*/
/*---------------將日志輸出到文件中-----------------------------------------
<File name="fileAppender" fileName="${logDir}//log4j2.log">
<!-- 配置文件輸出格式 -->
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>
</File>
*/
/*---------------日志的拆分-----------------------------------------
<RollingFile name="rollingFile" fileName="${logDir}/rollog.log"
filePattern="${logDir}/$${date:yyyy-MM-dd}/rollog-%d{yyyy-MM-dd-HH-mm}-%i.log">
<!-- 日志消息格式 -->
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>
<Policies>
<!-- 在系統啟動時,觸發拆分規則,產生一個日志文件 -->
<OnStartupTriggeringPolicy/>
<!-- 按照文件的大小進行拆分 -->
<SizeBasedTriggeringPolicy size="10KB"/>
<!-- 按照時間節點進行拆分 拆分規則就是filePattern-->
<TimeBasedTriggeringPolicy/>
</Policies>
<!-- 在同一目錄下,文件的個數限制,如果超出了設置的數值,則根據時間進行覆蓋,新的覆蓋舊的規則-->
<DefaultRolloverStrategy max="30"/>
</RollingFile>
*/
// 單純的使用Log4j2的 門面+實現
// Logger logger = LogManager.getLogger(Log4j2Test.class);
// 使用lf4j+log4j2
Logger logger = LoggerFactory.getLogger(Log4j2Test.class);
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
@Test
public void test02(){
/*
异步日志實現(單獨分配線程做日志的記錄)
方式1:使用AsyncAppender的方式
1.添加异步日志依賴
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.7</version>
</dependency>
2.在Appenders標簽中,對於异步進行配置
使用Async標簽
<!-- 配置异步日志 -->
<Async name="myAsync">
//將控制臺輸出做异步的操作
<AppenderRef ref="consoleAppender"/>
</Async>
3.rootlogger引用Async
<Root>
<AppenderRef ref="myAsync"/>
</Root>
*********************************************
异步日志實現(單獨分配線程做日志的記錄)
方式2:使用AsyncLogger的方式
1、全局异步:
所有的日志都是异步的日志記錄,在配置文件上不用做任何的改動
只需要在類路徑resources下添加一個properties屬性文件,做一步配置即可
文件名要求是:log4j2.component.properties
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
2、混合异步:(********主要用這個*********)
可以在應用中同時使用同步日志和异步日志,這使得日志的配置及輸出會更加的靈活
需求:
假設我們現在有自定義的logger -- com.log
讓自定義的logger是异步的
讓rootlogger是同步的
就是說文件在這個路徑下(com.log)的日志是异步操作,其他路徑則是同步
includeLocation="false" 錶示去除日志記錄中的行號信息,
additivity="false" 錶示不繼承rootlogger
<AsyncLogger name="com.log" level="trace"
includeLocation="false" additivity="false">
<!-- 將控制臺輸出consoleAppender,設置為异步打印 -->
<AppenderRef ref="consoleAppender"/>
</AsyncLogger>
注意:
在做測試前,一定要將全局的异步配置注釋掉
對於當前的logger,Log4j2Test01.class
Log4j2Test01本身就是在我們自定義的logger路徑下的
注意:
如果使用异步日志
AsyncAppender、AsyncLogger不要同時出現,沒有這個需求,效果也不會疊加
如果同時出現,那麼效率會以AsyncAppender為主
AsyncLogger的全局异步和混合异步也不要同時出現,沒有這個需求,效果也不會疊加
*/
Logger logger = LoggerFactory.getLogger(Log4j2Test.class);
//日志的記錄
for (int i = 0; i < 2000; i++) {
logger.error("error信息");
logger.warn("warn信息");
logger.info("info信息");
logger.debug("debug信息");
logger.trace("trace信息");
}
//系統業務邏輯
for (int i = 0; i < 1000; i++) {
System.out.println("------------------");
}
}
}
边栏推荐
- HOW TO CREATE A BEAUTIFUL INTERACTIVE HEATMAP IN R
- Precautions for scalable contract solution based on openzeppelin
- 抖音海外版TikTok:正与拜登政府敲定最终数据安全协议
- Visualization of chip SEQ data by deeptools
- PX4 Position_ Control RC_ Remoter import
- Principle of scalable contract delegatecall
- Is it safe to open a stock account online? I'm a novice, please guide me
- File operation (detailed!)
- php 根据经纬度查询距离
- 可昇級合約的原理-DelegateCall
猜你喜欢
电脑无缘无故黑屏,无法调节亮度。
在连接mysql数据库的时候一直报错
CTF record
揭露数据不一致的利器 —— 实时核对系统
制造业数字化转型和精益生产什么关系
HOW TO ADD P-VALUES ONTO A GROUPED GGPLOT USING THE GGPUBR R PACKAGE
How to Easily Create Barplots with Error Bars in R
HOW TO ADD P-VALUES TO GGPLOT FACETS
How to Easily Create Barplots with Error Bars in R
How to Create a Nice Box and Whisker Plot in R
随机推荐
A white hole formed by antineutrons produced by particle accelerators
Installation of ROS gazebo related packages
通讯录的实现(文件版本)
YYGH-BUG-04
BEAUTIFUL GGPLOT VENN DIAGRAM WITH R
QT meter custom control
HOW TO ADD P-VALUES ONTO A GROUPED GGPLOT USING THE GGPUBR R PACKAGE
K-Means Clustering Visualization in R: Step By Step Guide
flutter 问题总结
Always report errors when connecting to MySQL database
揭露数据不一致的利器 —— 实时核对系统
HOW TO EASILY CREATE BARPLOTS WITH ERROR BARS IN R
HOW TO CREATE AN INTERACTIVE CORRELATION MATRIX HEATMAP IN R
进入前六!博云在中国云管理软件市场销量排行持续上升
bedtools使用教程
Easyexcel and Lombok annotations and commonly used swagger annotations
R HISTOGRAM EXAMPLE QUICK REFERENCE
基于Hardhat编写合约测试用例
How to Create a Nice Box and Whisker Plot in R
Dynamic memory (advanced 4)