一、简述

  本文主要讲如何基于Log4j2来实现自定义的Appender。一般用途是用于Log4j2自带的Appender不足以满足我们的需求,或者需要我们对日志进行拦截统计等操作时,需要我们自定义Appender。

二、自定义Appender

  方法:实现一个类,让它继承自Log4j2的AbstractAppender,然后你重写其append方法,并添加一个@PluginFactory标记的createAppender方法。

  举例:例如,我们要实现一个通过日志输出的Level来统计计数来实现监控的一个Appender,并需要在配置日志时,实现对一些附加属性的配置,可以如下实现。

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属性。

三、配置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所在的包名(不同的包名请使用","分隔)

四、调用

  正常调用日志即可。需要说明的是,Appender会在程序启动后第一次调用日志时,实例化一次Appender,之后就不会再实例化了。之后会多次调用append方法。

Log4j/Log4j2自定义Appender来实现日志级别计数统计及监控的更多相关文章

  1. log4j2自定义Appender(输出到文件/RPC服务中)

    1.背景 虽然log4j很强大,可以将日志输出到文件.DB.ES等.但是有时候确难免完全适合自己,此时我们就需要自定义Appender,使日志输出到指定的位置上. 本文,将通过两个例子说明自定义APP ...

  2. log4j2和logback动态修改日志级别工具类

    工作中,在排查线上问题时,有以下场景在不重新部署或重启服务的情况下,需要动态调整线上日志级别 1.线上有些日志打印过多干扰有用的日志,需要动态修改线上日志记录器的打印日志级别,调高一些日志级别,打印出 ...

  3. SpringBoot | 第二十五章:日志管理之自定义Appender

    前言 前面两章节我们介绍了一些日志框架的常见配置及使用实践.一般上,在开发过程中,像log4j2.logback日志框架都提供了很多Appender,基本上可以满足大部分的业务需求了.但在一些特殊需求 ...

  4. springboot中动态修改log4j2日志级别

    springboot中动态修改log4j2日志级别 在spring boot中使用log4j2日志时,项目运行中,想要修改日志级别. 1.pom.xml依赖: <dependency> & ...

  5. 自定义log4j日志级别

    转载自:  http://blog.csdn.net/seven_cm/article/details/26849821 自定义log4j日志级别 参考了网上资料:http://www.360doc. ...

  6. log4j.xml配置,包含自定义log4j日志级别及输出日志到不同文件

      一.配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configura ...

  7. 详解log4j2(下) - Async/MongoDB/Flume Appender 按日志级别区分文件输出

    1. 按日志级别区分文件输出 有些人习惯按日志信息级别输出到不同名称的文件中,如info.log,error.log,warn.log等,在log4j2中可通过配置Filters来实现. 假定需求是把 ...

  8. Log4j,Log4j2,logback,slf4j日志学习

    日志学习笔记 Log4j Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.数据库等:我们也可以控制每一条日志的输出格式:通过定义每一条 ...

  9. log4j2动态修改日志级别及拓展性使用

    一.供参考的完整日志配置 <?xml version="1.0" encoding="UTF-8"?> <!-- 配置LoggerConfig ...

随机推荐

  1. 分解数据表(将一个datatable按数据量分隔成多个table)

    /// <summary> /// 分解数据表 /// </summary> /// <param name="originalTab">需要分 ...

  2. Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第三集之磁盘分区】

    磁盘分区的概念对接下来的自定义安装Linux具有重要作用.(可以直接先看第四集之Linux安装就能知道分区的重要性) ----------------------------------------- ...

  3. 爬虫2 urllib3 爬取30张百度图片

    import urllib3 import re # 下载百度首页页面的所有图片 # 1. 找到目标数据 # page_url = 'http://image.baidu.com/search/ind ...

  4. SVM:利用SVM算法实现手写图片识别(数据集50000张图片)—Jason niu

    import mnist_loader # Third-party libraries from sklearn import svm def svm_baseline(): training_dat ...

  5. Certbot让网站拥有免费https证书

    网站使用http协议,在chrome浏览器中总是报不安全,看着就让人不爽,自己建的网站,不安全总是会让自己心慌慌.看到有头有脸的网站都是https开头,心中自然也想装逼一把,让自己的网站高端大气上档次 ...

  6. SpringBoot整合dubbo

    Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成. 以上介绍来源于百度百科,具体dubbo相关可以自行查 ...

  7. .NET控件名称缩写一览表 zz

    标准控件1 btn Button2 chk CheckBox3 ckl CheckedListBox4 cmb ComboBox5 dtp DateTimePicker6 lbl Label7 llb ...

  8. 前端之html、css

    一.什么是前端 前端即网站前台部分,运行在PC端.移动端等浏览器上展现给用户浏览的网页.前端技术一般分为前端设计和前端开发,前端设计一般可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括基 ...

  9. 英语口语练习系列-C25-冒险-课堂用语-葬我

    词汇-冒险 adventure noun [ C or U ] UK /ədˈven.tʃər/ US /ədˈven.tʃɚ/ an unusual, exciting, and possibly ...

  10. python基础一 ------利用生成器生成一个可迭代对象

    #利用生成器生成一个可迭代对象#需求:生成可迭代对象,输出指定范围内的素数,利用生成器产生一个可迭代对象#生成器:本身是可迭代的,只是 yield 好比return返回,yield返回后函数冻结状态, ...