共计 4833 个字符,预计需要花费 13 分钟才能阅读完成。
本文源码: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 ;
@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 网关核心,落地实现计划 |