1. 编写数据接口,可视化

2. 优化文档和部分代码
pull/6/head
3y 2 years ago
parent cf53796c42
commit 49cb93dcb7

@ -256,6 +256,10 @@ docker exec -it redis redis-cli
![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a532e3221834466a85b6739871694957~tplv-k3u1fbpfcp-watermark.image?)
注:我的配置里更改过端口,所以我的程序`AustinApplication`写的端口为7000
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1b3944f3a9e849219c60e673baa5b7ff~tplv-k3u1fbpfcp-watermark.image?)
**<https://www.apolloconfig.com/#/zh/deployment/quick-start-docker>**
**<https://github.com/apolloconfig/apollo/tree/master/scripts/docker-quick-start>**

@ -15,12 +15,6 @@ public class AustinConstant {
public final static Integer FALSE = 0;
/**
*
*/
public final static String YYYY_MM_DD = "yyyyMMdd";
/**
* cron
*/

@ -1,4 +1,4 @@
package com.java3y.austin.stream.domain;
package com.java3y.austin.common.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;

@ -15,7 +15,7 @@ import lombok.ToString;
@AllArgsConstructor
public enum AnchorState {
RECEIVE(10, "成功消费Kafka"),
RECEIVE(10, "消息接收成功"),
DISCARD(20, "消费被丢弃"),
CONTENT_DEDUPLICATION(30, "消息被内容去重"),
RULE_DEDUPLICATION(40, "消息被频次去重"),
@ -30,4 +30,19 @@ public enum AnchorState {
private Integer code;
private String description;
/**
* code
*
* @param code
* @return
*/
public static String getDescriptionByCode(Integer code) {
for (AnchorState anchorState : AnchorState.values()) {
if (anchorState.getCode().equals(code)) {
return anchorState.getDescription();
}
}
return "未知点位";
}
}

@ -1,9 +1,9 @@
package com.java3y.austin.handler.script;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import com.java3y.austin.common.constant.AustinConstant;
import com.java3y.austin.common.enums.SmsStatus;
import com.java3y.austin.handler.domain.SmsParam;
import com.java3y.austin.handler.domain.TencentSmsParam;
@ -66,7 +66,7 @@ public class TencentSmsScript implements SmsScript {
.reverse().substring(0, PHONE_NUM)).reverse().toString();
SmsRecord smsRecord = SmsRecord.builder()
.sendDate(Integer.valueOf(DateUtil.format(new Date(), AustinConstant.YYYY_MM_DD)))
.sendDate(Integer.valueOf(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN)))
.messageTemplateId(smsParam.getMessageTemplateId())
.phone(Long.valueOf(phone))
.supplierId(tencentSmsParam.getSupplierId())

@ -4,7 +4,7 @@ import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import com.java3y.austin.common.domain.AnchorInfo;
import com.java3y.austin.stream.domain.SimpleAnchorInfo;
import com.java3y.austin.common.domain.SimpleAnchorInfo;
import com.java3y.austin.stream.utils.LettuceRedisUtils;
import io.lettuce.core.RedisFuture;
import lombok.extern.slf4j.Slf4j;
@ -56,7 +56,7 @@ public class AustinSink implements SinkFunction<AnchorInfo> {
*/
redisFutures.add(redisAsyncCommands.hincrby(String.valueOf(info.getBusinessId()).getBytes(),
String.valueOf(info.getState()).getBytes(), info.getIds().size()));
redisFutures.add(redisAsyncCommands.expire(String.valueOf(info.getBusinessId()).getBytes(), DateUtil.offsetDay(new Date(), 30).getTime()));
redisFutures.add(redisAsyncCommands.expire(String.valueOf(info.getBusinessId()).getBytes(), (DateUtil.offsetDay(new Date(), 30).getTime())/ 1000));
return redisFutures;
});

