新需求要在log4j上做些自定义的东西,所以补了log4j2这一块的东西
配置
先看下log4j2的传统配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<properties>
<property name="log_path">C:/</property>
<property name="file_name">file.log</property>
<property name="root_level">error</property>
</properties>
<Appenders>
<!--console :控制台输出的配置-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<!--File :同步输出日志到本地文件 append:是否追加写-->
<File name="log" fileName="${logFilePath}/${logFileName}" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!--RollingFile:日志滚动策略-->
<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--ThresholdFilter :日志输出过滤-->
<!--level="info" :日志级别,onMatch="ACCEPT" :级别在info之上则接受,onMismatch="DENY" :级别在info之下则拒绝-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- Policies :日志滚动策略-->
<Policies>
<!-- TimeBasedTriggeringPolicy :时间滚动策略,默认0点小时产生新的文件,interval="6" : 自定义文件滚动时间间隔,每隔6小时产生新文件, modulate="true" : 产生文件是否以0点偏移时间,即6点,12点,18点,0点-->
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<!-- SizeBasedTriggeringPolicy :文件大小滚动策略-->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="${root_level}">
<AppenderRef ref="Console"/>
</Root>
<!--配置Mybatis Sql语句打印-->
<logger name="com.demo.mapper" level="debug" additivity="false">
<AppenderRef ref="Console"/>
</logger>
</Loggers>
</Configuration>
配置主要包括以下几个节点
- Configuration
- properties
- property
- Appenders
- Console
- File
- RollingFile
- Loggers
- Logger
- Root
- properties
Configuration标签
日志的根标签,主要属性介绍
属性名 | 描述 |
---|---|
monitorInterval | 定时扫描日志配置,动态改变日志配置。参数为秒,最低值为5 |
name | 日志配置名称 |
status | 设置日志内部打印级别 |
strict | 日志模式 |
schema | 指定文档约束 |
Properties
日志文件中需要用到的属性值,通过子标签<property>
设置
property
用于设置日志可能会用到的属性值,比如配置文件中的
<property name="log_path">C:/</property>
在配置其他属性时可以通过${log_path}
获取。
Appenders
包含多个<Appender>
子标签,用于指定日志的输出位置及格式级别等,比如<Console>
,将日志打印到控制台。
Console
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
属性名 | 描述 |
---|---|
name | 配置名称 |
target | “SYSTEM_OUT"或者"SYSTEM_ERR”,默认是"SYSTEM_OUT" |
子节点
- PatternLayout:日志输出样式设置
File
定义输出到指定位置的文件,
<File name="log" fileName="${logFilePath}/${logFileName}" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
属性名 | 描述 |
---|---|
name | 配置名称 |
fileName | 日志输出日志文件名称 |
append | 是否追加输出到文件 |
RollingFile
输出日志文件策略,可进行历史日志压缩存储等操作
属性名 | 描述 |
---|---|
name | 配置名称 |
fileName | 日志文件名称 |
filePattern | 指定新建日志文件的名称格式 |
子节点
- ThresholdFilter:过滤日志级别过滤器
- PatternLayout:日志输出样式
- Policies:指定滚动日志的策略,何时进行新建日志文件输出日志
- TimeBasedTriggeringPolicy:指定日志滚动时间间隔,interval 属性指定间隔时间,默认为 1 小时。modulate属性,是否以0点为标准时间
- SizeBasedTriggeringPolicy:指定日志文件大小的滚动策略,size 属性用来定义每个日志文件的大小
- DefaultRolloverStrategy:指定日志文件覆盖策略,默认为最多同一个文件夹下7个文件开始覆盖删除旧日志文件,max属性定义最大数
Loggers
包含一个默认的日志输出和多个其他可选的日志输出,通常包括Root
和Logger
节点
Root
Root 节点用来指定项目的根日志,如果没有单独指定 Logger,那么就会默认使用该 Root日志输出,必须存在的标签
<Root level="${root_level}">
<AppenderRef ref="Console"/>
</Root>
属性名 | 描述 |
---|---|
level | 日志输出级别,All<Trace<Debug<Info<Warn<Error<Fatal < OFF |
子节点
- AppenderRef:指定日志输出Appender
Logger
Loggers的子节点,用来单独指定日志的形式
<!--配置Mybatis Sql语句打印-->
<logger name="com.demo.mapper" level="debug" additivity="false">
<AppenderRef ref="Console"/>
</logger>
属性名 | 描述 |
---|---|
name | 必须,指定具体的要打印的日志,通常为包路径 |
level | 日志输出级别,可选,默认为ERROR级别 |
additivity | 是否继承其他日志输出,可能会在Root中打印日志,可选,默认为false |
子节点
- AppenderRef:指定日志输出Appender,如未指定则继承Root
自定义Appender
大多数情况下Log4j2提供的Appender能够满足业务需求,当然想要自定义日志的输出位置和方式可以通过自定义Appender方式实现。下面代码展示如何实现自定义Appender,通过继承AbstractAppender
类
@Plugin(name="DefineAppender",category = "Core",elementType = "appender",printObject = true)
public class DefineAppender extends AbstractAppender {
//自定义配置项
private String fileName;
protected DefineAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions,String fileName) {
super(name, filter, layout, ignoreExceptions);
//自定义配置项
this.fileName = fileName;
}
@Override
public void append(LogEvent logEvent) {
//这里实现自定义日志的业务逻辑
}
@PluginFactory
public static DefineAppender createAppender(@PluginAttribute("name") String name,
@PluginElement("Filter") final Filter filter,
@PluginElement("Layout") Layout<? extends Serializable> layout,
@PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
@PluginAttribute("filename") String fileName) {
if (name == null) {
LOGGER.error("No name defiend in conf");
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new DefineAppender(name, filter, layout, ignoreExceptions,fileName);
}
}
过滤器
日志过滤器,通过配置过滤器可以过滤自己希望输出的日志,符合条件的日志可以被当前过滤器通过,进入到后续的处理。log4j2提供了多种日志。
比如ThresholdFilter过滤器,过滤不同级别的日志
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
参数 | 描述 |
---|---|
level | 设置过滤日志级别 |
onMatch | 满足level,根据参数值确定是否打印日志 |
onMismatch | 不满足level,根据参数值是否过滤日志 |
onMatch与onMisMatch使用三个参数值,分别是ACCEPT
,DENY
,NEUTRY
。
- onMatch=“ACCEPT” 表示匹配该级别及以上
- onMatch=“DENY” 表示不匹配该级别及以上
- onMatch=“NEUTRAL” 表示该级别及以上的,由下一个filter处理,如果当前是最后一个,则表示匹配该级别及以上
- onMismatch=“ACCEPT” 表示匹配该级别以下
- onMismatch=“NEUTRAL” 表示该级别及以下的,由下一个filter处理,如果当前是最后一个,则不匹配该级别以下的
- onMismatch=“DENY” 表示不匹配该级别以下的
其他过滤器可以参考Log4j2过滤器;
自定义过滤器
自定义了一个日志概率输出过滤器。
当需要自定义过滤器时可以继承AbstractFilter
@Plugin(name = "LogRateFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
public class LogRateFilter extends AbstractFilter {
//自定义配置项
private final Double rate;
private LogRateFilter(final Double rate,final Result onMatch,final Result onMismatch){
super(onMatch,onMismatch);
// 自定义配置项
this.rate = rate;
}
@PluginFactory
public static LogRateFilter createFilter(
@PluginAttribute("rate") Double rate,
@PluginAttribute("onMatch") final Result match,
@PluginAttribute("onMismatch") final Result mismatch){
final Double actuaRate = rate == 0.0 ? 1.0:rate;
final Result onMatch = match == null ? Result.NEUTRAL : match;
final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
return new LogRateFilter(rate,onMatch,onMismatch);
}
public Result filter(Level level){
// 根据日志级别实现业务
Random random = new Random();
double seed = random.nextDouble();
System.out.println(seed);
return seed <= rate ? onMatch:onMismatch;
}
@Override
public Result filter(final LogEvent event) {
return filter(event.getLevel());
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
final Throwable t) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
final Throwable t) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
final Object... params) {
return filter(level);
}
}
使用
项目中自定义过滤器需要让Log4j加载到,在configuration 配置packages 目录,多个目录以,
分割
<configuration monitorInterval="5" packages="com.demo.log4j2.config">
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- rate:日志输出概率50% -->
<LogRateFilter rate="0.5" />
</console>
</configuration>
来源:CSDN
作者:fxtahe
链接:https://blog.csdn.net/m0_37635806/article/details/104022878