java日志框架详解-Log4j2

一、概述

     Apache Log4j 2 (Log4j – Apache Log4j 2)是对Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并参考了Logback中优秀的设计,同时修复了Logback架构中的一些问题。被誉为是目前最优秀的Java日志框架;企业中通常使用SLF4j门面+Log4j2来记录日志。
    Log4j2主要的性能提升:
    异常处理:在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制。
    性能提升:log4j2 相较于log4j 和 logback 都具有明显的性能提升,有18倍性能提升,后面会有官方测试的数据。
    自动重载配置: 参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态的修改日志的级别而不需要重启应用。
    无垃圾机制: log4j2 在大部分情况下,都可以使用其设计的一套无垃圾机制【对象重用、内存缓冲】,避免频繁的日志收集导致的 jvm gc。

自动重新加载配置

与 Logback 一样,Log4j 2 可以在修改时自动重新加载其配置。与Logback不同,它会这样做 在进行重新配置时不会丢失日志事件。

高级过滤

与 Logback 一样,Log4j 2 支持基于上下文数据、标记、正则表达式和其他组件进行过滤 日志事件。可以指定筛选以在传递到记录器之前或通过时应用于所有事件 追加器。此外,过滤器还可以与记录器相关联。与 Logback 不同,您可以使用通用 Filter 类 在任何这些情况下。

二、Log4j2入门案例

开发实例:

依赖引入POM.xml:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Log4j2配置
log4j2默认加载classpath下的 log4j2.xml 文件中的配置。

<?xml version="1.0" encoding="UTF-8"?><!--status : 这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,会看到log4j2内部各种详细输出monitorInterval : Log4j能够自动检测修改配置文件和重新配置本身, 设置间隔秒数。此处表示每隔600秒重读一次配置文件
-->
<Configuration status="OFF" monitorInterval="600"><!--日志级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL--><!--如果设置为WARN,则低于WARN的信息都不会输出--><Properties><!-- 配置日志文件输出目录,此处为项目根目录下的logs文件夹 --><Property name="LOG_HOME">/app/applogs</Property><!-- 配置日志文件名称前缀 --><Property name="LOG_FILE_NAME">cu-upcc-ccc1-provider</Property><!-- 配置输出日志级别-通用日志 --><Property name="LOG_LEVEL">INFO</Property><!-- 配置输出日志级别-重要日志1 --><Property name="LOG_LEVEL_V1">DEBUG</Property><!-- 配置日志输出源appender的名称 --><Property name="APPENDER_NAME">APP-PROVIDER</Property><!-- 配置子Logger是否继承父Logger的输出源,true-是,false-否,默认true --><Property name="LOGGER_ADDITIVITY">true</Property><!-- 触发日志文件分割的时间间隔,此配置必须和filePattern协调, 如果后者是精确到HH, 则此配置项单位是小时,若后者精确到dd, 则此配置项单位是天--><Property name="POLICY_TIME_BASED_INTERVAL">1</Property><!-- 日志清理规则 从basePath起清理日志文件的目录层级深度 --><Property name="DELETE_MAX_DEPTH">1</Property><!-- 日志清理规则 文件名称匹配规则 --><Property name="DELETE_IF_FILE_NAME">*.log-*</Property><!-- 日志清理规则 归档日志文件存在时长匹配规则,此配置项必须和filePattern协调, 后者是精确到HH, 这里就要写成xH, xd就不起作用, 另外, 数字最好>2, 否则可能造成删除的时候, 最近的文件还处于被占用状态,导致删除不成功! --><Property name="DELETE_IF_LAST_MODIFIED_AGE">24H</Property></Properties><Appenders><!--这个输出控制台的配置--><Console name="Console" target="SYSTEM_OUT"><!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--><ThresholdFilter level="${LOG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/><!--日志输出的格式--><PatternLayout pattern="|%d{yyyy-MM-dd HH:mm:ss.SSS}|%5p|%5t|%4c:%L|%X{PtxId}|%X{clientNodeName}|%X{serverNodeName}|%X{clientSysName}|%X{serverSysName}|%X{txId}|%X{logType}|%m|%n" /></Console><RollingRandomAccessFile name="${APPENDER_NAME}" fileName="${LOG_HOME}/${LOG_FILE_NAME}.log"filePattern="${LOG_HOME}/${LOG_FILE_NAME}.log-%d{yyyyMMddHH}"><PatternLayout pattern="|%d{yyyy-MM-dd HH:mm:ss.SSS}|%5p|%5t|%4c:%L|%X{PtxId}|%X{clientNodeName}|%X{serverNodeName}|%X{clientSysName}|%X{serverSysName}|%X{txId}|%X{logType}|%m|%n" /><Policies><TimeBasedTriggeringPolicy interval="${POLICY_TIME_BASED_INTERVAL}"/><!--<SizeBasedTriggeringPolicy size="50MB"/>--></Policies><DefaultRolloverStrategy><Delete basePath="${LOG_HOME}/" maxDepth="${DELETE_MAX_DEPTH}"><IfFileName glob="${DELETE_IF_FILE_NAME}" /><!--!Note: 这里的age必须和filePattern协调, 后者是精确到HH, 这里就要写成xH, xd就不起作用另外, 数字最好>2, 否则可能造成删除的时候, 最近的文件还处于被占用状态,导致删除不成功!--><IfLastModified age="${DELETE_IF_LAST_MODIFIED_AGE}" /></Delete></DefaultRolloverStrategy></RollingRandomAccessFile><!-- alarm plugins --><AlarmLog4j2Appender name="AlarmLog4j2Appender"  enableApollo="true" apNameSpace="cu-upcc-ccc1-provider"><PatternLayout pattern="|%d{yyyy-MM-dd HH:mm:ss.SSS}|%m" /></AlarmLog4j2Appender></Appenders><!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--><Loggers><Logger name="com.epay.cu1.upcc1.ccc1.provider" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><Logger name="com.epay.ts.lacs.log" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><Logger name="com.epay.ts.piss" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><Logger name="org.springframework" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><Logger name="com.ctrip.framework" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><Logger name="org.apache" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><Logger name="feign.Logger" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><Logger name="com.alibaba.druid" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="${APPENDER_NAME}"/></Logger><logger name="com.broad.assessment.business.dao" level="${LOG_LEVEL_V1}"><AppenderRef ref="${APPENDER_NAME}"/></logger><logger name="org.mybatis" level="${LOG_LEVEL_V1}"><AppenderRef ref="${APPENDER_NAME}"/></logger><logger name="com.unicompayment.basictools" level="${LOG_LEVEL_V1}"><AppenderRef ref="${APPENDER_NAME}"/></logger><!-- alarm plugins --><Logger name="com.epay.cu1.upcc1.ccc1.provider" level="${LOG_LEVEL}" additivity="${LOGGER_ADDITIVITY}"><AppenderRef ref="AlarmLog4j2Appender"/></Logger><Root level="${LOG_LEVEL}"><Appender-Ref ref="Console"/></Root></Loggers></Configuration>

 测试代码:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;public class Log4j2Test {private static final Logger logger = LogManager.getLogger();public Log4j2Test(){logger.info( "Hello World!" );}
}

