首页 > 解决方案 > 如何使用自定义日志处理程序为 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 中的自定义处理程序来过滤异常日志。您可以探索实现结果的其他方法。

标签: loggingjbosswildflybackupcustomization

解决方案


推荐阅读