slf4j 日志监控
问题描述
监控系统
新系统起步,旨在监控原有系统的各种问题。主要的一部分,就是监视原有系统的日志。
日志,是Java
企业级应用开发必不可少的一部分,市场上有诸多日志框架。我们选用slf4j
。
日志有以下级别:
TRACE, DEBUG, INFO, WARN, ERROR
我们期待,当系统运行时打印了WARN
或ERROR
级别的日志时,向我们的服务器推送消息。使得我们可以分析日志,构造更完整的系统。
实现
思考
日志问题与之前的Hibernate
映射问题不同。
Hibernate
映射问题是默认用这个类,然后我们可以利用Spring Boot
为我们提供的配置,当去映射名称的时候调用我这个类。
我们的日志是这么写的:
private static final Logger logger = LoggerFactory.getLogger(xxxx.class);
对象都是从LoggerFactory
那创建出来的,我们根本没办法从配置中下手。
自定义日志
新建日志类YunzhiLogger
,去实现org.slf4j.Logger
接口。
这是Logger
接口的源码,一共有61
个方法,我们一一去实现是不现实的,根据面向对象大法,我们应该去找一个合适的父类去继承,然后重写不符合我们要求的方法。
package org.slf4j;public interface Logger {final public String ROOT_LOGGER_NAME = "ROOT";public String getName();public boolean isTraceEnabled();public void trace(String msg);public void trace(String format, Object arg);public void trace(String format, Object arg1, Object arg2);public void trace(String format, Object... arguments);public void trace(String msg, Throwable t);public boolean isTraceEnabled(Marker marker);public void trace(Marker marker, String msg);public void trace(Marker marker, String format, Object arg);public void trace(Marker marker, String format, Object arg1, Object arg2);public void trace(Marker marker, String format, Object... argArray);public void trace(Marker marker, String msg, Throwable t);public boolean isDebugEnabled();public void debug(String msg);public void debug(String format, Object arg);public void debug(String format, Object arg1, Object arg2);public void debug(String format, Object... arguments);public void debug(String msg, Throwable t);public boolean isDebugEnabled(Marker marker);public void debug(Marker marker, String msg);public void debug(Marker marker, String format, Object arg);public void debug(Marker marker, String format, Object arg1, Object arg2);public void debug(Marker marker, String format, Object... arguments);public void debug(Marker marker, String msg, Throwable t);public boolean isInfoEnabled();public void info(String msg);public void info(String format, Object arg);public void info(String format, Object arg1, Object arg2);public void info(String format, Object... arguments);public void info(String msg, Throwable t);public boolean isInfoEnabled(Marker marker);public void info(Marker marker, String msg);public void info(Marker marker, String format, Object arg);public void info(Marker marker, String format, Object arg1, Object arg2);public void info(Marker marker, String format, Object... arguments);public void info(Marker marker, String msg, Throwable t);public boolean isWarnEnabled();public void warn(String msg);public void warn(String format, Object arg);public void warn(String format, Object... arguments);public void warn(String format, Object arg1, Object arg2);public void warn(String msg, Throwable t);public boolean isWarnEnabled(Marker marker);public void warn(Marker marker, String msg);public void warn(Marker marker, String format, Object arg);public void warn(Marker marker, String format, Object arg1, Object arg2);public void warn(Marker marker, String format, Object... arguments);public void warn(Marker marker, String msg, Throwable t);public boolean isErrorEnabled();public void error(String msg);public void error(String format, Object arg);public void error(String format, Object arg1, Object arg2);public void error(String format, Object... arguments);public void error(String msg, Throwable t);public boolean isErrorEnabled(Marker marker);public void error(Marker marker, String msg);public void error(Marker marker, String format, Object arg);public void error(Marker marker, String format, Object arg1, Object arg2);public void error(Marker marker, String format, Object... arguments);public void error(Marker marker, String msg, Throwable t);
}
找父类
粗略地阅读了一下LoggerFactory
中getLogger
的源代码。
里面有很多的条件,先根据条件获取ILoggerFactory
,该接口一共有三个实现类,实现类中再去定义不同的getLogger
方法,不同的工厂获取出来的日志对象是不同的。
因为对日志框架不是很了解,如果我们随便找一个类继承,那slf4j
的判断就失去意义了,所以此种方法行不通。
装饰器模式
我们想到了装饰器模式。
将一个对象进行装饰,完善其方法。
先将Logger
中的方法都实现掉,然后定义私有变量logger
,定义有参构造函数。
定义logger
用YunzhiLogger
对该日志对象进行装饰。
private static final Logger logger = new YunzhiLogger(LoggerFactory.getLogger(xxxx.class));
借此,也理解了装饰器模式的应用场景。原来就想,装饰器实现的功能用继承不就能实现吗?为什么还要去装饰对象呢?直接继承父类然后调用super
上的方法再加新功能不和这一样吗?
现在也明白了,有时候,我们找不到合适的父类(因为创造出的日志对象是根据不同条件new
不同的类创造出来的),然后我们又想去给这个对象添加方法,没办法,只能修饰对象了。
或者有时候,找到父类,但是父类是final
,没法继承,才用的装饰器模式。
装饰方法
首先,调用原logger
方法进行默认实现。
package com.mengyunzhi.measurement.log;import org.slf4j.Logger;
import org.slf4j.Marker;/*** @author zhangxishuo on 2018/11/15*/
public class YunzhiLogger implements Logger {private Logger logger;public YunzhiLogger(Logger logger) {this.logger = logger;}@Overridepublic String getName() {return this.logger.getName();}@Overridepublic boolean isTraceEnabled() {return this.logger.isTraceEnabled();}@Overridepublic void trace(String msg) {this.logger.trace(msg);}@Overridepublic void trace(String format, Object arg) {this.logger.trace(format, arg);}@Overridepublic void trace(String format, Object arg1, Object arg2) {this.logger.trace(format, arg1, arg2);}@Overridepublic void trace(String format, Object... arguments) {this.logger.trace(format, arguments);}@Overridepublic void trace(String msg, Throwable t) {this.logger.trace(msg, t);}@Overridepublic boolean isTraceEnabled(Marker marker) {return this.logger.isTraceEnabled(marker);}@Overridepublic void trace(Marker marker, String msg) {this.logger.trace(marker, msg);}@Overridepublic void trace(Marker marker, String format, Object arg) {this.logger.trace(marker, format, arg);}@Overridepublic void trace(Marker marker, String format, Object arg1, Object arg2) {this.logger.trace(marker, format, arg1, arg2);}@Overridepublic void trace(Marker marker, String format, Object... argArray) {this.logger.trace(marker, format, argArray);}@Overridepublic void trace(Marker marker, String msg, Throwable t) {this.logger.trace(marker, msg, t);}@Overridepublic boolean isDebugEnabled() {return this.logger.isDebugEnabled();}@Overridepublic void debug(String msg) {this.logger.debug(msg);}@Overridepublic void debug(String format, Object arg) {this.logger.debug(format, arg);}@Overridepublic void debug(String format, Object arg1, Object arg2) {this.logger.debug(format, arg1, arg2);}@Overridepublic void debug(String format, Object... arguments) {this.logger.debug(format, arguments);}@Overridepublic void debug(String msg, Throwable t) {this.logger.debug(msg, t);}@Overridepublic boolean isDebugEnabled(Marker marker) {return this.logger.isDebugEnabled(marker);}@Overridepublic void debug(Marker marker, String msg) {this.logger.debug(marker, msg);}@Overridepublic void debug(Marker marker, String format, Object arg) {this.logger.debug(marker, format, arg);}@Overridepublic void debug(Marker marker, String format, Object arg1, Object arg2) {this.logger.debug(marker, format, arg1, arg2);}@Overridepublic void debug(Marker marker, String format, Object... arguments) {this.logger.debug(marker, format, arguments);}@Overridepublic void debug(Marker marker, String msg, Throwable t) {this.logger.debug(marker, msg, t);}@Overridepublic boolean isInfoEnabled() {return this.logger.isInfoEnabled();}@Overridepublic void info(String msg) {this.logger.info(msg);}@Overridepublic void info(String format, Object arg) {this.logger.info(format, arg);}@Overridepublic void info(String format, Object arg1, Object arg2) {this.logger.info(format, arg1, arg2);}@Overridepublic void info(String format, Object... arguments) {this.logger.info(format, arguments);}@Overridepublic void info(String msg, Throwable t) {this.logger.info(msg, t);}@Overridepublic boolean isInfoEnabled(Marker marker) {return this.logger.isInfoEnabled(marker);}@Overridepublic void info(Marker marker, String msg) {this.logger.info(marker, msg);}@Overridepublic void info(Marker marker, String format, Object arg) {this.logger.info(marker, format, arg);}@Overridepublic void info(Marker marker, String format, Object arg1, Object arg2) {this.logger.info(marker, format, arg1, arg2);}@Overridepublic void info(Marker marker, String format, Object... arguments) {this.logger.info(marker, format, arguments);}@Overridepublic void info(Marker marker, String msg, Throwable t) {this.logger.info(marker, msg, t);}@Overridepublic boolean isWarnEnabled() {return this.logger.isWarnEnabled();}@Overridepublic void warn(String msg) {this.logger.warn(msg);}@Overridepublic void warn(String format, Object arg) {this.logger.warn(format, arg);}@Overridepublic void warn(String format, Object... arguments) {this.logger.warn(format, arguments);}@Overridepublic void warn(String format, Object arg1, Object arg2) {this.logger.warn(format, arg1, arg2);}@Overridepublic void warn(String msg, Throwable t) {this.logger.warn(msg, t);}@Overridepublic boolean isWarnEnabled(Marker marker) {return this.logger.isWarnEnabled(marker);}@Overridepublic void warn(Marker marker, String msg) {this.logger.warn(marker, msg);}@Overridepublic void warn(Marker marker, String format, Object arg) {this.logger.warn(marker, format, arg);}@Overridepublic void warn(Marker marker, String format, Object arg1, Object arg2) {this.logger.warn(marker, format, arg1, arg2);}@Overridepublic void warn(Marker marker, String format, Object... arguments) {this.logger.warn(marker, format, arguments);}@Overridepublic void warn(Marker marker, String msg, Throwable t) {this.logger.warn(marker, msg, t);}@Overridepublic boolean isErrorEnabled() {return this.logger.isErrorEnabled();}@Overridepublic void error(String msg) {this.logger.error(msg);}@Overridepublic void error(String format, Object arg) {this.logger.error(format, arg);}@Overridepublic void error(String format, Object arg1, Object arg2) {this.logger.error(format, arg1, arg2);}@Overridepublic void error(String format, Object... arguments) {this.logger.error(format, arguments);}@Overridepublic void error(String msg, Throwable t) {this.logger.error(msg, t);}@Overridepublic boolean isErrorEnabled(Marker marker) {return this.logger.isErrorEnabled(marker);}@Overridepublic void error(Marker marker, String msg) {this.logger.error(marker, msg);}@Overridepublic void error(Marker marker, String format, Object arg) {this.logger.error(marker, format, arg);}@Overridepublic void error(Marker marker, String format, Object arg1, Object arg2) {this.logger.error(marker, format, arg1, arg2);}@Overridepublic void error(Marker marker, String format, Object... arguments) {this.logger.error(marker, format, arguments);}@Overridepublic void error(Marker marker, String msg, Throwable t) {this.logger.error(marker, msg, t);}
}
这是我为装饰器添加的默认实现,如有错误,欢迎批评指正。
然后就可以在相应的方法中添加我们的逻辑,如在error
的方法中向我们的日志监控服务推送消息。
总结
- 通过对
slf4j
源码的学习大致学习了日志框架slf4j
的运行原理。 - 通过找接口与父类理解了装饰器模式的应用场景。
- 本文只是实现了基本的功能,因为
error
方法与warn
方法有很多重载的方法,所以我们期待可以实现对该日志类中所有名为error
与warn
的方法进行切面处理。
slf4j 日志监控相关推荐
- SpringBoot入门建站全系列(二十八)整合Kafka做日志监控
SpringBoot入门建站全系列(二十八)整合Kafka做日志监控 一.概述 Apache Kafka是一个分布式发布 - 订阅消息系统和一个强大的队列,可以处理大量的数据,并使您能够将消息从一个端 ...
- 【详解】 ELK (ElasticStack) 实现日志监控
目录 ElasticStack 介绍: Demo 实现 说在前面 案例实现流程图 创建Spring Boot 项目 项目部署.运行 Logstash配置 FileBeat配置 ES配置 Kibana配 ...
- Java自动日志监控框架auto-log详解
Java自动日志监控框架auto-log详解 1. 需求概述 2. auto-log简介 2.1 auto-log定义 2.2 auto-log目的 2.3 auto-log特性 2.4 注解说明 2 ...
- ELK 搭建 TB 级海量日志监控系统,这个太强了!
欢迎关注方志朋的博客,回复"666"获面试宝典 作者:非洲羚羊 来源:cnblogs.com/dengbangpang/p/12961593.html 本文主要介绍怎么使用 ELK ...
- 简单分析MySQL 一则慢日志监控误报问题
这篇文章主要介绍了MySQL 一则慢日志监控误报的问题分析与解决,帮助大家更好的理解和使用MySQL,感兴趣的朋友可以了解下 之前因为各种原因,有些报警没有引起重视,最近放假马上排除了一些潜在的人为原 ...
- 打造一个TB级微服务日志监控平台
本文主要介绍怎么使用 ELK Stack 帮助我们打造一个支撑起日产 TB 级的日志监控系统.在企业级的微服务环境中,跑着成百上千个服务都算是比较小的规模了.在生产环境上,日志扮演着很重要的角色,排查 ...
- TB级微服务海量日志监控平台
本文主要介绍怎么使用 ELK Stack 帮助我们打造一个支撑起日产 TB 级的日志监控系统.在企业级的微服务环境中,跑着成百上千个服务都算是比较小的规模了.在生产环境上,日志扮演着很重要的角色,排查 ...
- 如何打造一个TB级微服务海量日志监控平台
前沿技术早知道,弯道超车有希望 积累超车资本,从关注DD开始 来源:性能与架构.图文编辑:xj 本文主要介绍怎么使用 ELK Stack 帮助我们打造一个支撑起日产 TB 级的日志监控系统.在企业级的 ...
- 深度学习核心技术精讲100篇(四十八)-TB级的日志监控系统很难?带你使用ELK轻松搭建日志监控系统
前言 本文主要介绍怎么使用 ELK Stack 帮助我们打造一个支撑起日产 TB 级的日志监控系统.在企业级的微服务环境中,跑着成百上千个服务都算是比较小的规模了.在生产环境上,日志扮演着很重要的角色 ...
最新文章
- Dropbox如何使用机器学习从数十亿图片中自动提取文字
- 使用CoreOS及Docker搭建简单的SaaS云平台
- 专访盖茨:我的梦想是实现生命价值平等[转]
- ajax传参到实体类对应字段
- centos 6.5 x64编译有python的vim7.4
- 项目实施管理之系统演示
- 轻松搞定vmware + win2003Cluste
- CSS-标准盒模型和怪异盒模型box-sizing
- java 算出下一个工作日,Java:计算一个日期加下指定工作日数(排除周六周日和一系列节日)...
- 视频监控物联卡有什么作用
- 【spring boot】application.properties官方完整文档【参考使用】
- MFC 的几个常用函数,用来计算文件大小,下载速度,转换时间的
- (2) 怎么学习IFC (Industry Foundation Class)
- 软件测试 — 面试题
- APP界面设计教程---手机ui高级实战案例(完整版)
- 步步为营---- MuleEsb学习(一) 扫盲篇
- PyCharm代码格式化插件
- 小型企业、初创企业海外众筹指南
- linux svn 查看忽略文件
- 优维EasyOps,打造新一代运维新方式
热门文章
- C++/C++11中头文件numeric的使用
- 二维码QR Code简介及其解码实现(zxing-cpp)
- 【Python】解决print不能立即打印的问题
- Linux查看WAS的jvm信息,linux 下使用命令查看jvm信息
- java冒泡排序_Java中的经典算法之冒泡排序(Bubble Sort)
- linux c 获取屏幕信息,Linux C 获取本机相关信息
- 关于60枚一分两分五分硬币凑成一块钱的解决方法
- 《深入理解计算机系统》第十章——系统级I/0
- 用R语言做词频统计_R语言 | 词频统计
- 浅谈 MVP in Android