java 异常 接入 钉钉

工具包

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

/**
 * @author 张林
 * @version 1.0
 * @date 2022/1/10 4:06 下午
 */
public class DingMessageUtils {

    public DingMessageUtils(String sendUrl, String secret, String active) {
        DingMessageUtils.sendUrl = sendUrl;
        DingMessageUtils.secret = secret;
        DingMessageUtils.active = active;
    }
	// 钉钉自定义机器人下的 url + token
    private static String sendUrl;
    // 密钥
    private static String secret;
    // 当前环境作推送限制
    private static String active;

    public void sendDingDingErrorMessage(Throwable e) {
        sendDingDingErrorMessage(getStackInfo(e));
    }

    public boolean sendDingDingErrorMessage(String errorMessage) {
        return sendDingDingMessage(errorMessage);
    }

    public boolean sendDingDingErrorMessage(Throwable e, String tranceId) {
    	// 组装信息格式
        return sendDingDingMessage(String.format(
                        "错误信息: \n" +
                        "%s \n" +
                        "TranceId : \n" +
                        "%s \n" +
                        "Stack_Info : \n" +
                        "%s",
                e.getMessage(), tranceId, getStackInfo(e)
        ));
        // 如果有elk 这里就不推送堆栈信息了
//        return sendDingDingMessage(String.format("%s \ntranceId : %s \n",
//                e.getMessage(), tranceId));
    }

    public boolean sendDingDingMessage(String message) {
    	// 特定环境就不推了
        if ("dev".equals(active) || Objects.isNull(secret) || Objects.isNull(sendUrl)) {
            return true;
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("msgtype", "text");
        JSONObject context = new JSONObject();
        context.put("content", message);
        jsonObject.put("text", context);

        String endUrl = sendUrl + genSign();
        String post = HttpUtil.post(endUrl, jsonObject.toString());
        return 0 == JSONObject.parseObject(post).getInteger("errcode");
    }

	// 签名 
    private static String genSign() {
        Long timestamp = System.currentTimeMillis();
        String stringToSign = timestamp + "\n" + secret;
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
            return "&timestamp=" + timestamp + "&sign=" + URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
            return "加密失败" + e.getMessage();
        }
    }

	// 堆栈信息
    private static String getStackInfo(Throwable e) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        e.printStackTrace(printWriter);
        return stringWriter.toString();
    }
}

获取链路的traceId

import brave.Tracer;

public class sendMessageUtil() {
	// 如果你的项目中接入了 ELK&链路追踪 , 这里可以获取traceId, 并且在推送消息的时候仅推送traceId, 
	// 这样在钉钉聊天窗中, 就不需要推送堆栈信息, 看着更舒服
	@Autowired
	private Tracer tracer;

    private void sendDingMessage(Throwable e) {
        dingMessageUtils.sendDingDingErrorMessage(e, tracer.currentSpan().context().traceIdString());
    }
}

在多环境使用中, 钉钉的配置信息可能需要yml 配置文件中获取, 但是不想把这些东西放在工具包中:
下边将DingMessageUtils 加入spring容器中管理

import util.DingMessageUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 张林
 * @version 1.0
 * @date 2022/1/10 5:58 下午
 */
@Configuration
public class DingMessageConfig {

   @Value("${spring.profiles.active}")
   private String active;
   @Value("${dingding.message.sendUrl}")
   private String sendUrl;
   @Value("${dingding.message.secret}")
   private String secret;

   @Bean
   public DingMessageUtils dingMessageUtil() {
       return new DingMessageUtils(sendUrl, secret, active);
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值