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

一、日志体系集成

1、日志管理

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

2、ELK日志体系

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

ELK相关文章:

  • SpringBoot2整合ElasticSearch框架
  • 搜索引擎框架,ElasticSearch集群模式
  • 基于Logstash全量或增量同步数据到ES中间件

基于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 ;@Resourceprivate 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. Unity - 搬砖日志 - BRP 管线下的自定义阴影尺寸(脱离ProjectSettings/Quality/ShadowResolution设置)

    文章目录 环境 原因 解决 CSharp 脚本 效果预览 - Light.shadowCustomResolution 效果预览 - Using Quality Settings 应用 Control ...

  2. 集成底座与业务系统对接过程梳理

    集成底座作为企业信息化的基础架构平台,主要满足5A管控.主数据治理以及业务集成等需求,通过基础架构的搭建,为企业的信息化建设提供一套全面稳定.标准统一.易于复用.灵活调整的基础环境.集成底座主要包括三 ...

  3. centos 日志切割_CentOS下的日志切割

    在Linux下,日志会不停的增长,为了防止日志文件过大,导致我们无法在日志中快速找到想要的信息,我们会定时对日志文件进行切割.在这里我将使用logrotate切割日志. (1).logrotate的配 ...

  4. JBoss模块很烂,无法在JBoss 7下使用自定义Resteasy / JAX-RS

    由于JBoss EAP 6.1 / AS 7.2.0是模块化的,并且您可以排除Webapp可见的模块,因此您希望可以轻松地忽略内置的JAX-RS实现(Rest Easy 2.3.6)并使用它.自定义的 ...

  5. Springboot2集成minidao持久层

    Springboot2集成minidao持久层 这里采用springboot版本号: 2.0.4.RELEASE minidao已经提供自定义starter,集成非常简单,直接pom引入minidao ...

  6. Mybatis集成日志与ehcache

    0:集成日志 1.导入log4j-1.2.17.jar包 1.在src目录下编写log4j.xml文件 一:回顾MyBatis的缓存技术 1.缓存技术是一种"以空间换时间"的设计理 ...

  7. 【Java从0到架构师】交错的日志系统、SpringBoot 集成日志框架

    交错的日志系统.SpringBoot 集成日志框架 交错复杂的日志系统① - 多个项目实现 SLF4J 门面 交错复杂的日志系统② - 统一底层实现为 Logback 交错复杂的日志系统③ - 统一底 ...

  8. 腾讯云海量社交网络业务下的DevOps架构应用实践

    在DevOps的理念中,企业的IT价值链流转的速度越快,意味着企业的互联网产品的交付能力越强,这也意味着在同行业的竞争中,企业凭借IT能力的优势,能够收获更大的竞争优势.也因此,DevOps框架的落地 ...

  9. 大前端时代,如何做好C 端业务下的React SSR?\n

    React在中后台业务里已经很好落地了,但对于C端(给用户使用的端,比如PC/H5)业务有其特殊性,对性能要求比较苛刻,且有SEO需求.另外团队层面也希望能够统一技术栈,小伙伴们希望成长,那么如何能够 ...

最新文章

  1. 支持Android4.0以下webp的使用
  2. windows下python安装Numpy和Scipy模块
  3. 【转】storm 开发系列一 第一个程序
  4. SQLite.NET在Win7(64位)下使用的问题
  5. 大厂经验(二):多端可视化埋点解决方案
  6. Android中Services简析
  7. 工业富联灯塔工厂白皮书:智能制造里程碑.pdf(附下载链接)
  8. Linux系统下破解root用户密码
  9. [转载] Python内置函数-min函数和max函数-详解
  10. Windows Phone 数据库并行访问【转】
  11. Linux TC的ifb原理以及ingress流控
  12. chromium/chrome内核修改、SEO快排搭建(2022最新源码)
  13. centos安装7zip
  14. 腾讯优图贾佳亚:当AI进入产业应用时代时,计算机视觉技术更应该服务于人才对!
  15. 在GPU上运行MATLAB程序
  16. 密码长度最小值修改为15位、16位
  17. html+css+JavaScript实现导航栏
  18. 求大神讨论:工科男如何找到自己的爱情
  19. 医保基金稽查案件管理系统丨陀螺研究院×FISCO BCOS案例专辑
  20. 兼容各大浏览器导出Excel

热门文章

  1. 编程中的移位运算符简单解释
  2. LSTM 与 Bilstm介绍(包含代码实现、Python)
  3. Postfix实现代理Exchange邮件传输方案
  4. Python数据存储:pickle模块的使用讲解(测试代码)
  5. java课程之团队开发冲刺阶段1.7
  6. ovs 下流表port 1进入,port 1出去
  7. JavaScript 基础 数据类型与运算符
  8. Myeclipse中左边的项目目录没了
  9. Luogu P1122 最大子树和 树形DP
  10. [leetcode]687. Longest Univalue Path