1. 日志埋点,引入注解打印日志

2. 接入邮件渠道发送
pull/4/head
3y 3 years ago
parent a65e154bfd
commit dfa35752c2

@ -0,0 +1,42 @@
package com.java3y.austin.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set;
/**
*
* @author 3y
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AnchorInfo {
/**
*
*/
private Set<String> ids;
/**
*
*/
private int state;
/**
* Id(使)
* TaskInfoUtils
*/
private Long businessId;
/**
*
*/
private long timestamp;
}

@ -0,0 +1,34 @@
package com.java3y.austin.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*
* @author 3y
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LogParam {
/**
*
*/
private Object object;
/**
*
*/
private String bizType;
/**
*
*/
private long timestamp;
}

@ -26,7 +26,7 @@ public class TaskInfo {
/**
* Id(使)
*
* TaskInfoUtils
*/
private Long businessId;

@ -1,9 +1,28 @@
package com.java3y.austin.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 3y
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EmailContentModel extends ContentModel {
/**
*
*/
private String title;
/**
* (HTML)
*/
private String content;
}

@ -0,0 +1,31 @@
package com.java3y.austin.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
/**
*
*
* @author 3y
*/
@Getter
@ToString
@AllArgsConstructor
public enum AnchorState {
RECEIVE(10, "成功消费Kafka"),
DISCARD(20, "消费被丢弃"),
CONTENT_DEDUPLICATION(30, "消息被内容去重"),
RULE_DEDUPLICATION(40, "消息被频次去重"),
WHITE_LIST(50, "白名单过滤"),
SEND_SUCCESS(60, "消息下发成功"),
SEND_FAIL(70, "消息下发失败"),
;
private Integer code;
private String description;
}

@ -35,5 +35,11 @@
</exclusion>
</exclusions>
</dependency>
<!--邮件发送-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
</dependencies>
</project>

@ -1,5 +1,6 @@
package com.java3y.austin.domain;
import com.java3y.austin.enums.AnchorState;
import lombok.Builder;
import lombok.Data;
@ -28,4 +29,9 @@ public class DeduplicationParam {
*/
private Integer countNum;
/**
*
*/
private AnchorState anchorState;
}

@ -1,7 +1,18 @@
package com.java3y.austin.handler;
import cn.hutool.extra.mail.Mail;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.google.common.base.Throwables;
import com.java3y.austin.domain.AnchorInfo;
import com.java3y.austin.domain.TaskInfo;
import com.java3y.austin.dto.ContentModel;
import com.java3y.austin.dto.EmailContentModel;
import com.java3y.austin.enums.AnchorState;
import com.java3y.austin.enums.ChannelType;
import com.java3y.austin.utils.LogUtils;
import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
@ -10,6 +21,7 @@ import org.springframework.stereotype.Component;
* @author 3y
*/
@Component
@Slf4j
public class EmailHandler extends Handler {
public EmailHandler() {
@ -17,6 +29,40 @@ public class EmailHandler extends Handler {
}
@Override
public void handler(TaskInfo taskInfoList) {
public boolean handler(TaskInfo taskInfo) {
EmailContentModel emailContentModel = (EmailContentModel) taskInfo.getContentModel();
MailAccount account = getAccount();
try {
MailUtil.send(account, taskInfo.getReceiver(), emailContentModel.getTitle(),
emailContentModel.getContent(), true, null);
} catch (Exception e) {
log.error("EmailHandler#handler fail!{},params:{}", Throwables.getStackTraceAsString(e), taskInfo);
return false;
}
return true;
}
/**
*
* @return
*/
private MailAccount getAccount() {
MailAccount account = new MailAccount();
try {
account.setHost("smtp.qq.com").setPort(465);
account.setUser("403686131@qq.com").setPass("cmnznhomnbtlbggi").setAuth(true);
account.setFrom("403686131@qq.com");
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
account.setStarttlsEnable(true).setSslEnable(true).setCustomProperty("mail.smtp.ssl.socketFactory", sf);
account.setTimeout(25000).setConnectionTimeout(25000);
} catch (Exception e) {
log.error("EmailHandler#getAccount fail!{}", Throwables.getStackTraceAsString(e));
}
return account;
}
}

@ -1,6 +1,9 @@
package com.java3y.austin.handler;
import com.java3y.austin.domain.AnchorInfo;
import com.java3y.austin.domain.TaskInfo;
import com.java3y.austin.enums.AnchorState;
import com.java3y.austin.utils.LogUtils;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
@ -30,7 +33,10 @@ public abstract class Handler {
}
public void doHandler(TaskInfo taskInfo) {
handler(taskInfo);
if (!handler(taskInfo)) {
LogUtils.print(AnchorInfo.builder().state(AnchorState.SEND_FAIL.getCode()).businessId(taskInfo.getBusinessId()).ids(taskInfo.getReceiver()).build());
}
LogUtils.print(AnchorInfo.builder().state(AnchorState.SEND_SUCCESS.getCode()).businessId(taskInfo.getBusinessId()).ids(taskInfo.getReceiver()).build());
}
/**
@ -39,6 +45,6 @@ public abstract class Handler {
* @param taskInfo
* @return
*/
public abstract void handler(TaskInfo taskInfo);
public abstract boolean handler(TaskInfo taskInfo);
}

@ -2,13 +2,19 @@ package com.java3y.austin.handler;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import com.java3y.austin.dao.SmsRecordDao;
import com.java3y.austin.domain.AnchorInfo;
import com.java3y.austin.domain.SmsParam;
import com.java3y.austin.domain.SmsRecord;
import com.java3y.austin.domain.TaskInfo;
import com.java3y.austin.dto.SmsContentModel;
import com.java3y.austin.enums.AnchorState;
import com.java3y.austin.enums.ChannelType;
import com.java3y.austin.script.SmsScript;
import com.java3y.austin.utils.LogUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -20,6 +26,7 @@ import java.util.List;
* @author 3y
*/
@Component
@Slf4j
public class SmsHandler extends Handler {
public SmsHandler() {
@ -34,22 +41,26 @@ public class SmsHandler extends Handler {
@Override
public void handler(TaskInfo taskInfo) {
public boolean handler(TaskInfo taskInfo) {
SmsParam smsParam = SmsParam.builder()
.phones(taskInfo.getReceiver())
.content(getSmsContent(taskInfo))
.messageTemplateId(taskInfo.getMessageTemplateId())
.supplierId(10)
.supplierName("腾讯云通知类消息渠道").build();
List<SmsRecord> recordList = smsScript.send(smsParam);
if (!CollUtil.isEmpty(recordList)) {
smsRecordDao.saveAll(recordList);
try {
List<SmsRecord> recordList = smsScript.send(smsParam);
if (!CollUtil.isEmpty(recordList)) {
smsRecordDao.saveAll(recordList);
}
return true;
} catch (Exception e) {
log.error("SmsHandler#handler fail:{},params:{}",
Throwables.getStackTraceAsString(e), JSON.toJSONString(smsParam));
}
return false;
}
/**
*
* <p>

@ -1,10 +1,15 @@
package com.java3y.austin.receiver;
import cn.monitor4all.logRecord.annotation.OperationLog;
import com.alibaba.fastjson.JSON;
import com.java3y.austin.domain.AnchorInfo;
import com.java3y.austin.domain.LogParam;
import com.java3y.austin.domain.TaskInfo;
import com.java3y.austin.enums.AnchorState;
import com.java3y.austin.pending.Task;
import com.java3y.austin.pending.TaskPendingHolder;
import com.java3y.austin.utils.GroupIdMappingUtils;
import com.java3y.austin.utils.LogUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
@ -22,7 +27,7 @@ import java.util.Optional;
*/
@Slf4j
public class Receiver {
private static final String LOG_BIZ_TYPE = "Receiver#consumer";
@Autowired
private ApplicationContext context;
@ -33,6 +38,7 @@ public class Receiver {
public void consumer(ConsumerRecord<?, String> consumerRecord, @Header(KafkaHeaders.GROUP_ID) String topicGroupId) {
Optional<String> kafkaMessage = Optional.ofNullable(consumerRecord.value());
if (kafkaMessage.isPresent()) {
List<TaskInfo> TaskInfoLists = JSON.parseArray(kafkaMessage.get(), TaskInfo.class);
String messageGroupId = GroupIdMappingUtils.getGroupIdByTaskInfo(TaskInfoLists.get(0));
@ -41,13 +47,11 @@ public class Receiver {
*/
if (topicGroupId.equals(messageGroupId)) {
for (TaskInfo taskInfo : TaskInfoLists) {
LogUtils.print(LogParam.builder().bizType(LOG_BIZ_TYPE).object(taskInfo).build(), AnchorInfo.builder().ids(taskInfo.getReceiver()).businessId(taskInfo.getBusinessId()).state(AnchorState.RECEIVE.getCode()).build());
Task task = context.getBean(Task.class).setTaskInfo(taskInfo);
taskPendingHolder.route(topicGroupId).execute(task);
}
}
}
}
}

@ -2,6 +2,7 @@ package com.java3y.austin.script;
import com.java3y.austin.domain.SmsRecord;
import com.java3y.austin.domain.SmsParam;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import java.util.List;
@ -17,6 +18,6 @@ public interface SmsScript {
* @param smsParam
* @return
*/
List<SmsRecord> send(SmsParam smsParam);
List<SmsRecord> send(SmsParam smsParam) throws Exception;
}

@ -10,6 +10,7 @@ import com.java3y.austin.domain.SmsParam;
import com.java3y.austin.domain.SmsRecord;
import com.java3y.austin.enums.SmsStatus;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
@ -62,18 +63,13 @@ public class TencentSmsScript implements SmsScript {
private String SIGN_NAME;
@Override
public List<SmsRecord> send(SmsParam smsParam) {
try {
public List<SmsRecord> send(SmsParam smsParam) throws TencentCloudSDKException {
SmsClient client = init();
SendSmsRequest request = assembleReq(smsParam);
SendSmsResponse response = client.SendSms(request);
return assembleSmsRecord(smsParam,response);
} catch (Exception e) {
log.error("send tencent sms fail!{},params:{}",
Throwables.getStackTraceAsString(e), JSON.toJSONString(smsParam));
return null;
}
}
private List<SmsRecord> assembleSmsRecord(SmsParam smsParam, SendSmsResponse response) {

@ -2,8 +2,11 @@ package com.java3y.austin.service.deduplication;
import cn.hutool.core.collection.CollUtil;
import com.java3y.austin.constant.AustinConstant;
import com.java3y.austin.domain.AnchorInfo;
import com.java3y.austin.domain.DeduplicationParam;
import com.java3y.austin.domain.TaskInfo;
import com.java3y.austin.enums.AnchorState;
import com.java3y.austin.utils.LogUtils;
import com.java3y.austin.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -46,7 +49,10 @@ public abstract class AbstractDeduplicationService {
putInRedis(readyPutRedisReceiver, inRedisValue, param);
// 剔除符合去重条件的用户
taskInfo.getReceiver().removeAll(filterReceiver);
if (CollUtil.isNotEmpty(filterReceiver)) {
taskInfo.getReceiver().removeAll(filterReceiver);
LogUtils.print(AnchorInfo.builder().businessId(taskInfo.getBusinessId()).ids(filterReceiver).state(param.getAnchorState().getCode()).build());
}
}

@ -8,6 +8,7 @@ import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.java3y.austin.constant.AustinConstant;
import com.java3y.austin.domain.DeduplicationParam;
import com.java3y.austin.domain.TaskInfo;
import com.java3y.austin.enums.AnchorState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -48,6 +49,7 @@ public class DeduplicationRuleService {
DeduplicationParam contentParams = DeduplicationParam.builder()
.deduplicationTime(contentDeduplication.getLong(TIME))
.countNum(contentDeduplication.getInteger(NUM)).taskInfo(taskInfo)
.anchorState(AnchorState.CONTENT_DEDUPLICATION)
.build();
contentDeduplicationService.deduplication(contentParams);
@ -57,6 +59,7 @@ public class DeduplicationRuleService {
DeduplicationParam businessParams = DeduplicationParam.builder()
.deduplicationTime(seconds)
.countNum(frequencyDeduplication.getInteger(NUM)).taskInfo(taskInfo)
.anchorState(AnchorState.RULE_DEDUPLICATION)
.build();
frequencyDeduplicationService.deduplication(businessParams);
}

@ -5,7 +5,10 @@ import com.alibaba.fastjson.JSONArray;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.java3y.austin.constant.AustinConstant;
import com.java3y.austin.domain.AnchorInfo;
import com.java3y.austin.domain.TaskInfo;
import com.java3y.austin.enums.AnchorState;
import com.java3y.austin.utils.LogUtils;
import org.springframework.stereotype.Service;
/**
@ -28,6 +31,7 @@ public class DiscardMessageService {
JSONArray array = JSON.parseArray(config.getProperty(DISCARD_MESSAGE_KEY,
AustinConstant.APOLLO_DEFAULT_VALUE_JSON_ARRAY));
if (array.contains(String.valueOf(taskInfo.getMessageTemplateId()))) {
LogUtils.print(AnchorInfo.builder().businessId(taskInfo.getBusinessId()).ids(taskInfo.getReceiver()).state(AnchorState.DISCARD.getCode()).build());
return true;
}
return false;

@ -118,6 +118,12 @@ public class AssembleAction implements BusinessProcess {
}
}
// 如果 url 字段存在则在url拼接对应的埋点参数
String url = (String) ReflectUtil.getFieldValue(contentModel, "url");
if (StrUtil.isNotBlank(url)) {
String resultUrl = TaskInfoUtils.generateUrl(url, messageTemplate.getId(), messageTemplate.getTemplateType());
ReflectUtil.setFieldValue(contentModel, "url", resultUrl);
}
return contentModel;
}
}

@ -1,5 +1,6 @@
package com.java3y.austin.service;
import cn.monitor4all.logRecord.annotation.OperationLog;
import com.java3y.austin.domain.BatchSendRequest;
import com.java3y.austin.domain.SendRequest;
import com.java3y.austin.domain.SendResponse;
@ -23,6 +24,7 @@ public class SendServiceImpl implements SendService {
private ProcessController processController;
@Override
@OperationLog(bizType = "SendService#send", bizId = "#sendRequest.messageTemplateId", msg = "#sendRequest")
public SendResponse send(SendRequest sendRequest) {
SendTaskModel sendTaskModel = SendTaskModel.builder()
@ -42,6 +44,7 @@ public class SendServiceImpl implements SendService {
}
@Override
@OperationLog(bizType = "SendService#batchSend", bizId = "#batchSendRequest.messageTemplateId", msg = "#batchSendRequest")
public SendResponse batchSend(BatchSendRequest batchSendRequest) {
SendTaskModel sendTaskModel = SendTaskModel.builder()
.messageTemplateId(batchSendRequest.getMessageTemplateId())

@ -69,7 +69,10 @@
</dependency>
<dependency>
<groupId>cn.monitor4all</groupId>
<artifactId>log-record-starter</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,51 @@
package com.java3y.austin.utils;
import cn.monitor4all.logRecord.bean.LogDTO;
import cn.monitor4all.logRecord.service.CustomLogListener;
import com.alibaba.fastjson.JSON;
import com.java3y.austin.domain.AnchorInfo;
import com.java3y.austin.domain.LogParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
*
*/
@Slf4j
@Component
public class LogUtils extends CustomLogListener {
/**
* @OperationLog
*/
@Override
public void createLog(LogDTO logDTO) throws Exception {
log.info(JSON.toJSONString(logDTO));
}
/**
*
*/
public static void print(LogParam logParam) {
logParam.setTimestamp(System.currentTimeMillis());
log.info(JSON.toJSONString(logParam));
}
/**
*
*/
public static void print(AnchorInfo anchorInfo) {
anchorInfo.setTimestamp(System.currentTimeMillis());
log.info(JSON.toJSONString(anchorInfo));
}
/**
*
*/
public static void print(LogParam logParam,AnchorInfo anchorInfo) {
print(anchorInfo);
print(logParam);
}
}

@ -24,4 +24,17 @@ public class TaskInfoUtils {
return Long.valueOf(String.format("%d%s", templateType * TYPE_FLAG + templateId, today));
}
/**
* url)
*/
public static String generateUrl(String url, Long templateId, Integer templateType) {
url = url.trim();
Long businessId = generateBusinessId(templateId, templateType);
if (url.indexOf('?') == -1) {
return url + "?track_code_bid=" + businessId;
} else {
return url + "&track_code_bid=" + businessId;
}
}
}

@ -12,7 +12,6 @@ public class AustinApplication {
public static void main(String[] args) {
// TODO apollo的地址
//System.setProperty("apollo.config-service", "http://ip:7000");
SpringApplication.run(AustinApplication.class, args);
}
}

@ -28,16 +28,16 @@ public class MessageTemplateController {
public String insert() {
MessageTemplate messageTemplate = MessageTemplate.builder()
.name("test短信")
.name("test邮件")
.auditStatus(10)
.flowId("yyyy")
.msgStatus(10)
.idType(10)
.sendChannel(10)
.templateType(10)
.idType(50)
.sendChannel(40)
.templateType(20)
.msgType(10)
.expectPushTime("0")
.msgContent("3333333m")
.msgContent("{\"content\":\"{$contentValue}\",\"title\":\"{$title}\"}")
.sendAccount(66)
.creator("yyyyc")
.updator("yyyyu")

@ -24,12 +24,10 @@ public class SendController {
/**
*
*
* @param phone
* @return
*/
@GetMapping("/sendSmsTest")
public SendResponse sendSmsTest(String phone, Long templateId) {
public SendResponse sendSmsTest(String receiver, Long templateId) {
/**
*
@ -39,11 +37,11 @@ public class SendController {
* messageTemplate Id 2
* {"auditStatus":10,"auditor":"yyyyyyz","created":1636978066,"creator":"yyyyc","deduplicationTime":1,"expectPushTime":"0","flowId":"yyyy","id":1,"idType":30,"isDeleted":0,"isNightShield":0,"msgContent":"{\"content\":\"{$contentValue}\"}","msgStatus":10,"msgType":20,"name":"test短信","proposer":"yyyy22","sendAccount":66,"sendChannel":30,"team":"yyyt","templateType":10,"updated":1636978066,"updator":"yyyyu"}
*/
// 文案参数
Map<String, String> variables = new HashMap<>(8);
variables.put("contentValue", "6666");
MessageParam messageParam = new MessageParam().setReceiver(phone).setVariables(variables);
variables.put("contentValue", "6666" + System.currentTimeMillis());
variables.put("title", "yyyyyy");
MessageParam messageParam = new MessageParam().setReceiver(receiver).setVariables(variables);
SendRequest sendRequest = new SendRequest().setCode(BusinessCode.COMMON_SEND.getCode())

@ -81,6 +81,21 @@
<artifactId>apollo-client-config-data</artifactId>
<version>1.9.1</version>
</dependency>
<!--注解打印日志-->
<dependency>
<groupId>cn.monitor4all</groupId>
<artifactId>log-record-starter</artifactId>
<version>1.0.4</version>
</dependency>
<!--邮件发送-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
</dependencyManagement>

Loading…
Cancel
Save