三、Log4j2异步日志

Log4j2提供了两种实现日志的方式,一个是通过AsyncAppender,一个是通过AsyncLogger,分别对应前面我们说的Appender组件和Logger组件。

 POM文件异步日志依赖添加:

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

1、AsyncAppender有锁异步

  异步日志是通过引用别的Appender来实现的,当有日志事件到达时,会开启另外一个线程来处理它们。需要注意的是,如果在Appender的时候出现异常,对应用来说是无法感知的。AsyncAppender应该在它引用的Appender之后配置,默认使用java.util.concurrent.ArrayBlockingQueue实现而不需要其它外部的类库。当使用此Appender的时候,在多线程的环境下需要注意,阻塞队列容易受到锁争用的影响,这可能会对性能产生影响。这时候,我们应该考虑使用无锁的异步记录器(AsyncLogger)

日志配置文件
<Configuration status="fatal" monitorInterval="30"><Properties><Property name="myPattern" value="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/></Properties><Appenders><Console name="ConsoleAppend" target="SYSTEM_OUT"><PatternLayout pattern="${myPattern}"/><!-- 只接受程序中DEBUG级别的日志进行处理--><ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/></Console><!--在Appenders标签内创建Async异步标签--><Async name="AsyncConsoleAppend"><!--指定当前Appenders标签内的哪个Appender需要设置异步并通过引用--><AppenderRef ref="ConsoleAppend"/></Async></Appenders><Loggers><Root level="ALL"><!--设置异步的Appender--><AppenderRef ref="AsyncConsoleAppend"/></Root></Loggers>
</Configuration>

2、AsyncLogger无锁日志

  AsyncLogger才是log4j2实现异步最重要的功能体现,也是官方推荐的异步方式。它可以使得调用Logger.log返回的更快。你可以有两种选择:全局异步和混合异步。

  全局异步:所有的日志都异步的记录,在配置文件上不用做任何改动,只需要在jvm启动的时候增加一个参数即可实现。

  混合异步:你可以在应用中同时使用同步日志和异步日志,这使得日志的配置方式更加灵活。

  虽然Log4j2提供以一套异常处理机制,可以覆盖大部分的状态,但是还是会有一小部分的特殊情况是无法完全处理的,比如我们如果是记录审计日志(特殊情况之一),那么官方就推荐使用同步日志的方式,而对于其它一些仅仅是记录一个程序日志的地方,使用异步日志将大幅提升性能,减少对应用本身的影响。混合异步的方式需要通过修改配置文件来实现,使用AsyncLogger标记配置。

全局异步:

<!-- 导入所需的依赖坐标 -->
<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.4</version>
</dependency><!-- 在resources资源目录下创建log4j2.component.properties文件并编写配置 -->
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

混合异步:

