Log4j/Log4j2自定义Appender来实现日志级别计数统计及监控
一、简述
本文主要讲如何基于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来实现日志级别计数统计及监控的更多相关文章
- log4j2自定义Appender(输出到文件/RPC服务中)
1.背景 虽然log4j很强大,可以将日志输出到文件.DB.ES等.但是有时候确难免完全适合自己,此时我们就需要自定义Appender,使日志输出到指定的位置上. 本文,将通过两个例子说明自定义APP ...
- log4j2和logback动态修改日志级别工具类
工作中,在排查线上问题时,有以下场景在不重新部署或重启服务的情况下,需要动态调整线上日志级别 1.线上有些日志打印过多干扰有用的日志,需要动态修改线上日志记录器的打印日志级别,调高一些日志级别,打印出 ...
- SpringBoot | 第二十五章:日志管理之自定义Appender
前言 前面两章节我们介绍了一些日志框架的常见配置及使用实践.一般上,在开发过程中,像log4j2.logback日志框架都提供了很多Appender,基本上可以满足大部分的业务需求了.但在一些特殊需求 ...
- springboot中动态修改log4j2日志级别
springboot中动态修改log4j2日志级别 在spring boot中使用log4j2日志时,项目运行中,想要修改日志级别. 1.pom.xml依赖: <dependency> & ...
- 自定义log4j日志级别
转载自: http://blog.csdn.net/seven_cm/article/details/26849821 自定义log4j日志级别 参考了网上资料:http://www.360doc. ...
- log4j.xml配置,包含自定义log4j日志级别及输出日志到不同文件
一.配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configura ...
- 详解log4j2(下) - Async/MongoDB/Flume Appender 按日志级别区分文件输出
1. 按日志级别区分文件输出 有些人习惯按日志信息级别输出到不同名称的文件中,如info.log,error.log,warn.log等,在log4j2中可通过配置Filters来实现. 假定需求是把 ...
- Log4j,Log4j2,logback,slf4j日志学习
日志学习笔记 Log4j Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.数据库等:我们也可以控制每一条日志的输出格式:通过定义每一条 ...
- log4j2动态修改日志级别及拓展性使用
一.供参考的完整日志配置 <?xml version="1.0" encoding="UTF-8"?> <!-- 配置LoggerConfig ...
随机推荐
- ELK安装(windows)
一.安装JAVA环境 在Oracle官网获取最新版的Java版本,官网:http://www.oracle.com/ 安装完成后,配置JAVA_HOME和JRE_HOME. 二.下载安装ELK htt ...
- 非root用户下实现SSH免密码登录
1.创建公钥.公钥 ssh-keygen -t rsa 无视它出来的任何提示,欢快的一路回车到底吧. 2.把公钥 id_rsa.pub 复制到远程机器的 /home/username/.ssh目录 并 ...
- 线段树-hdu3397
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题目描述: 题目大意:给我们一串二进制串,需要我们对其进行以下操作: 1.输入0,a,b,将a, ...
- TF之AE:AE实现TF自带数据集AE的encoder之后decoder之前的非监督学习分类—Jason niu
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt #Import MNIST data from t ...
- hdu 3499 flight 【分层图】+【Dijkstra】
<题目链接> 题目大意: 现在给你一些点,这些点之间存在一些有向边,每条边都有对应的边权,有一次机会能够使某条边的边权变为原来的1/2,求从起点到终点的最短距离. 解题分析: 分层图最短路 ...
- 同一台电脑上个人的github账户如何与公司的gitlab账户共存
前些天,写了篇博客 开发环境之git:团队协作git工作流与常用命令. 主要是回顾其中的第一小节基本配置. 但是对于很多程序员而言,我们不仅有公司的gitlab账户做公司的业务,也会有自己个人的git ...
- linux 学习笔记 防火墙设置
1> 重新设置启动防火墙命令 #service iptables restart 2>添加防火墙规则命令 2.1 #service iptables stop 停止防火墙 2.2 #vi ...
- SpringBoot统一处理异常
在springboot项目,报错有着默认的提示,这篇文章介绍一下如何统一处理异常. 新建项目,pom文件如下: <?xml version="1.0" encoding=&q ...
- Yolov3实战 基于darknet window版
特此声明:训练过程预先认为你对yolov3神经网络有一定了解的基础上进行. 目录 一.先备齐下面的工具(预先善其事,必先利其器) 二.接下里使用我们的工具编译我们的环境 三. 训练自己的数据集 1. ...
- codeforces651----A. Joysticks
//贪心,注意特判即可 #include <iostream> using namespace std; int main() { ; cin >> a >> b; ...