logging - 如何使用自定义日志处理程序为 Wildfly jboss 设置所有时间的最大备份日志
问题描述
我在 jboss 的 PeriodicSizeRotatingFileHandler 中遇到了限制。它每天轮换日志备份,并为一天创建 20 个备份索引。第二天它会创建新的 20 个备份,并且不会删除旧的备份。第二天再次进行相同的 20 次备份。这会消耗大量内存,我们不会删除旧文件。
我使用自定义处理程序并创建一个扩展 PeriodicSizeRotatingFileHandler 的新类。其中有新字段 maxBackupAllTime。您可以为其设置一个值,它可以删除比该索引更旧的文件。
这是一个如何创建自定义处理程序来执行此操作的示例。所有自定义处理程序都必须扩展 java.util.logging.Handler。对于这个例子,我正在扩展 org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler,因为它可以帮助我利用 PeriodicSizeRotatingFileHandler 提供的一些功能。
public class PeriodicSizeRotatingCustomFileHandler extends PeriodicSizeRotatingFileHandler {
private int maxBackupAllTime = 5;
public int getMaxBackupAllTime() {
return maxBackupAllTime;
}
public void setMaxBackupAllTime(int maxBackupAllTime) {
checkAccess(this);
synchronized (outputLock) {
this.maxBackupAllTime = maxBackupAllTime;
}
}
public PeriodicSizeRotatingCustomFileHandler() {
super();
}
public PeriodicSizeRotatingCustomFileHandler(final String fileName, final boolean append)
throws FileNotFoundException {
super(fileName, append);
}
/**
* @param maxBackupAllTime
*/
public PeriodicSizeRotatingCustomFileHandler(final String maxBackupAllTime) {
super();
this.maxBackupAllTime = Integer.parseInt(maxBackupAllTime);
}
/**
* @param fileName
* @param suffix
* @param rotateSize
* @param maxBackupIndex
* @param append
* @param maxBackupAllTime
* @throws FileNotFoundException
*/
public PeriodicSizeRotatingCustomFileHandler(final String fileName, final String suffix, final String rotateSize,
final String maxBackupIndex, final String append, final String maxBackupAllTime)
throws FileNotFoundException {
super(fileName == null ? null : new File(fileName), suffix, Boolean.parseBoolean(append));
this.setFile(fileName == null ? null : new File(fileName));
this.setRotateSize(Long.parseLong(rotateSize));
this.setMaxBackupIndex(Integer.parseInt(maxBackupIndex));
setMaxBackupAllTime(Integer.parseInt(maxBackupAllTime));
}
/*
* (non-Javadoc)
*
* @see org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler#preWrite(org.jboss.logmanager.ExtLogRecord)
* After Super class preWrite() execution, we check total logs file count, should not be more than @maxBackupAllTime
*/
@Override
public void preWrite(final ExtLogRecord record) {
super.preWrite(record);
if (maxBackupAllTime != 0) {
File logfile = getFile();
File path = new File(logfile.getParent());
List<File> logFilesInDirectory = Arrays.asList(path.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
boolean result;
if (name.startsWith("server.log")) {
result = true;
} else {
result = false;
}
return result;
}
}));
if (logFilesInDirectory.size() > this.maxBackupAllTime) {
logFilesInDirectory.sort(Comparator.comparing(File::lastModified));
int filesCountToRemove = logFilesInDirectory.size() - this.maxBackupAllTime - 1;
List<File> filesToRemove = new ArrayList<>();
for (int i = 0; i < filesCountToRemove; i++) {
filesToRemove.add(logFilesInDirectory.get(i));
}
try {
deleteSelectedFiles(filesToRemove);
} catch (IOException e) {
reportError("Unable to delete log file", e, ErrorManager.OPEN_FAILURE);
}
}
}
}
/**
* Deletes the specified files.
*
* @param path
* the file to delete
* @throws IOException
* if a problem occurred deleting the file
*/
private void deleteSelectedFiles(final List<File> selectedForDeletion) throws IOException {
for (final File file : selectedForDeletion) {
Files.deleteIfExists(file.toPath());
}
}
在此自定义处理程序中,我们将覆盖 preWrite() 方法以检查文件计数是否超过 maxBackupAllTIme 中给定的数量并删除额外的备份文件。
创建自定义处理程序后,我们必须将类打包到 JAR 文件中(例如 custom-logger.jar)并创建 JBoss 模块。Module.xml 如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<module name="org.jboss.logmanager.custom.handlers" xmlns="urn:jboss:module:1.6">
<resources>
<resource-root path="custom-logger.jar"/>
</resources>
<dependencies>
<!-- for java.beans -->
<module name="java.desktop"/>
<module name="java.logging"/>
<module name="java.xml"/>
<module name="javax.json.api"/>
<module name="org.jboss.modules" export="true"/>
<module name="org.jboss.logmanager" export="true"/>
<module name="org.wildfly.common" export="true"/>
</dependencies>
</module>
您可以使用 JBoss CLI 创建模块,也可以通过 JAR 和 module.xml 在正确的位置手动创建它。或者您可以手动创建目录 org/jboss/logmanager/custom/handlers/main 并在其中复制 jar 文件和 module.xml。
成功创建模块后,我们将不得不在您的配置的日志子系统下配置自定义处理程序,如 domain.xml 中。配置 XML 如下所示:
<custom-handler name="FILEA"
class="org.jboss.logmanager.custom.handlers.PeriodicSizeRotatingCustomFileHandler"
module="org.jboss.logmanager.custom.handlers">
<level name="DEBUG"/>
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<properties>
<property name="fileName" value="${jboss.server.log.dir}/server.log"/>
<property name="suffix" value=".yyyy-MM-dd"/>
<property name="rotateSize" value="1000000"/>
<property name="maxBackupIndex" value="5"/>
<property name="append" value="false"/>
<property name="maxBackupAllTime" value="8"/>
</properties>
</custom-handler>
<root-logger>
<level name="DEBUG"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILEA"/>
</handlers>
</root-logger>
这只是一个示例,说明如何使用 JBoss logmanager 中的自定义处理程序来过滤异常日志。您可以探索实现结果的其他方法。
解决方案
推荐阅读
- javascript - 尽管来自源的数据已更新 JavaScript php,但 Typeahead 下拉列表是相同的
- azure-container-instances - 使用多个容器更新 Azure 容器实例中的单个容器
- r - 测试 R 中的 shapefile 中是否存在纬度/经度对
- javascript - Vue:将选择值从组件返回到父组件
- excel - Excel:使用参考范围内的生效日期根据单个查询日期查询适用记录范围的方法
- pandas - Matplotlib 的 axhline 函数与日期时间对象
- mysql - 使用python 3.6的mysql查询(字符串变量在单引号中)
- python - Grakn 1.7.1 的数据加载问题
- python - 如何修复 [CRITICAL] App.root 必须是 Widget 的_instance_
- xcode - SwiftUI @State 未在旧项目中更新