Log4j/Log4j2自定義Appender來實現日誌級別計數統計及監控

1、簡述java

  本文主要講如何基於Log4j2來實現自定義的Appender。通常用途是用於Log4j2自帶的Appender不足以知足咱們的需求,或者須要咱們對日誌進行攔截統計等操做時,須要咱們自定義Appender。apache

 

2、自定義Appenderapp

  方法:實現一個類,讓它繼承自Log4j2的AbstractAppender,而後你重寫其append方法,並添加一個@PluginFactory標記的createAppender方法。ide

  舉例:例如,咱們要實現一個經過日誌輸出的Level來統計計數來實現監控的一個Appender,並須要在配置日誌時,實現對一些附加屬性的配置,能夠以下實現。this

package com.test.utils.logs;

import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
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.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;

import java.io.Serializable;

@Plugin(name = "Statistics", category = "Core", elementType = "appender", printObject = true)
public class StatisticsAppender extends AbstractAppender {
    /** 日誌級別大於等於此級別及以上會進行判斷錯誤。默認:ERROR */
    private String failedOnLogLevel;
    /** 指定時間內,出現多少次該日誌級別,會被認爲是錯誤。默認:10 */
    private Integer failedOnLogLevelCount;
    /** 該日誌級別以上持續出現多長時間,會被認爲是錯誤。默認:30000 */
    private Integer failedOnLogLevelInMisSecond;
    /** 當連續小於該日誌級別多長時間後,恢復爲正常狀態。默認:120000 */
    private Integer recoveryOnLessLogLevelInMisSecond;

    protected StatisticsAppender(String name, Filter filter, Layout<? extends Serializable> layout,
                                 String failedOnLogLevel,
                                 Integer failedOnLogLevelCount,
                                 Integer failedOnLogLevelInMisSecond,
                                 Integer recoveryOnLessLogLevelInMisSecond) {
        super(name, filter, layout);
        this.failedOnLogLevel = failedOnLogLevel;
        this.failedOnLogLevelCount = failedOnLogLevelCount;
        this.failedOnLogLevelInMisSecond = failedOnLogLevelInMisSecond;
        this.recoveryOnLessLogLevelInMisSecond = recoveryOnLessLogLevelInMisSecond;
    }


    @Override
    public void append(LogEvent logEvent) {
        //此處省略告警過濾統計代碼。
        // .....
        String msg = logEvent.getMessage().getFormattedMessage();
        System.out.println(msg);
    }

    @PluginFactory public static StatisticsAppender createAppender(@PluginAttribute("name") String name,
                                                    @PluginElement("Filter") final Filter filter,
                                                    @PluginElement("Layout") Layout<? extends Serializable> layout,
                                                    @PluginAttribute("failedOnLogLevel") String failedOnLogLevel,
                                                    @PluginAttribute("failedOnLogLevelCount") Integer failedOnLogLevelCount,
                                                    @PluginAttribute("failedOnLogLevelInMisSecond") Integer failedOnLogLevelInMisSecond,
                                                    @PluginAttribute("recoveryOnLessLogLevelInMisSecond") Integer recoveryOnLessLogLevelInMisSecond) {
        if (name == null) {
            LOGGER.error("No name provided for MyCustomAppenderImpl");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        if (failedOnLogLevel == null) {
            failedOnLogLevel = "ERROR";
        }
        if (failedOnLogLevelCount == null) {
            failedOnLogLevelCount = 10;
        }
        if (failedOnLogLevelInMisSecond == null) {
            failedOnLogLevelInMisSecond = 30000;
        }
        if (recoveryOnLessLogLevelInMisSecond == null) {
            recoveryOnLessLogLevelInMisSecond = 120000;
        }
        return new StatisticsAppender(name, filter, layout, failedOnLogLevel, failedOnLogLevelCount, failedOnLogLevelInMisSecond, recoveryOnLessLogLevelInMisSecond);
    }

}

  說明:注意黃色區域的地方,另外createAppender方法中,紅色的參數表示XML中要配置的Appender屬性。spa

3、配置log4j2.xml文件日誌

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="ON" packages="org.apache.logging.log4j.core,io.sentry.log4j2,com.test.utils.logs">
    <appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <RollingFile name="RollingFile" fileName="datamerge-logs/app.log"
                     filePattern="datamerge-logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
            <SizeBasedTriggeringPolicy size="300 MB"/>
        </RollingFile>
        <Sentry name="Sentry"/>
        <Statistics name="StatisticsMonitor" failedOnLogLevel="ERROR" failedOnLogLevelCount="10" failedOnLogLevelInMisSecond="30000" recoveryOnLessLogLevelInMisSecond="120000"/>
    </appenders>
    <loggers>
        <root level="INFO">
            <appender-ref ref="Console"/>
            <!--<appender-ref ref="RollingFile"/>-->
            <!--<appender-ref ref="Sentry" level="ERROR" />-->
            <appender-ref ref="StatisticsMonitor"/>
        </root>
    </loggers>
</configuration>

  說明,請仔細閱讀黃色區域的內容。packages中要標註Appender所在的包名(不一樣的包名請使用","分隔)code

 

4、調用orm

  正常調用日誌便可。須要說明的是,Appender會在程序啓動後第一次調用日誌時,實例化一次Appender,以後就不會再實例化了。以後會屢次調用append方法。xml

相關文章
相關標籤/搜索