slf4j 日志监控

  • Post author:
  • Post category:其他


问题描述

监控系统

新系统起步,旨在监控原有系统的各种问题。主要的一部分,就是监视原有系统的日志。

日志,是

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

接口。


clipboard.png

这是

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

的源代码。


clipboard.png

里面有很多的条件,先根据条件获取

ILoggerFactory

,该接口一共有三个实现类,实现类中再去定义不同的

getLogger

方法,不同的工厂获取出来的日志对象是不同的。

因为对日志框架不是很了解,如果我们随便找一个类继承,那

slf4j

的判断就失去意义了,所以此种方法行不通。

装饰器模式

我们想到了装饰器模式。

将一个对象进行装饰,完善其方法。

先将

Logger

中的方法都实现掉,然后定义私有变量

logger

,定义有参构造函数。


clipboard.png

定义

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

的方法中向我们的日志监控服务推送消息。

总结

  1. 通过对

    slf4j

    源码的学习大致学习了日志框架

    slf4j

    的运行原理。
  2. 通过找接口与父类理解了装饰器模式的应用场景。
  3. 本文只是实现了基本的功能,因为

    error

    方法与

    warn

    方法有很多重载的方法,所以我们期待可以实现对该日志类中所有名为

    error



    warn

    的方法进行切面处理。