装饰器的实际应用

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 使用装饰器模式改造slf4j打印json格式日志

上一篇文章中总结了装饰器模式,现在将装饰器结合实际应用起来。

使用装饰器模式改造slf4j打印json格式日志,以便于日志的分析


一、准备

装饰器模式得有一个抽象组件Component

这里的抽象组件可以直接是org.slf4j.Loggerorg.slf4j.LoggerFactory#getLogger(java.lang.Class)可以看作是一个具体组件(Concrete Component)

还缺少装饰器(Decorator)具体组件(Concrete Decorator)

二、实现

2.1 装饰器JsonLoggerDecorator

publicclassJsonLoggerDecoratorimplementsLogger {
protectedfinalLoggerlogger;
publicJsonLoggerDecorator(Loggerlogger) {
this.logger=logger;
    }
@OverridepublicStringgetName() {
returnnull;
    }
@OverridepublicbooleanisTraceEnabled() {
returnfalse;
    }
@Overridepublicvoidtrace(Stringmsg) {
    }
@Overridepublicvoidtrace(Stringformat, Objectarg) {
    }
@Overridepublicvoidtrace(Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoidtrace(Stringformat, Object... arguments) {
    }
@Overridepublicvoidtrace(Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisTraceEnabled(Markermarker) {
returnfalse;
    }
@Overridepublicvoidtrace(Markermarker, Stringmsg) {
    }
@Overridepublicvoidtrace(Markermarker, Stringformat, Objectarg) {
    }
@Overridepublicvoidtrace(Markermarker, Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoidtrace(Markermarker, Stringformat, Object... argArray) {
    }
@Overridepublicvoidtrace(Markermarker, Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisDebugEnabled() {
returnfalse;
    }
@Overridepublicvoiddebug(Stringmsg) {
    }
@Overridepublicvoiddebug(Stringformat, Objectarg) {
    }
@Overridepublicvoiddebug(Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoiddebug(Stringformat, Object... arguments) {
    }
@Overridepublicvoiddebug(Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisDebugEnabled(Markermarker) {
returnfalse;
    }
@Overridepublicvoiddebug(Markermarker, Stringmsg) {
    }
@Overridepublicvoiddebug(Markermarker, Stringformat, Objectarg) {
    }
@Overridepublicvoiddebug(Markermarker, Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoiddebug(Markermarker, Stringformat, Object... arguments) {
    }
@Overridepublicvoiddebug(Markermarker, Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisInfoEnabled() {
returnfalse;
    }
@Overridepublicvoidinfo(Stringmsg) {
    }
@Overridepublicvoidinfo(Stringformat, Objectarg) {
    }
@Overridepublicvoidinfo(Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoidinfo(Stringformat, Object... arguments) {
    }
@Overridepublicvoidinfo(Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisInfoEnabled(Markermarker) {
returnfalse;
    }
@Overridepublicvoidinfo(Markermarker, Stringmsg) {
    }
@Overridepublicvoidinfo(Markermarker, Stringformat, Objectarg) {
    }
@Overridepublicvoidinfo(Markermarker, Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoidinfo(Markermarker, Stringformat, Object... arguments) {
    }
@Overridepublicvoidinfo(Markermarker, Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisWarnEnabled() {
returnfalse;
    }
@Overridepublicvoidwarn(Stringmsg) {
    }
@Overridepublicvoidwarn(Stringformat, Objectarg) {
    }
@Overridepublicvoidwarn(Stringformat, Object... arguments) {
    }
@Overridepublicvoidwarn(Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoidwarn(Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisWarnEnabled(Markermarker) {
returnfalse;
    }
@Overridepublicvoidwarn(Markermarker, Stringmsg) {
    }
@Overridepublicvoidwarn(Markermarker, Stringformat, Objectarg) {
    }
@Overridepublicvoidwarn(Markermarker, Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoidwarn(Markermarker, Stringformat, Object... arguments) {
    }
@Overridepublicvoidwarn(Markermarker, Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisErrorEnabled() {
returnfalse;
    }
@Overridepublicvoiderror(Stringmsg) {
    }
@Overridepublicvoiderror(Stringformat, Objectarg) {
    }
@Overridepublicvoiderror(Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoiderror(Stringformat, Object... arguments) {
    }
@Overridepublicvoiderror(Stringmsg, Throwablet) {
    }
@OverridepublicbooleanisErrorEnabled(Markermarker) {
returnfalse;
    }
@Overridepublicvoiderror(Markermarker, Stringmsg) {
    }
@Overridepublicvoiderror(Markermarker, Stringformat, Objectarg) {
    }
@Overridepublicvoiderror(Markermarker, Stringformat, Objectarg1, Objectarg2) {
    }
@Overridepublicvoiderror(Markermarker, Stringformat, Object... arguments) {
    }
@Overridepublicvoiderror(Markermarker, Stringmsg, Throwablet) {
    }
}

2.2 具体装饰器JsonLogger

importcom.alibaba.fastjson.JSONObject;
importorg.slf4j.Logger;
importjava.util.Arrays;
publicclassJsonLoggerextendsJsonLoggerDecorator {
publicJsonLogger(Loggerlogger) {
super(logger);
    }
@Overridepublicvoidinfo(Stringmsg) {
JSONObjectjsonObject=this.newJsonObject();
jsonObject.put("message", msg);
logger.info(jsonObject.toJSONString());
    }
@Overridepublicvoiderror(Stringmsg) {
JSONObjectjsonObject=this.newJsonObject();
jsonObject.put("message", msg);
logger.error(jsonObject.toJSONString());
    }
/*** 重载一个异常的error** @param e*/publicvoiderror(Exceptione) {
JSONObjectjsonObject=this.newJsonObject();
jsonObject.put("name", e.getClass().getName());
StringstackTrace=Arrays.toString(e.getStackTrace());
jsonObject.put("stackTrace", stackTrace);
logger.error(jsonObject.toJSONString());
    }
privateJSONObjectnewJsonObject() {
returnnewJSONObject();
    }
}

三、使用

Logger对外提供了一个工厂LoggerFactory,这里我们也提供一个JsonLoggerFactory

importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
publicclassJsonLoggerFactory {
publicstaticJsonLoggergetJsonLogger(Class<?>clazz) {
Loggerlogger=LoggerFactory.getLogger(clazz);
returnnewJsonLogger(logger);
    }
}

四、测试类

publicclassJsonLoggerTest {
privatestaticfinalJsonLoggerlogger=JsonLoggerFactory.getJsonLogger(JsonLoggerTest.class);
publicstaticvoidmain(String[] args) {
logger.info("info日志");
logger.error("系统异常");
logger.error(newException("抛出异常"));
    }
}

4.1 执行结果

10:30:31.368 [main] INFO com.example.validated.design.decorator.logger.JsonLoggerTest - {"message":"info日志"}
10:30:31.372 [main] ERROR com.example.validated.design.decorator.logger.JsonLoggerTest - {"message":"系统异常"}
10:30:31.372 [main] ERROR com.example.validated.design.decorator.logger.JsonLoggerTest - {"name":"java.lang.Exception","stackTrace":"[com.example.validated.design.decorator.logger.JsonLoggerTest.main(JsonLoggerTest.java:13)]"}

五、类图

image.png

六、其他

在实际的开发过程,我们也可以通过装饰器模式实现不同角色的用户去展示不同的导航菜单

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
装饰器:装饰器为主,闭包和高阶函数为辅
装饰器:装饰器为主,闭包和高阶函数为辅
|
5月前
|
测试技术 Python
装饰器
【8月更文挑战第1天】
28 2
|
8月前
|
设计模式
设计模式之装饰器 Decorator
设计模式之装饰器 Decorator
55 1
|
8月前
|
JavaScript
03_装饰器
03_装饰器
73 1
|
8月前
|
数据安全/隐私保护 Python
解释装饰器(decorator)的功能和用法。
解释装饰器(decorator)的功能和用法。
61 1
|
存储 缓存 关系型数据库
Python装饰器1-闭包与函数装饰器
闭包与函数装饰器:被装饰函数不带参数、被装饰函数带参数、装饰器带参数,装饰器的调用
Python装饰器1-闭包与函数装饰器
|
开发者 Python
装饰器详解|学习笔记
快速学习装饰器详解
|
Python
Python编程:decorator装饰器
Python编程:decorator装饰器
138 0
|
设计模式 JavaScript 前端开发
2021你要知道的前端装饰器(Decorator)
2021你要知道的前端装饰器(Decorator)
685 0