职贝云数AI新零售门户
标题:
接口报错预警企微音讯
[打印本页]
作者:
ECSGk4
时间:
2023-4-2 15:23
标题:
接口报错预警企微音讯
接口报错预警企微音讯
摘要
及时发现程序报错预警
关键词
企微发送助手音讯接口、自定义注解、aop、解耦
成绩的提出
1- 即时反馈用户端异常状况
2- 减少脏数据的入库
处理思绪以及实际
对于能够导致数据不分歧状况的地方 代码中不要catch 或者catch住要停止处理 或者抛出到controller层 在一致异常处理之前阻拦住异常 调用企微发送音讯接口向配置的员工发送企微音讯
(, 下载次数: 6)
上传
点击文件名下载附件
配置文件中配置运用称号、环境称号
在预警音讯中发送异常发生的接口、央求参数、错误信息、还有工夫戳。可以根据工夫戳定位到错误发生地位(方便查询日志)
运用
自定义一个starter starter中尽能够少依赖其他jar包
自定义了一个注解 对于在接口上添加此注解的接口停止错误预警
配置文件中可配置运用、环境、企业、对应企业的员工、能否激活此注解
运用时只需求添加starter依赖、配置你本人的配置文件 在接口报错的时分就会在企微中发给你预警音讯 对应的开发人员可以即时发现即时处理
注解
/**
* @Author ningYu
* @create 2022/6/10 11:17
* @Target 注解用来指定一个注解的运用范围
* @Retention 用于描画注解的生命周期,也就是该注解被保留的工夫长短
* @Documented 注解修饰的注解类会被 JavaDoc 工具提取成文档
* @Inherited 是一个标记注解,用来指定该注解可以被承继
*/
@Target(value = {ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface WarnNotice {
//方法名
String value() ;
//操作类型
int operateType();
//功能类型
String functionType() ;
}
复制代码
处理注解代码
`
@Pointcut("@annotation(com.huibo.warnNotice.annotation.WarnNotice)")
public void access() {
}
/**
* 假如接口抛出错误 企微提示开发人员
*
* @param joinPoint
* @throws Exception
*/
@AfterThrowing(value = "access()", throwing = "error")
public void addErrorLogRecord(JoinPoint joinPoint, Exception error) throws Exception {
String errMsg = "";
String timeStamp = System.currentTimeMillis() + "";
log.error(timeStamp + ":" + "接口出现异常 向配置的开发人员发起告诉");
try {
Signature sig = joinPoint.getSignature();
MethodSignature msig = (MethodSignature) sig;
//根据aop参数获取到目的对象 获取到切面 根据反射和切面获取到方法签名和方法参数获取目的对象的方法 获取到方法的注解 拿到注解的属性
Object target = joinPoint.getTarget();
Object[] args = joinPoint.getArgs();
Method method = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
WarnNotice annotation = method.getAnnotation(WarnNotice.class);
String methodName = annotation.value();
String[] parameterNames = u.getParameterNames(method);
Map<String, Object> paramMap = new HashMap<>();
if (parameterNames.length > 0) {
int i = 0;
for (String paramName : parameterNames) {
paramMap.put(paramName, args[i]);
}
}
errMsg = qwUserConfig.getEnvironment() + "环境:" + qwUserConfig.getModuleName() + "bug音讯预警--\n timeStamp:" + timeStamp + "\n 方法:" + methodName + "\n param:" + JSON.toJSONString(paramMap) + "\n error:" + error.getMessage();
sendQwMsg(errMsg);
} catch (Throwable e) {
log.error(timeStamp + ":发音讯代码错误 " + e.getMessage(), e);
} finally { //将异常抛出去 交给全局异常处理器处理
if (error instanceof BizException) {
BizException e = (BizException) error;
log.error(timeStamp + e.getMessage(), e);
throw new BizException(e.getCode(), e.getMessage());
} else {
log.error(timeStamp + error.getMessage(), error);
throw new BizException(BizExceptionEnum.SYSTEM_ERROR);
}
}
}`
复制代码
发送企微音讯代码
//这里其实就是调用了一个http接口
public void sendQwMsg(String errMsg) throws Exception {
log.info("errMsg:[{}]", errMsg);
LambdaQueryWrapper<QyAgentInfo> qw = new LambdaQueryWrapper<>();
qw.eq(QyAgentInfo::getIsDelete, 0)
.eq(QyAgentInfo::getStatus, 1)
.eq(QyAgentInfo::getCorpId, qwUserConfig.getCorpid())
.last(" limit 1 ");
QyAgentInfo qyAgentInfo = qyAgentInfoMapper.selectOne(qw);
RestTemplate restTemplate = new RestTemplate();
log.info("qyAgentInfo:[{}]", JSON.toJSONString(qyAgentInfo));
URI uri = new URI(qwUserConfig.getSendurl() + qyAgentInfo.getAccessToken());
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("touser", qwUserConfig.getTouser());
paramMap.put("msgtype", qwUserConfig.getMsgtype());
paramMap.put("agentid", qwUserConfig.getAgentid());
paramMap.put("safe", qwUserConfig.getSafe());
Map<String, Object> map = new HashMap<>();
map.put("content", errMsg);
paramMap.put("text", map);
RequestEntity<Map<String, Object>> requestEntity = RequestEntity.post(uri).
contentType(MediaType.APPLICATION_JSON).body(paramMap);
ResponseEntity<QiWeiRes> exchange = restTemplate.exchange(requestEntity, QiWeiRes.class);
return;
}
复制代码
欢迎光临 职贝云数AI新零售门户 (https://www.taojin168.com/cloud/)
Powered by Discuz! X3.5