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 ...
随机推荐
- Spring-1-(简介及HelloWord)
一:Spring简介 Spring 框架宗旨:不重新发明技术,让原有技术使用起来更加方便. Spring核心功能: 1.AOP:面向切面编程 2.Ioc/Di:控制反转/依赖注入 3.声明式事务 Sp ...
- Manager解决Process进程之间的数据访问
import multiprocessing mgr = mutiprocessing.Manager() 开启一个守护子进程,并返回用来与其通信的管理器 share_list = mgr.list( ...
- hdu5745(dp+bitset)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5745 C++ bitset的用法:https://www.cnblogs.com/magisk/p/880 ...
- Harmonic Number(调和级数+欧拉常数)
In mathematics, the nth harmonic number is the sum of the reciprocals of the first n natural numbers ...
- CentOS系统找不到setup命令工具的解决方法
如果你的CentOS系统中没有setup命令,很有可能是因为你安装CentOS系统时采用了最小化安装(minimal).这时,你执行setup命令时,就会报错: 错误信息: 1[root@localh ...
- HDU 1385 Minimum Transport Cost (输出字典序最小路径)【最短路】
<题目链接> 题目大意:给你一张图,有n个点,每个点都有需要缴的税,两个直接相连点之间的道路也有需要花费的费用.现在进行多次询问,给定起点和终点,输出给定起点和终点之间最少花费是多少,并且 ...
- Linux学习之日志管理(二十一)
Linux学习之日志管理 目录 日志管理 日志服务 rsyslogd的新特点 启动日志服务 常见日志的作用 日志文件的一般格式 rsyslogd日志服务 /etc/rsyslog.conf配置文件 服 ...
- vue-cli@3.x初体验之前篇-回顾vue-cli@2.x创建项目的流程
模拟实际工作中的操作,假如新开启了一个vue项目,可以先看看上篇博文中的git操作,新建空仓库vue-demo,并拉取到本地,创建本地dev分支后 1. 全局安装vue-cli yarn global ...
- 排列组合 HDU - 1521 -指数型母函数
排列组合 HDU - 1521 一句话区分指数型母函数和母函数就是 母函数是组合数,指数型母函数是排列数 #include<bits/stdc++.h> using namespace s ...
- JS 实现打印
<input id="btnPrint" type="button" value="打印预览" onclick=preview(1) ...