摘要:问题描述监控系统新系统起步,旨在监控原有系统的各种问题。实现思考日志问题与之前的映射问题不同。定义用对该日志对象进行装饰。然后就可以在相应的方法中添加我们的逻辑,如在的方法中向我们的日志监控服务推送消息。
问题描述 监控系统
新系统起步,旨在监控原有系统的各种问题。主要的一部分,就是监视原有系统的日志。
日志,是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; } @Override public String getName() { return this.logger.getName(); } @Override public boolean isTraceEnabled() { return this.logger.isTraceEnabled(); } @Override public void trace(String msg) { this.logger.trace(msg); } @Override public void trace(String format, Object arg) { this.logger.trace(format, arg); } @Override public void trace(String format, Object arg1, Object arg2) { this.logger.trace(format, arg1, arg2); } @Override public void trace(String format, Object... arguments) { this.logger.trace(format, arguments); } @Override public void trace(String msg, Throwable t) { this.logger.trace(msg, t); } @Override public boolean isTraceEnabled(Marker marker) { return this.logger.isTraceEnabled(marker); } @Override public void trace(Marker marker, String msg) { this.logger.trace(marker, msg); } @Override public void trace(Marker marker, String format, Object arg) { this.logger.trace(marker, format, arg); } @Override public void trace(Marker marker, String format, Object arg1, Object arg2) { this.logger.trace(marker, format, arg1, arg2); } @Override public void trace(Marker marker, String format, Object... argArray) { this.logger.trace(marker, format, argArray); } @Override public void trace(Marker marker, String msg, Throwable t) { this.logger.trace(marker, msg, t); } @Override public boolean isDebugEnabled() { return this.logger.isDebugEnabled(); } @Override public void debug(String msg) { this.logger.debug(msg); } @Override public void debug(String format, Object arg) { this.logger.debug(format, arg); } @Override public void debug(String format, Object arg1, Object arg2) { this.logger.debug(format, arg1, arg2); } @Override public void debug(String format, Object... arguments) { this.logger.debug(format, arguments); } @Override public void debug(String msg, Throwable t) { this.logger.debug(msg, t); } @Override public boolean isDebugEnabled(Marker marker) { return this.logger.isDebugEnabled(marker); } @Override public void debug(Marker marker, String msg) { this.logger.debug(marker, msg); } @Override public void debug(Marker marker, String format, Object arg) { this.logger.debug(marker, format, arg); } @Override public void debug(Marker marker, String format, Object arg1, Object arg2) { this.logger.debug(marker, format, arg1, arg2); } @Override public void debug(Marker marker, String format, Object... arguments) { this.logger.debug(marker, format, arguments); } @Override public void debug(Marker marker, String msg, Throwable t) { this.logger.debug(marker, msg, t); } @Override public boolean isInfoEnabled() { return this.logger.isInfoEnabled(); } @Override public void info(String msg) { this.logger.info(msg); } @Override public void info(String format, Object arg) { this.logger.info(format, arg); } @Override public void info(String format, Object arg1, Object arg2) { this.logger.info(format, arg1, arg2); } @Override public void info(String format, Object... arguments) { this.logger.info(format, arguments); } @Override public void info(String msg, Throwable t) { this.logger.info(msg, t); } @Override public boolean isInfoEnabled(Marker marker) { return this.logger.isInfoEnabled(marker); } @Override public void info(Marker marker, String msg) { this.logger.info(marker, msg); } @Override public void info(Marker marker, String format, Object arg) { this.logger.info(marker, format, arg); } @Override public void info(Marker marker, String format, Object arg1, Object arg2) { this.logger.info(marker, format, arg1, arg2); } @Override public void info(Marker marker, String format, Object... arguments) { this.logger.info(marker, format, arguments); } @Override public void info(Marker marker, String msg, Throwable t) { this.logger.info(marker, msg, t); } @Override public boolean isWarnEnabled() { return this.logger.isWarnEnabled(); } @Override public void warn(String msg) { this.logger.warn(msg); } @Override public void warn(String format, Object arg) { this.logger.warn(format, arg); } @Override public void warn(String format, Object... arguments) { this.logger.warn(format, arguments); } @Override public void warn(String format, Object arg1, Object arg2) { this.logger.warn(format, arg1, arg2); } @Override public void warn(String msg, Throwable t) { this.logger.warn(msg, t); } @Override public boolean isWarnEnabled(Marker marker) { return this.logger.isWarnEnabled(marker); } @Override public void warn(Marker marker, String msg) { this.logger.warn(marker, msg); } @Override public void warn(Marker marker, String format, Object arg) { this.logger.warn(marker, format, arg); } @Override public void warn(Marker marker, String format, Object arg1, Object arg2) { this.logger.warn(marker, format, arg1, arg2); } @Override public void warn(Marker marker, String format, Object... arguments) { this.logger.warn(marker, format, arguments); } @Override public void warn(Marker marker, String msg, Throwable t) { this.logger.warn(marker, msg, t); } @Override public boolean isErrorEnabled() { return this.logger.isErrorEnabled(); } @Override public void error(String msg) { this.logger.error(msg); } @Override public void error(String format, Object arg) { this.logger.error(format, arg); } @Override public void error(String format, Object arg1, Object arg2) { this.logger.error(format, arg1, arg2); } @Override public void error(String format, Object... arguments) { this.logger.error(format, arguments); } @Override public void error(String msg, Throwable t) { this.logger.error(msg, t); } @Override public boolean isErrorEnabled(Marker marker) { return this.logger.isErrorEnabled(marker); } @Override public void error(Marker marker, String msg) { this.logger.error(marker, msg); } @Override public void error(Marker marker, String format, Object arg) { this.logger.error(marker, format, arg); } @Override public void error(Marker marker, String format, Object arg1, Object arg2) { this.logger.error(marker, format, arg1, arg2); } @Override public void error(Marker marker, String format, Object... arguments) { this.logger.error(marker, format, arguments); } @Override public void error(Marker marker, String msg, Throwable t) { this.logger.error(marker, msg, t); } }
这是我为装饰器添加的默认实现,如有错误,欢迎批评指正。
然后就可以在相应的方法中添加我们的逻辑,如在error的方法中向我们的日志监控服务推送消息。
总结通过对slf4j源码的学习大致学习了日志框架slf4j的运行原理。
通过找接口与父类理解了装饰器模式的应用场景。
本文只是实现了基本的功能,因为error方法与warn方法有很多重载的方法,所以我们期待可以实现对该日志类中所有名为error与warn的方法进行切面处理。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/72208.html
摘要:这篇文章是边听尚硅谷的课程边记的笔记,也是为了之后方便查看,视频链接精彩的故事小张负责一个大型系统的开发,为了监控系统的运行状况,系统中包含大量的语句,为了更好地管理呢,小张决定写一个日志框架对日志进行管理,他设想的日志框架应该包含以下几个 这篇文章是边听尚硅谷的课程边记的笔记,也是为了之后方便查看,视频链接:https://www.bilibili.com/vide... 1. 精彩...
摘要:本文主要介绍如何使用这个可以直接显示完整的日志框架,希望对大家能有所帮助。当设置为或时,意味关闭记录。 在常规项目的开发中可能最容易出问题的地方就在于对数据库的处理了,在大部分的环境下,我们对数据库的操作都是使用流行的框架,比如 Hibernate 、 MyBatis 等。由于各种原因,我们有时会想知道在这些框架下实际执行的 SQL 究竟是什么。 虽然 Hibernate 可以在配置...
摘要:本文主要介绍如何使用这个可以直接显示完整的日志框架,希望对大家能有所帮助。当设置为或时,意味关闭记录。 在常规项目的开发中可能最容易出问题的地方就在于对数据库的处理了,在大部分的环境下,我们对数据库的操作都是使用流行的框架,比如 Hibernate 、 MyBatis 等。由于各种原因,我们有时会想知道在这些框架下实际执行的 SQL 究竟是什么。 虽然 Hibernate 可以在配置...
阅读 2528·2021-11-23 09:51
阅读 3334·2021-11-22 15:22
阅读 1851·2021-11-18 13:22
阅读 2195·2021-09-24 09:48
阅读 1285·2019-08-29 13:58
阅读 1276·2019-08-26 13:39
阅读 2397·2019-08-26 10:48
阅读 3016·2019-08-26 10:21