<Configuration status="fatal" monitorInterval="30"><Properties><Property name="myPattern" value="%d{HH:mm:ss.SSS} [%t] %L %-5level %logger{36} - %msg%n"/></Properties><Appenders><Console name="ConsoleAppend" target="SYSTEM_OUT"><PatternLayout pattern="${myPattern}"/><!-- 只接受程序中DEBUG级别的日志进行处理--><ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/></Console></Appenders><Loggers><!--创建一个自定义的异步Logger--><!--name:对com.xw当前及其子包下的全部类的日志记录走此异步方式--><!--includeLocation:表示去除日志上的行号信息--><!--注:配置多个Logger时需要设置additivty来取消继承RootLogger--><AsyncLoggger name="com.xw" level="INFO" includeLocation="false" additivty="false"><AppenderRef ref="ConsoleAppend"/></AsyncLoggger><!--RootLogger--><Root level="ALL"><!--设置异步的Appender--><AppenderRef ref="ConsoleAppend"/></Root></Loggers>
</Configuration>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/129894.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

现货黄金指标之王是什么

很多现货黄金投资在日常看盘的交易的时候&#xff0c;都会借助各种各样的技术指标来辅助自己的分析&#xff0c;但其实好用的技术指标两三个就足够了。如果有那么一个指标&#xff0c;可以帮助投资者辨清趋势&#xff0c;把握行情走势的大局&#xff0c;一定会是大受市场欢迎。…

CSS 布局案例: 2行、多行每行格数不定,最后一列对齐

布局期望的效果如下&#xff1a; 第二行最后一格与第一行最后一格对齐。每行格数不定。自动拉伸填充整个宽度 实现&#xff1a; 一开始打算用display:flex&#xff0c; 自动分散&#xff0c;但是第二行对齐第一行最后一格控制不了。 使用grid fr均分单位控制。 <!DOCTYPE…

问题记录:无法删除.dll文件,显示“文件已在Windows资源管理器中打开”

序言 用过的无效方法列表&#xff1a; 360 解除占用无效360 粉碎无效单纯的用taskkill /f /t /im "xxx.dll" 进程名无效 解决方法 1&#xff09;tasklist /m 文件名 tasklist /m 得到进程PID 7692 2&#xff09;taskkill /F /PID 7692 &#xff08;该命令效果…

Feign(替代RestTemplate)远程调用

Feign初步学习 定义 Feign 是一个基于 Java 的 HTTP 客户端库&#xff0c;它是 Spring Cloud 中的一部分&#xff0c;用于简化微服务之间的 HTTP 通信。与传统的使用 RestTemplate 来调用 RESTful 服务不同&#xff0c;Feign 提供了一种声明式、基于接口的方式来定义和调用 H…

大语言模型学到什么

背景&#xff1a; 这篇文章是对《LANGUAGE MODELS REPRESENT SPACE AND TIME》论文的翻译加解读。之所以选这篇文章是因为最近在研究大模型的可解释性&#xff0c;以及基于可解释性对大模型的下游任务适配做训练级别可控性增强研究。其实总结成两句话就是&#xff1a; 1.大模…

WPFdatagrid结合comboBox

在WPF的DataGrid中希望结合使用ComboBox下拉框&#xff0c;达到下拉选择绑定的效果&#xff0c;在实现的过程中&#xff0c;遇到了一些奇怪的问题&#xff0c;因此记录下来。 网上能够查询到的解决方案&#xff1a; 总共有三种ItemSource常见绑定实现方式&#xff1a; 1.ItemS…

ctfshow web入门 php特性 web136-web140

1.web136 还有一种写文件的命令时tee命令 payload&#xff1a; : ls /|tee 1 访问1下载查看文件1发现根目录下有flag cat /f149_15_h3r3|tee 2 访问下载查看文件22.web137 call_user_func <?php class myclass {static function say_hello(){echo "He…

数据结构-图-最短路径问题

最短路径问题 单源最短路径Dijkstra算法原理代码实现 Bellman-Ford算法原理代码实现SPFA优化SPFA代码实现 多元最短路径Floyd-Warshall算法原理代码实现 单源最短路径 &#x1f680;最短路径&#xff1a;从图G的某个顶点出发到达另一个顶点的最短路径&#xff0c;其中最短是指…

PLC和工控机的网络特性

现场总线技术是工业自动化***深刻变革之一。PLC和工控机采用现场总线后可方便地作为I/O站和监控站连接在DCS系统中。现场总线是一种取代4&#xff5e;20mA标准&#xff0c;用于连接智能现场设备和控制设备的双向数字通讯技术&#xff0c;现场总线具有开放性和互操作性&#xff…

blender UV展开

快捷键&#xff1a;选面可以一点&#xff0c;选线或点变形&#xff0c;g 移动&#xff0c;l 孤岛化 a全选 在Shading视图下&#xff0c;给mesh建立一个栅格图的纹理 变成这个样子 UV实时展开&#xff1a; 在UV editing模式下&#xff0c;打开左右实时同步 焊接shift选中左边两个…

【算法|双指针系列No.3】leetcode202. 快乐数

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

react管理系统layOut简单搭建

一、新建立react文件夹&#xff0c;生成项目 npx create-react-app my-app cd my-app npm start 二、安装react-router-dom npm install react-router-dom 三、安装Ant Design of React&#xff08;UI框架库&#xff0c;可根据需求进行安装&#xff09; npm install antd …