基础描述
在实际业务中,很多时候都是被动获取系统业务异常,如通过业务部门或者通过客户反馈说某个功能不行时,这样显得系统很被动和呆板 在SpringBoot中有统一异常处理可以来实现,当我们检测到非业务异常时,比如空指针异常、数组越界异常等 我们可以主动知晓异常发生的时间和业务场景,方便系统主动捕获异常,快速定位处理 但都遇到过一样的事情——系统异常导致损失。这似乎成了每个公司都必须要经历的事情 不管是电商行业还是金融行业,凡涉及到交易的业务,其实都会有很大的系统风险。例如,系统或者接口异常导致用户无法完成交易,这对公司来说是交易额的损失。又比如,运营人员操作不当导致被刷单或者薅羊毛,这对公司来说是利润的损失
钉钉机器人创建
新建群
创建一个钉钉群,用于接收告警消息
新建钉钉机器人
点击群设置 点击机器人 选择自定义 进行配置 保存好密钥和webhook通知地址 收到告警消息
统一异常捕获
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@Autowired
DingMsgService dingMsgService;
@ExceptionHandler ( Exception . class )
public R handleException ( Exception e) {
log. error ( e. getMessage ( ) , e) ;
try {
dingMsgService. sendDingTalkMsg ( JSONObject . toJSONString ( e) ) ;
} catch ( Exception ee) {
log. error ( "发送异常信息接口异常" , ee) ;
}
return R . fail ( e. getMessage ( ) ) ;
}
}
发送钉钉消息
config :
dingtalk :
secret : SECe1a978f33f20ec1e91091a91ff52a3d2da0bb1afb48ef69d183ec9de7d35681f
webhook : https: //oapi.dingtalk.com/robot/send? access_token=20347ef4a6b6a8086227f5c36c09d62d452f787674be17cc6caa062d2d76e8ea
发送钉钉消息核心代码
@Slf4j
@Service
public class DingMsgService {
@Value ( "${config.dingtalk.secret}" )
private String dingtalkSecret;
@Value ( "${config.dingtalk.webhook}" )
private String dingtalkWebhook;
public void sendDingTalkMsg ( String content) {
if ( content. length ( ) >= 1990 ) {
content = content. substring ( 0 , 1990 ) ;
}
DingTalkSendMsgRequestDTO requestDTO = new DingTalkSendMsgRequestDTO ( ) ;
requestDTO. setSecret ( dingtalkSecret) ;
requestDTO. setWebhook ( dingtalkWebhook) ;
requestDTO. setContent ( content) ;
Map < String , String > contentMap = new HashMap < > ( ) ;
contentMap. put ( "content" , requestDTO. getContent ( ) ) ;
Map < String , Object > atMap = new HashMap < > ( ) ;
atMap. put ( "isAtAll" , requestDTO. getIsAtAll ( ) ) ;
atMap. put ( "atMobiles" , requestDTO. getMobileList ( ) ) ;
Map < String , Object > reqMap = new HashMap < > ( ) ;
reqMap. put ( "msgtype" , "text" ) ;
reqMap. put ( "text" , contentMap) ;
reqMap. put ( "at" , atMap) ;
requestDTO. setContent ( JSON. toJSONString ( reqMap) ) ;
try {
String secret = requestDTO. getSecret ( ) ;
long timestamp = Instant . now ( ) . toEpochMilli ( ) ;
String stringToSign = timestamp + "\n" + secret;
Mac mac = Mac . getInstance ( "HmacSHA256" ) ;
mac. init ( new SecretKeySpec ( secret. getBytes ( "UTF-8" ) , "HmacSHA256" ) ) ;
byte [ ] signData = mac. doFinal ( stringToSign. getBytes ( "UTF-8" ) ) ;
String sign = URLEncoder . encode ( new String ( Base64 . encodeBase64 ( signData) ) , "UTF-8" ) ;
String dingUrl = requestDTO. getWebhook ( ) + "×tamp=" + timestamp + "&sign=" + sign;
String result = HttpUtil . post ( dingUrl, requestDTO. getContent ( ) ) ;
log. info ( "re={}" , result) ;
} catch ( Exception e) {
log. error ( "钉钉推送消息出现异常" , e) ;
}
}
}
示例代码
@RestController
public class TestController {
@GetMapping ( value = "test" )
public R test ( ) {
System . out. print ( 1 / 0 ) ;
return R . ok ( ) ;
}
}
源码地址
示例代码地址下载 https://github.com/rundreamstop/springboot-msg
其他
我们平时开发接口时,遇到接口异常,我们希望能第一时间得知 以往的经验我们是通过邮件等方式告知相对于的人员 现在大多数的告警可以发送到相关的app上了 群机器人是钉钉群的高级扩展功能,群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步 借助钉钉机器人,通过调用官方提供的API,我们可以很方便地将异常告警信息通知到到相应的人员