slf4j 日誌監控

問題描述

監控系統

新系統起步,旨在監控原有系統的各類問題。主要的一部分,就是監視原有系統的日誌。java

日誌,是Java企業級應用開發必不可少的一部分,市場上有諸多日誌框架。咱們選用slf4j服務器

日誌有如下級別:框架

TRACE, DEBUG, INFO, WARN, ERRORide

咱們期待,當系統運行時打印了WARNERROR級別的日誌時,向咱們的服務器推送消息。使得咱們能夠分析日誌,構造更完整的系統。函數

實現

思考

日誌問題與以前的Hibernate映射問題不一樣。學習

Hibernate映射問題是默認用這個類,而後咱們能夠利用Spring Boot爲咱們提供的配置,當去映射名稱的時候調用我這個類。this

咱們的日誌是這麼寫的:spa

private static final Logger logger = LoggerFactory.getLogger(xxxx.class);

對象都是從LoggerFactory那建立出來的,咱們根本沒辦法從配置中下手。debug

自定義日誌

新建日誌類YunzhiLogger,去實現org.slf4j.Logger接口。3d

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);
}

找父類

粗略地閱讀了一下LoggerFactorygetLogger的源代碼。

clipboard.png

裏面有不少的條件,先根據條件獲取ILoggerFactory,該接口一共有三個實現類,實現類中再去定義不一樣的getLogger方法,不一樣的工廠獲取出來的日誌對象是不一樣的。

由於對日誌框架不是很瞭解,若是咱們隨便找一個類繼承,那slf4j的判斷就失去意義了,因此此種方法行不通。

裝飾器模式

咱們想到了裝飾器模式。

將一個對象進行裝飾,完善其方法。

先將Logger中的方法都實現掉,而後定義私有變量logger,定義有參構造函數。

clipboard.png

定義loggerYunzhiLogger對該日誌對象進行裝飾。

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方法有不少重載的方法,因此咱們期待能夠實現對該日誌類中全部名爲errorwarn的方法進行切面處理。
相關文章
相關標籤/搜索