链路追踪
# 埋点
埋点状态
@Getter
@ToString
@AllArgsConstructor
public enum AnchorState implements PowerfulEnum {
/**
* 消息接收成功(获取到请求)
*/
RECEIVE(10, "消息接收成功"),
/**
* 消息被丢弃(从Kafka消费后,被丢弃)
*/
DISCARD(20, "消费被丢弃"),
/**
* 消息被夜间屏蔽(模板设置了夜间屏蔽)
*/
NIGHT_SHIELD(22, "夜间屏蔽"),
/**
* 消息被夜间屏蔽(模板设置了夜间屏蔽,次日9点再发送)
*/
NIGHT_SHIELD_NEXT_SEND(24, "夜间屏蔽(次日早上9点发送)"),
/**
* 消息被内容去重(重复内容5min内多次发送)
*/
CONTENT_DEDUPLICATION(30, "消息被内容去重"),
/**
* 消息被频次去重(同一个渠道短时间内发送多次消息给用户)
*/
RULE_DEDUPLICATION(40, "消息被频次去重"),
/**
* 白名单过滤(非正式环境,不在白名单内)
*/
WHITE_LIST(50, "白名单过滤"),
/**
* 下发成功(调用渠道接口成功)
*/
SEND_SUCCESS(60, "消息下发成功"),
/**
* 下发失败(调用渠道接口失败)
*/
SEND_FAIL(70, "消息下发失败"),
/**
* 点击(下发的消息被点击)
*/
CLICK(64, "消息被点击");
private final Integer code;
private final String description;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
埋点信息
public class SimpleAnchorInfo {
/**
* 具体点位
*/
private int state;
/**
* 业务Id(数据追踪使用)
* 生成逻辑参考 TaskInfoUtils
*/
private Long businessId;
/**
* 生成时间
*/
private long timestamp;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 全链路请求参数
public class DataParam {
/**
* 查看消息Id的链路信息
*/
private String messageId;
/**
* 查看用户的链路信息
*/
private String receiver;
/**
* 业务Id(数据追踪使用)
* 如果传入的是模板ID,则生成当天的业务ID
*/
private String businessId;
/**
* 日期时间(检索短信的条件使用)
*/
private Long dateTime;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 全链路返回信息
public class TraceResponse {
/**
* 响应状态
*/
private String code;
/**
* 响应编码
*/
private String msg;
/**
* 埋点信息
*/
private List<SimpleAnchorInfo> data;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 链路查询
基于MessageID查询链路结果;
@Service
@Primary
public class TraceServiceImpl implements TraceService {
@Autowired
private RedisUtils redisUtils;
@Override
public TraceResponse traceByMessageId(String messageId) {
if (CharSequenceUtil.isBlank(messageId)) {
return new TraceResponse(RespStatusEnum.CLIENT_BAD_PARAMETERS.getCode(), RespStatusEnum.CLIENT_BAD_PARAMETERS.getMsg(), null);
}
String redisMessageKey = CharSequenceUtil.join(StrUtil.COLON, AustinConstant.CACHE_KEY_PREFIX, AustinConstant.MESSAGE_ID, messageId);
List<String> messageList = redisUtils.lRange(redisMessageKey, 0, -1);
if (CollUtil.isEmpty(messageList)) {
return new TraceResponse(RespStatusEnum.FAIL.getCode(), RespStatusEnum.FAIL.getMsg(), null);
}
// 按时间排序
List<SimpleAnchorInfo> sortAnchorList = messageList.stream().map(s -> JSON.parseObject(s, SimpleAnchorInfo.class)).sorted((o1, o2) -> Math.toIntExact(o1.getTimestamp() - o2.getTimestamp())).collect(Collectors.toList());
return new TraceResponse(RespStatusEnum.SUCCESS.getCode(), RespStatusEnum.SUCCESS.getMsg(), sortAnchorList);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 获取发送消息的全链路数据
接口:DataController#getMessageData()
@PostMapping("/message")
@ApiOperation("/获取【72小时】发送消息的全链路数据")
public UserTimeLineVo getMessageData(@RequestBody DataParam dataParam) {
if (Objects.isNull(dataParam) || CharSequenceUtil.isBlank(dataParam.getMessageId())) {
return UserTimeLineVo.builder().items(new ArrayList<>()).build();
}
return dataService.getTraceMessageInfo(dataParam.getMessageId());
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
@Override
public UserTimeLineVo getTraceMessageInfo(String messageId) {
TraceResponse traceResponse = traceService.traceByMessageId(messageId);
if (CollUtil.isEmpty(traceResponse.getData())) {
return UserTimeLineVo.builder().items(new ArrayList<>()).build();
}
return buildUserTimeLineVo(traceResponse.getData());
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8