欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线上日志线上流量回放-预发环境-接入报警篇

程序员文章站 2022-07-13 15:18:23
...

http接口解析见https://blog.csdn.net/weixin_42498050/article/details/105039318

本篇介绍接入报警能力

钉钉机器人报警钉钉开放平台

https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq

1. 群添加机器人-自定义机器人

线上日志线上流量回放-预发环境-接入报警篇

线上日志线上流量回放-预发环境-接入报警篇

2. webhook就是机器人接口,除了token还需要传

timestamp和sign

线上日志线上流量回放-预发环境-接入报警篇

 

线上日志线上流量回放-预发环境-接入报警篇

3. 报警消息发送到机器人

 

package com.alibaba.logPlayBack.sdksearch.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.httpclient.Header;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import org.apache.commons.codec.binary.Base64;

import java.net.URLEncoder;

/**
 * 报警-钉钉消息-机器人
 */
public class DingTalkUtil {
    public static int alert(String token, String text, List<String> mobiles, boolean isAtAll) throws IOException {
        // 是否@所有人,true为会在报警信息后面@所有人,false不会在报警信息后面@所有人
        isAtAll = false;

        // 安全设置加签timestamp和sign(这个问题排查了半天,原来的机器人可以发报警,最新创建的不可以,原来钉钉增加了此选项,接口传参参数变了)
        Long timestamp = System.currentTimeMillis();
        String secret = "this is secret";

        String stringToSign = timestamp + "\n" + secret;
        Mac mac = null;

        try {
            mac = Mac.getInstance("HmacSHA256");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        try {
            mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }

        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        System.out.println(sign);

        // 以上代码是安全设置加签timestamp和sign参数传参,保持之前的token不变

        if (null == token || token.isEmpty()) {
            // 日志流量回放群钉钉机器人token
            token = "xx";
        }

        String url = "https://oapi.dingtalk.com/robot/send?access_token=" + token + "&timestamp=" + timestamp + "&sign=" + sign;
        // 以下为改版之前老的机器人传参,不需要timestamp和sign
        // String url = "https://oapi.dingtalk.com/robot/send?access_token=" + token;
        //System.out.println(url);

        Header header = new Header("Content-type", "application/json");

        // 其他传参 msgtype content atMobiles isAtAll
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("msgtype", "text");
        JSONObject textJson = new JSONObject();
        textJson.put("content", text);
        bodyJson.put("text", textJson);

        JSONObject at = new JSONObject();
        if (null != mobiles && !mobiles.isEmpty()) {
            at.put("atMobiles", mobiles.toArray());
        }

        at.put("isAtAll", isAtAll);
        bodyJson.put("at", at);
        //String info="";

        String info = HttpUtilAdd.doPost(url, bodyJson.toJSONString(), header);
        if (info != null && !info.isEmpty()) {
            return 1;
        } else {
            return 0;
        }
    }

    public static void main(String[] args) throws IOException {

        String err = "钉钉发不出消息了吗?日志";
        // 群钉钉机器人
        alert("xx", err, null, false);
    }
}

 

业务代码

package com.alibaba.logPlayBack.sdksearch.searchScene;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.logPlayBack.sdksearch.logDeal.logJoinPrint;
import com.alibaba.logPlayBack.FileOperate.FileWrite;
import com.alibaba.logPlayBack.sdksearch.utils.DingTalkUtil;
import com.alibaba.logPlayBack.sdksearch.utils.TimeTransfer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;


public class mobile_multi {
    private static Logger logger = LoggerFactory.getLogger(mobile_multi.class);


    /**
     * @param responseToJson
     * @param count          mobile_multi为搜索默认页场景
     */
    public static void parse2JSON(JSONObject requestToJson, JSONObject responseToJson, int count, long currentTimeMillis) {

        boolean mobile_multi = requestToJson.getString("appScene").equals("mobile_multi");
        // 读取的日志里,记录用户行为的时间clientTimeStamp
        String clientTimeStamp = TimeTransfer.clientTimeStamp(requestToJson);
        StringBuilder sb = new StringBuilder();

        HashMap<String, Integer> appScenes = new HashMap<>();

        if (mobile_multi) {

            Object ob = appScenes.get("mobile_multi");
            if (ob != null) {
                int value = Integer.parseInt(ob.toString());
                appScenes.put("mobile_multi", value);
            } else {
                appScenes.put("mobile_multi", 1);
            }
            // 取[]是JSONArray,如nodes: [] ,取{}是JSONObject,如data:{},取int类型的返回值是getString,如status: 0
            // 发现在浏览器里的返回key没有"",如level: 0,  在Charles里key有"",如"level": 0,

            // 1. 返回类型为JSONObject,data: {}
            System.out.println("responseToJson为" + responseToJson);
            JSONObject data = responseToJson.getJSONObject("data");
            Integer pz = responseToJson.getJSONObject("data").getInteger("pz");
            Integer rstate = data.getInteger("rstate");
            Integer isEnd = data.getInteger("isEnd");
            String highlightWord = data.getString("highlightWord");
//            JSONObject trackInfo = responseToJson.getJSONObject("data").getJSONObject("action").getJSONObject("report").getJSONObject("trackInfo");

            if (!data.containsKey("1111")) {
                System.err.println(logJoinPrint.bugDesc(requestToJson, count) + "data为空");
                // 用于写入错误日志文件errorLog,再做字段拆分,从而写入数据库,记录读取的log日志
                FileWrite.errorLog(logJoinPrint.errLogJoint(currentTimeMillis, count, requestToJson) +
                        "条日志,搜索场景为【搜索结果页】,接口返参data为空,BUG BUG BUG!!!" + FileWrite.rex + "1");
                // 记录error级别的信息
                logger.error(logJoinPrint.logBugDesc(requestToJson, count) + "data为空");
                //2019-10-28新增钉钉机器人接入报警,打印出问题的参数以及在数据库查询出的原始日志,便于排查
                sb.append("第" + count + "条日志,预发环境流量回放接口返回===搜索场景为【" + requestToJson.getString("appScene") +
                        "】,data为空。请求参数为==" + requestToJson);

                // 搜索线上-日志监控机器人报警,此处填写自己创建机器人时的token
                if (!sb.toString().isEmpty()) {
                    try {
                        // 机器人报警,此处填写自己创建机器人时的token
                        DingTalkUtil.alert(null, sb.toString(), null, false);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            if (pz != 30) {
                System.err.println(logJoinPrint.bugDesc(requestToJson, count) + "pz不为30");
                // 用于写入错误日志文件errorLog,再做字段拆分,从而写入数据库,记录读取的log日志
                FileWrite.errorLog(currentTimeMillis + FileWrite.rex + clientTimeStamp + FileWrite.rex + count + FileWrite.rex + "条日志,搜索场景为【搜索结果页】,接口返参" +
                        "data结果为空,BUG BUG BUG!!!" + FileWrite.rex + "1");
                System.err.println("第" + count + "条日志,搜索场景为【搜索结果页】,接口返参data结果为空,BUG BUG BUG!!!");
                // 记录error级别的信息
                logger.error("第" + count + "条日志,搜索场景为【搜索结果页】,接口返参data结果为空,BUG BUG BUG!!!");

            }

            System.out.println("搜索场景【mobile_multi】日志回放结束,共" + count + "条日志");
            System.err.println("mobile_multi的个数为:" + appScenes.size());

        }

    }
}



 

保存原始日志以及错误日志,以后开发接口写库用

线上日志线上流量回放-预发环境-接入报警篇

 

 

线上日志线上流量回放-预发环境-接入报警篇

 

待续。。

相关标签: 流量回放