天天看點

基于行和時間的日志列印

有個需求,是要按照行和日期進行日志切割,後來根據官網介紹和百度查閱,找到了一種方法,稍加修改,記錄一下,

首先聲明用到的包如下,不同的包繼承的類會不同<properties>

    <slf4j.api.version>1.7.14</slf4j.api.version>

    <log4j.slf4j.impl.version>2.5</log4j.slf4j.impl.version>

    <log4j.core.version>2.5</log4j.core.version>

</properties>

<dependency>

    <groupId>org.slf4j</groupId>

    <artifactId>slf4j-api</artifactId>

    <version>${slf4j.api.version}</version>

</dependency>

<dependency>

    <groupId>org.apache.logging.log4j</groupId>

    <artifactId>log4j-slf4j-impl</artifactId>

    <version>${log4j.slf4j.impl.version}</version>

</dependency>

<dependency>

    <groupId>org.apache.logging.log4j</groupId>

    <artifactId>log4j-core</artifactId>

    <version>${log4j.core.version}</version>

</dependency>

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.logging.log4j.core.LogEvent;

import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;

import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;

import org.apache.logging.log4j.core.config.plugins.Plugin;

import org.apache.logging.log4j.core.config.plugins.PluginAttribute;

import org.apache.logging.log4j.core.config.plugins.PluginFactory;

import org.apache.logging.log4j.status.StatusLogger;

@Plugin(name = "LineBasedTriggeringPolicy", category = "Core", printObject = true)

public class LineBasedTriggeringPolicy implements TriggeringPolicy {

    protected static final StatusLogger LOGGER = StatusLogger.getLogger();

    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 int counter = 0;

    private long lastUpdateTime = System.currentTimeMillis();

    private AtomicInteger times = new AtomicInteger(1);

    private RollingFileManager manager;

    protected LineBasedTriggeringPolicy() {

        this.maxLineSize = MAX_LINE_SIZE;

        maxElapsedTime = MAX_ELAPSE_TIME;

    }

    protected LineBasedTriggeringPolicy(final long maxFileSize,

                                        int maxElapsedTime) {

        this.maxLineSize = maxFileSize;

        this.maxElapsedTime = maxElapsedTime;

    }

    @PluginFactory

    public static LineBasedTriggeringPolicy createPolicy(@PluginAttribute("size")

                                                         final String size, @PluginAttribute("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);

    }

    public void initialize(final RollingFileManager manager) {

        this.manager = manager;

    }

    public boolean isTriggeringEvent(final LogEvent event) {

        if (counter == 0 && times.intValue() == 1) {

            times.incrementAndGet();

            return true;

        }

        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 "LineBasedTriggeringPolicy(size=" + maxLineSize + ")";

    }

}

測試方法

public class TestLog {

    private static final Logger logger = LoggerFactory.getLogger("com.xxx.test.log");

    public static void main(String[] args) throws InterruptedException {

        while (true) {

            logger.info("TestLogController");

            Thread.sleep(1000);

        }

    }

}

log4j2.xml配置

<?xml version="1.0" encoding="utf-8"?>

<Configuration monitorInterval="30" packages="com.xxx.controller">

    <Appenders>

        <Console name="console" target="SYSTEM_OUT">

            <PatternLayout

                    pattern="%m%n"/>

        </Console>

        <RollingFile name="testLog" fileName="D:/testLog.log"

                     filePattern="D:/$${date:yyyy-MM}/$${date:yyyy-MM-dd}/testLog-%d{yyyy-MM-dd-HH-mm-ss}-%i.log.bak">

            <PatternLayout pattern="%m%n"/>

            <Policies>

                <LineBasedTriggeringPolicy size="10" maxElapsedTime="10"/>

            </Policies>

        </RollingFile>

    </Appenders>

    <Loggers>

        <Root level="info">

            <AppenderRef ref="console"/>

        </Root>

        <Logger name="com.xxx.test.log" level="info" additivity="false">

            <AppenderRef ref="testLog"/>

        </Logger>

    </Loggers>

</Configuration>

啟動後我們可以看到能正常輸出日志,且每次都是10條

基于行和時間的日志列印
基于行和時間的日志列印

然後暫停,将休眠時間改為2S

基于行和時間的日志列印
基于行和時間的日志列印

我們可以看到重新開機後第一次日志隻有7條就復原了,這就說明代碼加了第一次輸出日志就復原生效了

我們可以看到将休眠時間改為2S後就一直每次都是5條了

基于行和時間的日志列印