@ -1,7 +1,7 @@
package com.java3y.austin.support.utils;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.java3y.austin.common.constant.AustinConstant;
import java.util.Date;
@ -21,10 +21,24 @@ public class TaskInfoUtils {
* (16)
*/
public static Long generateBusinessId(Long templateId, Integer templateType) {
Integer today = Integer.valueOf(DateUtil.format(new Date(), AustinConstant.YYYY_MM_DD));
Integer today = Integer.valueOf(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN));
return Long.valueOf(String.format("%d%s", templateType * TYPE_FLAG + templateId, today));
}
/**
* 8MessageTemplateId ID
*/
public static Long getMessageTemplateIdFromBusinessId(Long businessId) {
return Long.valueOf(String.valueOf(businessId).substring(1, 8));
}
/**
* businessId
*/
public static Long getDateFromBusinessId(Long businessId) {
return Long.valueOf(String.valueOf(businessId).substring(8));
}
/**
* url)
*/

@ -0,0 +1,12 @@
package com.java3y.austin.web.constants;
/**
* amis
* @author 3y
*/
public class AmisVoConstant {
public static final String LEGEND_TITLE = "人数";
public static final String TYPE = "bar";
}

@ -2,20 +2,17 @@ package com.java3y.austin.web.controller;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.java3y.austin.common.enums.RespStatusEnum;
import com.java3y.austin.common.vo.BasicResultVO;
import com.java3y.austin.support.utils.RedisUtils;
import com.java3y.austin.web.service.DataService;
import com.java3y.austin.web.vo.DataParam;
import com.java3y.austin.web.vo.amis.EchartsVo;
import com.java3y.austin.web.vo.amis.UserTimeLineVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import org.springframework.web.bind.annotation.*;
/**
* )
@ -28,29 +25,25 @@ import java.util.List;
@Api("获取数据接口(全链路追踪)")
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true", allowedHeaders = "*")
public class DataController {
@Autowired
private RedisUtils redisUtils;
@Autowired
private DataService dataService;
@GetMapping("/user")
@PostMapping("/user")
@ApiOperation("/获取【当天】用户接收消息的全链路数据")
public BasicResultVO getUserData(String receiver) {
List<String> list = redisUtils.lRange(receiver, 0, -1);
// log.info("data:{}", JSON.toJSONString(objectObjectMap));
return BasicResultVO.success();
public BasicResultVO getUserData(@RequestBody DataParam dataParam) {
UserTimeLineVo traceUserInfo = dataService.getTraceUserInfo(dataParam.getReceiver());
return BasicResultVO.success(traceUserInfo);
}
@GetMapping("/messageTemplate")
@PostMapping("/messageTemplate")
@ApiOperation("/获取消息模板全链路数据")
public BasicResultVO getMessageTemplateData(String businessId) {
public BasicResultVO getMessageTemplateData(@RequestBody DataParam dataParam) {
EchartsVo echartsVo = EchartsVo.builder().build();
if (StrUtil.isNotBlank(businessId)) {
echartsVo = dataService.getTraceMessageTemplateInfo(businessId);
if (StrUtil.isNotBlank(dataParam.getBusinessId())) {
echartsVo = dataService.getTraceMessageTemplateInfo(dataParam.getBusinessId());
}
return BasicResultVO.success(echartsVo);
return new BasicResultVO<>(RespStatusEnum.SUCCESS, echartsVo);
}
public static void main(String[] args) {

@ -1,7 +1,7 @@
package com.java3y.austin.web.service;
import com.java3y.austin.web.vo.amis.EchartsVo;
import com.java3y.austin.web.vo.amis.TimeLineItemVo;
import com.java3y.austin.web.vo.amis.UserTimeLineVo;
/**
*
@ -12,12 +12,18 @@ public interface DataService {
/**
*
*
* @param receiver
* @return
*/
TimeLineItemVo getTraceUserInfo(String receiver);
UserTimeLineVo getTraceUserInfo(String receiver);
/**
*
*
* @param businessId IDIDID
* @return
*/
EchartsVo getTraceMessageTemplateInfo(String businessId);

