本文源码:GitHub·点这里 || GitEE·点这里

一、日志体系集成

1、日志管理

在系统的开发中,最关键的一个组件工具就是日志,日志打印方便问题排查,或者生产事故回溯,日志记录用来监控并分析系统性能点,并以此为依据,不断对系统进行优化;同时基于用户的操作日志,对用户行为进行分析,开发智能推荐的功能,或者进行营销投放,这在系统中都是常见且关键的业务流程。

2、ELK日志体系

在大型系统架构中,ELK的日志管理系统是系统必备功能,ELK-Stack是Elasticsearch、Logstash、Kiban三个开源软件的组合,通常用来做日志分析,实时数据检索。基于Logstash做数据流动通道,使日志数据不断的流入搜索组件,基于Elasticsearch做数据实时查询,基于Kiban的ES可视化界面,以此实现日志数据的搜集、存储、分析等核心功能,且该体系方便扩展。

ELK相关文章:

基于ELK体系的核心操作,有关于ElasticSearch其他文章可以自行查阅之前的内容,这里不在陈列,好像很多东西都是这样一点点积累出来的。

二、集成环境

1、项目结构

defined-log-api:测试工程;

defined-log-config:日志核心模块,依赖之后使用该模块下注解即可;

2、数据表结构

CREATE TABLE dt_defined_log (
id INT ( 11 ) NOT NULL AUTO_INCREMENT COMMENT '主键',
class_name VARCHAR ( 200 ) DEFAULT NULL COMMENT '请求类名',
method_name VARCHAR ( 100 ) DEFAULT NULL COMMENT '请求方法名',
method_desc VARCHAR ( 100 ) DEFAULT NULL COMMENT '请求方法描述',
api_type INT ( 1 ) DEFAULT 0 COMMENT 'API类型',
biz_nature INT ( 1 ) DEFAULT 0 COMMENT '业务性质类型',
data_flow_type INT ( 1 ) DEFAULT 0 COMMENT '日志数据流向',
req_param VARCHAR ( 200 ) DEFAULT NULL COMMENT '请求报文',
res_param VARCHAR ( 200 ) DEFAULT NULL COMMENT '响应报文',
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '日志记录表';

这里完全基于业务需求自定义即可。

三、核心代码说明

1、注解参数

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface DefinedLog { /**
* 操作类型
*/
ApiTypeEnum apiType () ; /**
* 方法描述
*/
String methodDesc(); /**
* 业务性质
*/
BizNatureEnum bizNature() ; /**
* 数据流向,与业务性质关联
*/
DataFlowEnum dataFlow() ; /**
* 存储入参
*/
boolean isSaveReqParam () default true ; /**
* 存储出参
*/
boolean isSaveResParam() default true ; /**
* 是否需要异步处理
*/
boolean isAsync () default false ;
}

这里描述一下如下几个参数的意思:

bizNature:业务性质,即该日志是否有分析,或者营销推广操作,例如在在电商业务中,浏览系列商品后是否推送广告;

dataFlow:数据流向,即数据存储后是否向其他数据源推送,常见可能推送到MQ或者Redis或者分析引擎中,推荐类系统中对关键日志实时性要求极高,可以基于此做用户行为实时分析;

isAsync:是否异步处理,在一些并发高的接口中,避免日志记录成为性能问题的一个因素;

其他相关参数都是十分常见,例如接口类型增删改查,入参出参报文存储,方法模块的描述等等,这些都可以基于业务的需求自定义,然后做相关业务处理开发,思路开阔即可。

2、切面拦截

基于切面编程是方式,做相关日志处理,获取相应参数,构建日志模型即可。

@Component
@Aspect
public class LogAop { private static final Logger LOGGER = LoggerFactory.getLogger(LogAop.class); @Value("${spring.application.app-id}")
private String appId ;
@Resource
private DefineLogService defineLogService ; /**
* 日志切入点
*/
@Pointcut("@annotation(com.defined.log.annotation.DefinedLog)")
public void logPointCut() { } /**
* 环绕切入
*/
@Around("logPointCut()")
public Object around (ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object result = null ;
StopWatch stopWatch = new StopWatch();
stopWatch.start();
try{
// 执行方法
result = proceedingJoinPoint.proceed();
stopWatch.stop();
} catch (Exception e){
stopWatch.stop();
} finally {
// 保存日志
LOGGER.info(" execute time: {} ms ", stopWatch.getTotalTimeMillis());
DefineLogModel defineLogModel = buildLogParam (proceedingJoinPoint);
defineLogModel.setResParam(JSONObject.toJSONString(result));
defineLogService.saveLog(defineLogModel) ;
}
return result ;
} private DefineLogModel buildLogParam (ProceedingJoinPoint point){ DefineLogModel defineLogModel = new DefineLogModel() ; MethodSignature signature = (MethodSignature) point.getSignature();
Method reqMethod = signature.getMethod();
String className = point.getTarget().getClass().getName();
Object[] reqParam = point.getArgs(); LOGGER.info("请求方法:"+reqMethod.getName());
LOGGER.info("请求类名:"+className);
LOGGER.info("请求参数:"+ JSONObject.toJSONString(reqParam));
// 获取方法上注解
reqMethod.getAnnotation(DefinedLog.class).getClass();
DefinedLog definedLog = reqMethod.getAnnotation(DefinedLog.class); // 构建参数
String methodName = reqMethod.getName() ;
Integer apiType = definedLog.apiType().getApiType();
String apiTypeDesc = definedLog.apiType().getApiTypeDesc();
String methodDesc = definedLog.methodDesc() ;
Integer bizNature = definedLog.bizNature().getBizNature() ;
Integer dataFlowType = definedLog.dataFlow().getDataFlowType();
boolean isSaveReqParam = definedLog.isSaveReqParam();
boolean isSaveResParam = definedLog.isSaveResParam();
boolean isAsync = definedLog.isAsync() ; defineLogModel.setAppId(appId);
defineLogModel.setClassName(className);
defineLogModel.setMethodName(methodName);
defineLogModel.setMethodDesc(methodDesc);
defineLogModel.setApiType(apiType);
defineLogModel.setApiTypeDesc(apiTypeDesc);
defineLogModel.setBizNature(bizNature);
defineLogModel.setDataFlowType(dataFlowType);
defineLogModel.setSaveReqParam(isSaveReqParam);
defineLogModel.setSaveResParam(isSaveResParam);
defineLogModel.setAsync(isAsync);
defineLogModel.setReqParam(JSONObject.toJSONString(reqParam)); return defineLogModel ;
}
}

3、使用方式

DefinedLog注解在接口方法上即可。

@RestController
public class LogController { @GetMapping("/logApi")
@DefinedLog(apiType=ApiTypeEnum.COMPOSITE,
methodDesc="测试日志",
bizNature= BizNatureEnum.DEFAULT,
dataFlow= DataFlowEnum.DEFAULT)
public String logApi (@RequestParam("param") String param){
return "success-re" ;
} }

4、记录参数

这样自定义日志流程就完成了。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/middle-ware-parent
GitEE·地址
https://gitee.com/cicadasmile/middle-ware-parent

推荐阅读:微服务架构系列

标题
微服务架构:项目技术选型简介,架构图解说明
微服务架构:业务架构设计,系统分层管理
微服务架构:数据库选型简介,业务数据规划设计
微服务架构:中间件集成,公共服务封装
微服务架构:SpringCloud 基础组件应用设计
微服务架构:通过业务、应用、技术、存储,聊聊架构
微服务技术栈:常见注册中心组件,对比分析
微服务技术栈:流量整形算法,服务熔断与降级
微服务技术栈:API网关中心,落地实现方案

SpringBoot2 集成日志,复杂业务下的自定义实现的更多相关文章

  1. Activiti(二) springBoot2集成activiti,集成activiti在线设计器

    摘要 本篇随笔主要记录springBoot2集成activiti流程引擎,并且嵌入activiti的在线设计器,可以通过浏览器直接编辑出我们需要的流程,不需要通过eclipse或者IDEA的actiB ...

  2. go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务

    0.索引 go-zero docker-compose 搭建课件服务(九):http统一返回和集成日志服务 0.1源码地址 https://github.com/liuyuede123/go-zero ...

  3. 权限管理系统之项目框架搭建并集成日志、mybatis和分页

    前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...

  4. 小D课堂 - 零基础入门SpringBoot2.X到实战_第11节 Logback日志框架介绍和SpringBoot整合实战_45、SpringBoot2.x日志讲解和Logback配置实战

    笔记 2.SpringBoot2.x日志讲解和自定义Logback配置实战     简介:讲解SpringBoot2.x整合Logback配置实战 1.官网介绍:https://docs.spring ...

  5. ASP.NET全局错误处理和异常日志记录以及IIS配置自定义错误页面

    应用场景和使用目的 很多时候,我们在访问页面的时候,由于程序异常.系统崩溃会导致出现黄页.在通常的情况下,黄页对于我们来说,帮助是极大的,因为它可以帮助我们知道问题根源,甚至是哪一行代码出现了错误.但 ...

  6. Spring Boot 揭秘与实战(三) 日志框架篇 - 如何快速集成日志系统

    文章目录 1. 默认的日志框架 logback2. 常用的日志框架 log4j 1.1. 日志级别 1.2. 日志文件 3. 源代码 Java 有很多日志系统,例如,Java Util Logging ...

  7. UidGenerator springboot2集成篇

    uid-generator 官网集成文档: https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md 由于并没有提供spri ...

  8. Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

    Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...

  9. QLViewController在iOS7下的自定义

    原文来自:QLViewController在iOS7下的自定义 原先的项目使用了quicklook framework,用于在iPhone上浏览各类文件,除了txt文本会有乱码的问题,其他文件的显示都 ...

随机推荐

  1. Java基础—面向对象特性

    1.三大特性 ①.封装 所谓封装,就是将客观事物封装成抽象的类,类的数据和方法只允许可信的类或者对象操作,对不可信的类或对象进行信息隐藏.封装是面向对象的特征之一,是对象和类概念的主要特性.简单的说, ...

  2. Springboot常用的注解

    1.@Controller主要用来修饰类,用来处理http请求 2.@ResponseBody主要用来修饰类和方法.返回字符串和json数据,不用来返回模板. 3.@RestController主要用 ...

  3. js获取当前地址信息

    var url = window.location.href; //获取当前窗口的Url; 结果:http://localhost:61768/Home/Index?id=2&age=18 v ...

  4. 手把手教你在win10下搭建pytorch GPU环境(Anaconda+Pycharm)

    Anaconda指的是一个开源的Python发行版本,其主要优点如下: Anaconda默认安装了常见的科学计算包,用它搭建起Python环境后不用再费时费力安装这些包: Anaconda可以创建互相 ...

  5. GAN量化评估方法——IS(Inception Score)和FID(Frechet Inception Distance score)

    生成模型产生的是高维的复杂结构数据,它们不同于判别模型,很难用简单的指标来评估模型的好坏.下面介绍两种当前比较流行的评估生成模型的指标(仅判别图像):IS(Inception Score)和FID(F ...

  6. goland2019.2破解方法

    第一步:下载 jetbrains-agent.jar 链接:https://pan.baidu.com/s/1V2qZokAeAGcbsKDaoD9eSw 提取码:nrce 第二步:将下载的jetbr ...

  7. HM16.0之PCM模式——xCheckIntraPCM

    参考:https://blog.csdn.net/cxy19931018/article/details/79781042 1.源代码: /** Check R-D costs for a CU wi ...

  8. Python语言中的关键字(自己做的读书笔记)

    电脑配置:联想笔记本电脑 windows8系统 Python版本:2.7.8 本文章撰写时间:2015.1.1 作者:陈东陈 阅读说明: 1.本文都是先解释,后放图片: 2.文中斜体部分要么为需要输入 ...

  9. JS继承 小白文

    继承我的理解是 一个对象 能够使用另一个对象的方法和属性 继承需要一个父类构造函数 一.通过原型链继承 通过 创建一个 Person 的实例对象,该对象身上 不仅有 name 和 age 等方法, 也 ...

  10. CloudBase Framework丨第一个 Deno 部署工具是如何打造的?

    云端一体化部署工具 CloudBase Framework (简称 CBF)自开源发布以来迭代迅速,不仅支持 Vue.React 等前端框架,也支持 Nuxt 等 SSR 框架,基于 Node 开发的 ...