今天,我将向您介绍log4j2的异步使用以及添加自定义参数的方法。很多人可能不太了解。为了让大家更加了解,边肖为大家总结了以下内容。希望你能从这篇文章中有所收获。
00-1010关于log4j2的性能和原理我就不赘述了。本文主要介绍使用、配置文件解释、添加自定义参数和部分应用。
与其他日志系统相比,log4j2的数据丢失更少。在多线程环境中,颠覆者技术的性能比日志备份高10倍以上。利用jdk1.5的并发性,减少了死锁。
目前log4j2的表现最为突出。
log4j2异步使用及添加自定义参数
相关性
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-web/artifactId
排除!-删除回弹的默认配置-
排除
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-log/artifactId
/排除
/排除
/依赖性
依赖性!-引入log4j2依赖性-
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-log4j 2/artifactId
/dependency然后将文件log4j2.xml添加到每个项目中,并将@slf4j注释(lombok的)添加到要使用的类中,这样就可以使用log对象了。
Log4j 2.0与之前的1.x明显不同,其配置文件只能是。xml,json或。jsn。默认情况下,系统选择的配置文件的优先级如下:(类路径为src文件夹)
类路径是一个名为log4j-test.json或log4j-test.jsn的文件。
类路径名为log4j 2-test.xml。
路径是名为log4j.json或log4j.jsn的文件。
路径名为log4j2.xml
级别:日志输出级别,有8个级别,从低到高:所有跟踪调试信息警告错误致命关闭。
添加依赖(这里省略了版本号)
?xmlversion='1.0 '编码='UTF-8 '?
!-用于设置log4j2内部信息输出的- Configuration后面的状态无法设置。当它被设置为trace时,您将看到log4j2-的各种详细的内部输出
!- monitorInterval:Log4j可以自动检测配置文件的修改并自行重新配置,并设置间隔秒数-
configurationstatus='WARN '
性能
!-公共变量配置用于以下用途-
属性=' app _ name '项目名称/属性
property name=' LOGGER _ LEVEL ' INFO/property
!-日志路径对应于服务器路径-
property name=' LOGGER _ PATH '/data/log/pr
operty>
<Property name="LOG_HOME">${LOGGER_PATH}/${APP_NAME}</Property>
<!--文件大小-->
<Property name="FILE_SIZE">10M</Property>
<!--日志格式-->
<Property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</Property>
<!--日志文件命名格式-->
<Property name="rolling_file_name">-%d{yyyy-MM-dd}.%i.zip</Property>
<!--日志留存最大文件数-->
<Property name="rollover_strategy_max">30</Property>
<Property name="LOG_HOME_PROJECT">${LOG_HOME}/${APP_NAME}-project</Property>
<Property name="LOG_HOME_PROJECT_ERROR">${LOG_HOME}/${APP_NAME}-project-error</Property>
<Property name="LOG_HOME_SQL">${LOG_HOME}/${APP_NAME}-sql</Property>
</Properties>
<appenders>
<!--控制台打印 及格式-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${log_pattern}" />
</Console>
<!--定义rolling() 供下文使用-->
<RollingRandomAccessFile name="projectRolling"
fileName="${LOG_HOME_PROJECT}.log"
filePattern="${LOG_HOME_PROJECT}${rolling_file_name}"
immediateFlush="false" append="true">
<PatternLayout>
<Pattern>${log_pattern}</Pattern>
<Charset>UTF-8</Charset>
</PatternLayout>
<Policies>
<!--滚动规则 时间或者文件大小 滚动后将按照filePattern命名-->
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
<TimeBasedTriggeringPolicy interval="24"/>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${rollover_strategy_max}" />
</RollingRandomAccessFile>
<RollingRandomAccessFile name="projectErrorRolling"
fileName="${LOG_HOME_PROJECT_ERROR}.log"
filePattern="${LOG_HOME_PROJECT_ERROR}${rolling_file_name}"
immediateFlush="false" append="true">
<Filters>
<!-- 只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)可以使用多个ThresholdFilter 达到精准过滤某个级别的日志-->
<ThresholdFilter level="${LOGGER_LEVEL}" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
<PatternLayout>
<Pattern>${log_pattern}</Pattern>
<Charset>UTF-8</Charset>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${rollover_strategy_max}" />
</RollingRandomAccessFile>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="sqlRolling"
fileName="${LOG_HOME_SQL}.log"
filePattern="${LOG_HOME_SQL}${rolling_file_name}"
immediateFlush="false" append="true">
<PatternLayout>
<Pattern>${log_pattern}</Pattern>
<Charset>UTF-8</Charset>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="${FILE_SIZE}"/>
</Policies>
<DefaultRolloverStrategy max="${rollover_strategy_max}" />
</RollingRandomAccessFile>
</appenders>
<!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
<loggers>
<!--异步日志 区别于普通使用的logger root 搭配-->
<!--name 为包名 对应配置日志输出等级level -->
<!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
<!--将org.springframework包下的日志打印到Console控制台,projectRolling文件,projectErrorRolling(error级别单独一个文件)-->
<AsyncLogger name="org.springframework" level="${LOGGER_LEVEL}" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="projectRolling"/>
<appender-ref ref="projectErrorRolling"/>
</AsyncLogger>
<AsyncLogger name="com.alibaba.dubbo" level="${LOGGER_LEVEL}" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="projectRolling"/>
<appender-ref ref="projectErrorRolling"/>
</AsyncLogger>
<AsyncLogger name="druid.sql" level="${LOGGER_LEVEL}" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="sqlRolling"/>
</AsyncLogger>
<AsyncLogger name="org.mybatis" level="${LOGGER_LEVEL}" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="sqlRolling"/>
</AsyncLogger>
<AsyncLogger name="com.项目包名" level="${LOGGER_LEVEL}" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="projectRolling"/>
<appender-ref ref="projectErrorRolling"/>
</AsyncLogger>
<AsyncRoot level="${LOGGER_LEVEL}">
<appender-ref ref="Console"/>
<appender-ref ref="projectRolling" />
<appender-ref ref="projectErrorRolling" />
</AsyncRoot>
</loggers>
</configuration>
如上配置会产生3个日志文件
-
项目名称-project.log
-
项目名称-project-error.log
-
项目名称-sql.log
补充知识
onMatch和onMismatch都有三个属性值,分别为Accept、DENY和NEUTRAL
分别介绍这两个配置项的三个属性值:
-
onMatch=“ACCEPT”
表示匹配该级别及以上 -
onMatch=“DENY”
表示不匹配该级别及以上 -
onMatch=“NEUTRAL”
表示该级别及以上的,由下一个filter处理,如果当前是最后一个,则表示匹配该级别及以上 -
onMismatch=“ACCEPT”
表示匹配该级别以下 -
onMismatch=“NEUTRAL”
表示该级别及以下的,由下一个filter处理,如果当前是最后一个,则不匹配该级别以下的 -
onMismatch=“DENY”
表示不匹配该级别以下的
自定义日志格式
-
%d{HH:mm:ss.SSS}
表示输出到毫秒的时间 -
%logger{36}
简单理解为类名 -
%thread
输出当前线程名称 -
%-5level
输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0 -
%logger
输出logger名称,因为Root Logger没有名称,所以没有输出 -
%msg
日志文本 -
%n
换行 -
%X{xxx} xxx
为自定义参数
如何在日志中添加自己想传的参数?
定义拦截器(web服务拦controller,dubbo服务拦api),每次请求过来,拦住,然后将自定义参数传入。至于自定义参数怎么存,就是另一个问题了。
eg: traceId 跟踪号 对应log4j2.xml中的 %X{traceId}
下面是关键代码:
public class ContextFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String traceId = UUID.randomUUID().toString().replaceAll("-", ""); // org.slf4j.MDC MDC.put(CommonConsts.TRACE_ID_LOG, traceId);// 用来给日志文件使用 // org.apache.logging.log4j.ThreadContext ThreadContext.put(CommonConsts.TRACE_ID_LOG, traceId); //经测试,这两行都可行。 filterChain.doFilter(servletRequest, servletResponse); }
最后的日志打印效果如下:
2019-05-29 12:04:30.122 [http-nio-8080-exec-2] [2333333] INFO com.core.web.filter.ContextFilter - 接口调用时间:245毫秒
log4j 输入自定义参数
使用log4j、log4j2输入日志时,有时想追加打印自定义参数(比如客户端环境:手机型号、浏览器数据,request数据、用户数据等),以便于快速定位问题所在。
亦或在多线程环境中,快速定位哪些日志是由同一用户输出,便于其他工具进行日志分析。
log4j提供了ThreadContext 线程上下文类,用于存储自定义数据,以便在输入日志时,包含指定数据。
测试代码如下
package com.howtodoinjava.log4j2.examples; import java.util.UUID; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.ThreadContext; public class Log4j2HelloWorldExample { private static final Logger LOGGER = LogManager.getLogger(Log4j2HelloWorldExample.class.getName()); public static void main(String[] args) { //Add context information ThreadContext.put("id", UUID.randomUUID().toString()); ThreadContext.put("ipAddress", "192.168.21.9"); LOGGER.debug("Debug Message Logged !!"); LOGGER.info("Info Message Logged !!"); LOGGER.debug("Another Debug Message !!"); //Clear the map ThreadContext.clearMap(); LOGGER.debug("Thread Context Cleaned up !!"); LOGGER.debug("Log message with no context information !!"); } }
而后在 log4j.xml 中指定上述参数,
单独使用%X以包含地图的全部内容。
使用%X{key}包括指定的键。
使用%x包括堆栈的全部内容。
在实际应用时,一般是在过滤器、拦截器进行上述操作,方法之前,将数据绑定到线程中,方法完成后,清理线程数据。
看完上述内容,你们对log4j2的异步使用及添加自定义参数方式是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/155756.html