@ -1,19 +1,28 @@
package com.java3y.austin.web.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.java3y.austin.common.constant.AustinConstant;
import com.java3y.austin.common.domain.SimpleAnchorInfo;
import com.java3y.austin.common.enums.AnchorState;
import com.java3y.austin.common.enums.ChannelType;
import com.java3y.austin.support.dao.MessageTemplateDao;
import com.java3y.austin.support.domain.MessageTemplate;
import com.java3y.austin.support.utils.RedisUtils;
import com.java3y.austin.support.utils.TaskInfoUtils;
import com.java3y.austin.web.constants.AmisVoConstant;
import com.java3y.austin.web.service.DataService;
import com.java3y.austin.web.vo.amis.EchartsVo;
import com.java3y.austin.web.vo.amis.TimeLineItemVo;
import com.java3y.austin.web.vo.amis.UserTimeLineVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -31,23 +40,98 @@ public class DataServiceImpl implements DataService {
private MessageTemplateDao messageTemplateDao;
@Override
public TimeLineItemVo getTraceUserInfo(String receiver) {
return null;
public UserTimeLineVo getTraceUserInfo(String receiver) {
List<String> userInfoList = redisUtils.lRange(receiver, 0, -1);
if (CollUtil.isEmpty(userInfoList)) {
return UserTimeLineVo.builder().items(new ArrayList<>()).build();
}
// 0. 按时间排序
List<SimpleAnchorInfo> sortAnchorList = userInfoList.stream().map(s -> JSON.parseObject(s, SimpleAnchorInfo.class)).sorted((o1, o2) -> Math.toIntExact(o1.getTimestamp() - o2.getTimestamp())).collect(Collectors.toList());
// 1. 对相同的businessId进行分类 {"businessId":[{businessId,state,timeStamp},{businessId,state,timeStamp}]}
Map<String, List<SimpleAnchorInfo>> map = new HashMap<>();
for (SimpleAnchorInfo simpleAnchorInfo : sortAnchorList) {
List<SimpleAnchorInfo> simpleAnchorInfos = map.get(String.valueOf(simpleAnchorInfo.getBusinessId()));
if (CollUtil.isEmpty(simpleAnchorInfos)) {
simpleAnchorInfos = new ArrayList<>();
}
simpleAnchorInfos.add(simpleAnchorInfo);
map.put(String.valueOf(simpleAnchorInfo.getBusinessId()), simpleAnchorInfos);
}
// 2. 封装vo 给到前端渲染展示
List<UserTimeLineVo.ItemsVO> items = new ArrayList<>();
for (Map.Entry<String, List<SimpleAnchorInfo>> entry : map.entrySet()) {
Long messageTemplateId = TaskInfoUtils.getMessageTemplateIdFromBusinessId(Long.valueOf(entry.getKey()));
MessageTemplate messageTemplate = messageTemplateDao.findById(messageTemplateId).get();
StringBuilder sb = new StringBuilder();
for (SimpleAnchorInfo simpleAnchorInfo : entry.getValue()) {
if (AnchorState.RECEIVE.getCode().equals(simpleAnchorInfo.getState())) {
sb.append(StrPool.CRLF);
}
String startTime = DateUtil.format(new Date(simpleAnchorInfo.getTimestamp()), DatePattern.NORM_DATETIME_PATTERN);
String stateDescription = AnchorState.getDescriptionByCode(simpleAnchorInfo.getState());
sb.append(startTime).append(StrPool.C_COLON).append(stateDescription).append("==>");
}
for (String detail : sb.toString().split(StrPool.CRLF)) {
if (StrUtil.isNotBlank(detail)) {
UserTimeLineVo.ItemsVO itemsVO = UserTimeLineVo.ItemsVO.builder()
.businessId(entry.getKey())
.sendType(ChannelType.getEnumByCode(messageTemplate.getSendChannel()).getDescription())
.creator(messageTemplate.getCreator())
.title(messageTemplate.getName())
.detail(detail)
.build();
items.add(itemsVO);
}
}
}
return UserTimeLineVo.builder().items(items).build();
}
@Override
public EchartsVo getTraceMessageTemplateInfo(String businessId) {
// 1. 获取businessId并获取模板信息
businessId = getRealBusinessId(businessId);
Optional<MessageTemplate> optional = messageTemplateDao.findById(TaskInfoUtils.getMessageTemplateIdFromBusinessId(Long.valueOf(businessId)));
if (!optional.isPresent()) {
return null;
}
MessageTemplate messageTemplate = optional.get();
List<String> xAxisList = new ArrayList<>();
List<Integer> actualData = new ArrayList<>();
/**
* keystate
* value:stateCount
*/
Map<Object, Object> anchorResult = redisUtils.hGetAll(getRealBusinessId(businessId));
List<Integer> stateList = anchorResult.entrySet().stream().map(objectObjectEntry -> Integer.valueOf(String.valueOf(objectObjectEntry.getKey()))).collect(Collectors.toList());
for (AnchorState value : AnchorState.values()) {
if (CollUtil.isNotEmpty(anchorResult)) {
anchorResult = MapUtil.sort(anchorResult);
for (Map.Entry<Object, Object> entry : anchorResult.entrySet()) {
String description = AnchorState.getDescriptionByCode(Integer.valueOf(String.valueOf(entry.getKey())));
xAxisList.add(description);
actualData.add(Integer.valueOf(String.valueOf(entry.getValue())));
}
}
return null;
String title = "【" + messageTemplate.getName() + "】在" + TaskInfoUtils.getDateFromBusinessId(Long.valueOf(businessId)) + "的下发情况:";
return EchartsVo.builder()
.title(EchartsVo.TitleVO.builder().text(title).build())
.legend(EchartsVo.LegendVO.builder().data(Arrays.asList(AmisVoConstant.LEGEND_TITLE)).build())
.xAxis(EchartsVo.XAxisVO.builder().data(xAxisList).build())
.series(Arrays.asList(EchartsVo.SeriesVO.builder().name(AmisVoConstant.LEGEND_TITLE).type(AmisVoConstant.TYPE).data(actualData).build()))
.yAxis(EchartsVo.YAxisVO.builder().build())
.tooltip(EchartsVo.TooltipVO.builder().build())
.build();
}
/**
@ -65,5 +149,4 @@ public class DataServiceImpl implements DataService {
}
return businessId;
}
}

@ -19,14 +19,15 @@ public class DataParam {
/**
* userId
*/
private String userId;
private String receiver;
/**
* Id(使)
* TaskInfoUtils
* IDID
*/
private Long businessId;
private String businessId;
}

@ -1,5 +1,6 @@
package com.java3y.austin.web.vo.amis;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -21,28 +22,34 @@ public class EchartsVo {
/**
* title
*/
@JsonProperty
private TitleVO title;
/**
* tooltip
*/
@JsonProperty
private TooltipVO tooltip;
/**
* legend
*/
@JsonProperty
private LegendVO legend;
/**
* xAxis x
*/
@JsonProperty
private XAxisVO xAxis;
/**
* yAxis y
*/
@JsonProperty
private YAxisVO yAxis;
/**
* series
* <p>
* type
*/
@JsonProperty
private List<SeriesVO> series;
/**
@ -50,7 +57,6 @@ public class EchartsVo {
*/
@Data
@Builder
public static class TitleVO {
/**
* text
@ -63,8 +69,8 @@ public class EchartsVo {
*/
@Data
@Builder
public static class TooltipVO {
private String color;
}
/**
@ -72,7 +78,6 @@ public class EchartsVo {
*/
@Data
@Builder
public static class LegendVO {
/**
* data
@ -98,8 +103,8 @@ public class EchartsVo {
*/
@Data
@Builder
public static class YAxisVO {
private String type;
}
/**
@ -107,7 +112,6 @@ public class EchartsVo {
*/
@Data
@Builder
public static class SeriesVO {
/**
* name

@ -9,21 +9,18 @@ import lombok.NoArgsConstructor;
import java.util.List;
/**
* https://aisuda.bce.baidu.com/amis/zh-CN/components/timeline#timeline-item
*
* @author 3y
* 线 Vo
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TimeLineItemVo {
public class UserTimeLineVo {
/**
* items
*/
private List<TimeLineItemVo.ItemsVO> items;
private List<UserTimeLineVo.ItemsVO> items;
/**
* ItemsVO
@ -32,24 +29,27 @@ public class TimeLineItemVo {
@Builder
public static class ItemsVO {
/**
* time
* ID
*/
private String time;
private String businessId;
/**
* title
* title
*/
private String title;
/**
* detail
* detail
*/
private String detail;
/**
* color
*
*/
private String color;
private String sendType;
/**
* icon
*
*/
private String icon;
private String creator;
}
}
Loading…
Cancel
Save