本文源码: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. C#LeetCode刷题-记忆化

    记忆化篇 # 题名 刷题 通过率 难度 329 矩阵中的最长递增路径   31.0% 困难

  2. Linux学习日志——基本指令②

    文章目录 Linux学习日志--基本指令② 前言 touch cp (copy) mv (move) rm vim 输出重定向(> 或 >>) cat df(disk free) f ...

  3. MySQL元数据信息

    一.查看数据库清单 show databases; 二.查看数据库下表清单 方法1) show full tables from ${schema名}; 方法2) use ${数据库名}; show ...

  4. vue.extend和vue.component的区别

    vue.extend 使用基础 Vue 构造器函数,通过原型继承,(返回)创建一个"子类"(构造器).参数是一个包含组件选项的对象. const Sub = function Vu ...

  5. 【USACO13DEC】 最优挤奶 - 线段树

    题目描述 FJ最近买了1个新仓库, 内含N 个挤奶机,1 到N 编号并排成一行. 挤奶机i 每天能产出M(i) 单位的奶.不幸的是, 机器装得太近以至于如果一台机器i 在某天被使用, 那与它相邻的两台 ...

  6. Salesforce学习笔记之Actions and Recommendations(续)

    上次对这个Actions and Recommendations进行了初步研究,因为一些问题没有得到很好的解决,又花了很多时间,终于得到了一个比较好的解决方案.小结一下. 1. 生成Actions a ...

  7. 《Java从入门到失业》第二章:Java环境(一):Java SE安装

    从这一章开始,终于我们可以开始正式进入Java世界了.前面我们提到过,Java分三个版本,我们这里只讨论Java SE. 2.1Java SE安装 所谓工欲善其事,必先利其器.第一步,我们当然是要下载 ...

  8. 上手了RabbitMQ?再来看看它的交换机(Exchange)吧

    人生终将是场单人旅途,孤独之前是迷茫,孤独过后是成长. 楔子 本篇是消息队列RabbitMQ的第三弹. RabbitMQ的入门和RabbitMQ+SpringBoot的整合可以点此链接进去回顾,今天要 ...

  9. docker入门2-docker service

    docker service介绍 service是生产环境中某个image的container集合.一个service只使用一个image,但它编排这个image的运行方式,比如使用哪个端口,根据需求 ...

  10. 使用BurpSuite、Hydra和medusa爆破相关的服务

    一.基本定义 1.爆破=爆破工具(BP/hydra)+字典(用户字典/密码字典). 字典:就是一些用户名或者口令(弱口令/使用社工软件的生成)的集合. 2.BurpSuite 渗透测试神器,使用Jav ...