目标:实现基于行和时间间隔的文件滚动。
注:不是纯粹的行,而是log的次数,如果log一次是一行,就是行数(我log一次就是一行)。
例如:单个文件超过10行滚动文件,如果超过10秒还不到10行,也滚动文件。
mysql默认的组合策略达不到这个目标,他是两种策略的“或”,单一的行数到达限制,或者单一的时间间隔到达限制,都会滚动。在滚动后,两个策略单独重置,而不是一起都重置。
实现方法:
通过实现一个TriggeringPlolicy即可达到这个目标。这个接口的isTriggeringEvent方法来控制滚动,如果该方法返回true,那么就滚动。
这里实现了一个LineBasedTriggeringPolicy ,需要实现TriggeringPlolicy,和一个工厂方法。该类和工厂方法都需要用Annotation标注。
上层对isTriggeringEvent的调用时同步的,我们这里不需额外的同步。
配置关键点解释:
1.configuration的packages:由于是基于Annotation开发,所以log4j需要扫描包,找到它的组件,如果没有这个属性,会找不到我们定义的Policy。
2. filePattern的日期格式:如果日志录入较快,文件滚动比较频繁,文件名重复的几率很大,这时是通过添加序号(pattern中的i)来解决的,RollingStrategy的max属性指示序号最大有几个,如果超过了最大个数,会再从头滚动,这样,我们前面的日志被覆盖,造成日志丢失。如果采用毫秒级的文件名,重复几率大大降低。(另外如果max的只很大,滚动会变得很慢,比如10万,我没有深究为什么。)
3. LineBasedTriggeringPolicy 就是我们的滚动策略。这里配置的是最多10行,最多10秒,就滚动。
4.类、工厂方法、工厂方法上的参数,都要有相应的Annotation。
5.configuration的statu属性:配置成debug可以查看log4j的装配过程,设置成OFF,即可关闭状态日志。
配置文件:
自定义TriggeringPolicy:
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration name="ConfigTest" status="debug"
packages="org.apache.logging.log4j,">
<appenders>
<FastRollingFile name="FastFile" fileName="asyncWithLocation"
immediateFlush="false" append="true"
filePattern="%d{yyyyMMdd-mmssSSS}-%i.log">
<PatternLayout>
<pattern>%m%n</pattern>
</PatternLayout>
<LineBasedTriggeringPolicy size="10" maxElapsedTime="10" />
<DefaultRolloverStrategy max="10" min="0" />
</FastRollingFile>
</appenders>
<loggers>
<asyncRoot level="fatal" includeLocation="true">
<appender-ref ref="FastFile" />
</asyncRoot>
</loggers>
</configuration>自定义TriggeringPolicy:
package org.apache.logging.log4j.core.appender.rolling;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttr;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.status.StatusLogger;
/**
* zhmt
*/
@Plugin(name = "LineBasedTriggeringPolicy", type = "Core", printObject = true)
public class LineBasedTriggeringPolicy implements TriggeringPolicy {
/**
* Allow subclasses access to the status logger without creating another
* instance.
*/
protected static final Logger LOGGER = StatusLogger.getLogger();
private int counter = 0;
private long lastUpdateTime = System.currentTimeMillis();
/**
* Rollover threshold size in bytes.
*/
private static final long MAX_LINE_SIZE = 10 * 1024 * 2; // let 20k line
private static final int MAX_ELAPSE_TIME = 24 * 60 * 60 * 1000; // 1day
private final long maxLineSize;
private final int maxElapsedTime; // in ms
private RollingFileManager manager;
/**
* Constructs a new instance.
*/
protected LineBasedTriggeringPolicy() {
this.maxLineSize = MAX_LINE_SIZE;
maxElapsedTime = MAX_ELAPSE_TIME;
}
/**
* Constructs a new instance.
*
* @param maxFileSize
* rollover threshold size in bytes.
*/
protected LineBasedTriggeringPolicy(final long maxFileSize,
int maxElapsedTime) {
this.maxLineSize = maxFileSize;
this.maxElapsedTime = maxElapsedTime;
}
/**
* Initialize the TriggeringPolicy.
*
* @param manager
* The RollingFileManager.
*/
public void initialize(final RollingFileManager manager) {
this.manager = manager;
}
/**
* Returns true if a rollover should occur.
*
* @param event
* A reference to the currently event.
* @return true if a rollover should take place, false otherwise.
*/
public boolean isTriggeringEvent(final LogEvent event) {
counter++;
int cur = counter;
boolean ret = cur >= maxLineSize;
if (!ret) {
long time = System.currentTimeMillis() - lastUpdateTime;
if (time > maxElapsedTime) {
ret = true;
}
}
if (ret) {
counter = 0;
lastUpdateTime = System.currentTimeMillis();
}
return ret;
}
@Override
public String toString() {
return "SizeBasedTriggeringPolicy(size=" + maxLineSize + ")";
}
/**
* Create a SizeBasedTriggeringPolicy.
*
* @param size
* The size of the file before rollover is required.
* @return A SizeBasedTriggeringPolicy.
*/
@PluginFactory
public static LineBasedTriggeringPolicy createPolicy(@PluginAttr("size")
final String size, @PluginAttr("maxElapsedTime")
final String maxElapsedTime) {
final long maxSize = size == null ? MAX_LINE_SIZE : Integer
.valueOf(size);
int time = maxElapsedTime == null ? MAX_ELAPSE_TIME / 1000 : Integer
.valueOf(maxElapsedTime);
return new LineBasedTriggeringPolicy(maxSize, time * 1000);
}
}
本文介绍了如何实现一个自定义的log4j2触发策略,该策略基于日志行数和时间间隔进行文件滚动。不同于默认的组合策略,这个策略在日志达到特定行数或超过特定时间间隔时同时滚动,而不是单独满足任一条件。通过创建一个实现了TriggeringPolicy接口的LineBasedTriggeringPolicy类,并在配置文件中指定,实现了10行或10秒内未满10行即滚动文件的目标。此外,文章还详细讲解了配置的关键点,如配置包扫描、文件名格式、策略配置等。
2301

被折叠的 条评论
为什么被折叠?



