亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用AOP實現系統(tǒng)告警的方法詳解

 更新時間:2022年09月19日 09:24:43   作者:知了一笑  
在開發(fā)的過程中會遇到各種各樣的開發(fā)問題,服務器宕機、網絡抖動、代碼本身的bug等等。針對代碼的bug,我們可以提前預支,通過發(fā)送告警信息來警示我們去干預,盡早處理。本文將利用AOP實現系統(tǒng)告警,需要的可以參考一下

一、業(yè)務背景

在開發(fā)的過程中會遇到各種各樣的開發(fā)問題,服務器宕機、網絡抖動、代碼本身的bug等等。針對代碼的bug,我們可以提前預支,通過發(fā)送告警信息來警示我們去干預,盡早處理。

二、告警的方式

1、釘釘告警

通過在企業(yè)釘釘群,添加群機器人的方式,通過機器人向群內發(fā)送報警信息。至于釘釘機器人怎么創(chuàng)建,發(fā)送消息的api等等,請參考官方文檔

2、企業(yè)微信告警

同樣的套路,企業(yè)微信也是,在企業(yè)微信群中,添加群機器人。通過機器人發(fā)送告警信息。具體請看官方文檔

3、郵件告警

與上述不同的是,郵件是發(fā)送給個人的,當然也可以是批量發(fā)送,只實現了發(fā)送文本格式的方式,至于markdown格式,有待考察。郵件發(fā)送相對比較簡單,這里就不展開贅述。

三、源碼解析

1、Alarm自定義注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public?@interface?Alarm?{

????/**
?????*?報警標題
?????*
?????*?@return?String
?????*/
????String?title()?default?"";

????/**
?????*?發(fā)送報警格式:目前支持text,markdown
?????*?@return
?????*/
????MessageTye?messageType()?default?MessageTye.TEXT;

????/**
?????*?告警模板id
?????*?@return
?????*/
????String?templateId()?default?"";

????/**
?????*?成功是否通知:true-通知,false-不通知
?????*?@return
?????*/
????boolean?successNotice()?default?false;
}

1.1、注解使用

@Alarm標記在方法上使用,被標記的方法發(fā)生異常,會根據配置,讀取配置信息,發(fā)送異常堆棧信息。使用方法如下所示:

@Alarm(title?=?"某某業(yè)務告警",?messageType?=?MessageTye.MARKDOWN,?templateId?=?"errorTemp")

1.2、注解字段解析

title

告警消息標題:可以定義為業(yè)務信息,如導師身份計算

messageType

告警消息展示類型:目前支持text文本類型,markdown類型

templateId

消息模板id:與配置文件中配置的模板id一致

successNotice

正常情況是否也需要發(fā)送告警信息,默認值是fasle,表示不需要發(fā)送。當然,有些業(yè)務場景正常情況也需要發(fā)送,比如:支付出單通知等。

2、配置文件分析

2.1、釘釘配置文件

spring:
??alarm:
????dingtalk:
?????#?開啟釘釘發(fā)送告警
??????enabled:?true
?????#?釘釘群機器人唯一的token
??????token:?xxxxxx
?????#?安全設置:加簽的密鑰
??????secret:?xxxxxxx

2.2、企業(yè)微信配置文件

spring:
??alarm:
????wechat:
?????#?開啟企業(yè)微信告警
??????enabled:?true
?????#?企業(yè)微信群機器人唯一key
??????key:?xxxxxdsf
?????#?被@人的手機號
??????to-user:?1314243

2.3、郵件配置文件

spring:
??alarm:????
????mail:
??????enabled:?true
??????smtpHost:?xxx@qq.com
??????smtpPort:?22
??????to:?xxx@qq.com
??????from:?132@qq.com
??????username:?wsrf
??????password:?xxx

2.4、自定義模板配置

spring:
??alarm:
????template:
??????#?開啟通過模板配置
??????enabled:?true
??????#?配置模板來源為文件
??????source:?FILE
??????#?配置模板數據
??????templates:
????????errorTemp:
??????????templateId:?errorTemp
??????????templateName:?服務異常模板
??????????templateContent:?這里是配置模板的內容
  • spring:alarm:template:enabled,Boolean類型,表示開啟告警消息使用模板發(fā)送。
  • spring:alarm:template:source,模板來源,枚舉類:JDBC(數據庫)、FILE(配置文件)、MEMORY(內存),目前只支持FILE,其他兩種可自行擴展。
  • spring:alarm:template:templates,配置模板內容,是一個map,errorTemp是模板id,需要使用哪種模板,就在@Alarm中的templateId設置為對應配置文件中的templateId。

3、核心AOP分析

3.1、原理分析

3.2、自定義切面

@Aspect
@Slf4j
@RequiredArgsConstructor
public?class?AlarmAspect?{
????private?final?AlarmTemplateProvider?alarmTemplateProvider;

????private?final?static?String?ERROR_TEMPLATE?=?"\n\n<font?color=\"#F37335\">異常信息:</font>\n"?+
????????????"```java\n"?+
????????????"#{[exception]}\n"?+
????????????"```\n";

????private?final?static?String?TEXT_ERROR_TEMPLATE?=?"\n異常信息:\n"?+
????????????"#{[exception]}";

????private?final?static?String?MARKDOWN_TITLE_TEMPLATE?=?"#?【#{[title]}】\n"?+
????????????"\n請求狀態(tài):<font color=\"#{[stateColor]}\">#{[state]}</font>\n\n";

????private?final?static?String?TEXT_TITLE_TEMPLATE?=?"【#{[title]}】\n"?+
????????????"請求狀態(tài):#{[state]}\n";

????@Pointcut("@annotation(alarm)")
????public?void?alarmPointcut(Alarm?alarm)?{

????}

????@Around(value?=?"alarmPointcut(alarm)",?argNames?=?"joinPoint,alarm")
????public?Object?around(ProceedingJoinPoint?joinPoint,?Alarm?alarm)?throws?Throwable?{
????????Object?result?=?joinPoint.proceed();
????????if?(alarm.successNotice())?{
????????????String?templateId?=?alarm.templateId();
????????????String?fileTemplateContent?=?"";
????????????if?(Objects.nonNull(alarmTemplateProvider))?{
????????????????AlarmTemplate?alarmTemplate?=?alarmTemplateProvider.loadingAlarmTemplate(templateId);
????????????????fileTemplateContent?=?alarmTemplate.getTemplateContent();
????????????}
????????????String?templateContent?=?"";
????????????MessageTye?messageTye?=?alarm.messageType();
????????????if?(messageTye.equals(MessageTye.TEXT))?{
????????????????templateContent?=?TEXT_TITLE_TEMPLATE.concat(fileTemplateContent);
????????????}?else?if?(messageTye.equals(MessageTye.MARKDOWN))?{
????????????????templateContent?=?MARKDOWN_TITLE_TEMPLATE.concat(fileTemplateContent);
????????????}
????????????Map<String,?Object>?alarmParamMap?=?new?HashMap<>();
????????????alarmParamMap.put("title",?alarm.title());
????????????alarmParamMap.put("stateColor",?"#45B649");
????????????alarmParamMap.put("state",?"成功");
????????????sendAlarm(alarm,?templateContent,?alarmParamMap);
????????}
????????return?result;
????}


????@AfterThrowing(pointcut?=?"alarmPointcut(alarm)",?argNames?=?"joinPoint,alarm,e",?throwing?=?"e")
????public?void?doAfterThrow(JoinPoint?joinPoint,?Alarm?alarm,?Exception?e)?{
????????log.info("請求接口發(fā)生異常?:?[{}]",?e.getMessage());
????????String?templateId?=?alarm.templateId();
????????//?加載模板中配置的內容,若有
????????String?templateContent?=?"";
????????String?fileTemplateContent?=?"";
????????if?(Objects.nonNull(alarmTemplateProvider))?{
????????????AlarmTemplate?alarmTemplate?=?alarmTemplateProvider.loadingAlarmTemplate(templateId);
????????????fileTemplateContent?=?alarmTemplate.getTemplateContent();
????????}
????????MessageTye?messageTye?=?alarm.messageType();
????????if?(messageTye.equals(MessageTye.TEXT))?{
????????????templateContent?=?TEXT_TITLE_TEMPLATE.concat(fileTemplateContent).concat(TEXT_ERROR_TEMPLATE);
????????}?else?if?(messageTye.equals(MessageTye.MARKDOWN))?{
????????????templateContent?=?MARKDOWN_TITLE_TEMPLATE.concat(fileTemplateContent).concat(ERROR_TEMPLATE);
????????}
????????Map<String,?Object>?alarmParamMap?=?new?HashMap<>();
????????alarmParamMap.put("title",?alarm.title());
????????alarmParamMap.put("stateColor",?"#FF4B2B");
????????alarmParamMap.put("state",?"失敗");
????????alarmParamMap.put("exception",?ExceptionUtil.stacktraceToString(e));
????????sendAlarm(alarm,?templateContent,?alarmParamMap);
????}

????private?void?sendAlarm(Alarm?alarm,?String?templateContent,?Map<String,?Object>?alarmParamMap)?{
????????ExpressionParser?parser?=?new?SpelExpressionParser();
????????TemplateParserContext?parserContext?=?new?TemplateParserContext();
????????String?message?=?parser.parseExpression(templateContent,?parserContext).getValue(alarmParamMap,?String.class);
????????MessageTye?messageTye?=?alarm.messageType();
????????NotifyMessage?notifyMessage?=?new?NotifyMessage();
????????notifyMessage.setTitle(alarm.title());
????????notifyMessage.setMessageTye(messageTye);
????????notifyMessage.setMessage(message);
????????AlarmFactoryExecute.execute(notifyMessage);
????}
}

4、模板提供器

4.1、AlarmTemplateProvider

定義一個抽象接口AlarmTemplateProvider,用于被具體的子類實現

public?interface?AlarmTemplateProvider?{


????/**
?????*?加載告警模板
?????*
?????*?@param?templateId?模板id
?????*?@return?AlarmTemplate
?????*/
????AlarmTemplate?loadingAlarmTemplate(String?templateId);
}

4.2、BaseAlarmTemplateProvider

抽象類BaseAlarmTemplateProvider實現該抽象接口

public?abstract?class?BaseAlarmTemplateProvider?implements?AlarmTemplateProvider?{

????@Override
????public?AlarmTemplate?loadingAlarmTemplate(String?templateId)?{
????????if?(StringUtils.isEmpty(templateId))?{
????????????throw?new?AlarmException(400,?"告警模板配置id不能為空");
????????}
????????return?getAlarmTemplate(templateId);
????}

????/**
?????*?查詢告警模板
?????*
?????*?@param?templateId?模板id
?????*?@return?AlarmTemplate
?????*/
????abstract?AlarmTemplate?getAlarmTemplate(String?templateId);
}

4.3、YamlAlarmTemplateProvider

具體實現類YamlAlarmTemplateProvider,實現從配置文件中讀取模板,該類在項目啟動時,會被加載進spring的bean容器

@RequiredArgsConstructor
public?class?YamlAlarmTemplateProvider?extends?BaseAlarmTemplateProvider?{

????private?final?TemplateConfig?templateConfig;

????@Override
????AlarmTemplate?getAlarmTemplate(String?templateId)?{
????????Map<String,?AlarmTemplate>?configTemplates?=?templateConfig.getTemplates();
????????AlarmTemplate?alarmTemplate?=?configTemplates.get(templateId);
????????if?(ObjectUtils.isEmpty(alarmTemplate))?{
????????????throw?new?AlarmException(400,?"未發(fā)現告警配置模板");
????????}
????????return?alarmTemplate;
????}
}

4.4、MemoryAlarmTemplateProvider和JdbcAlarmTemplateProvider

抽象類BaseAlarmTemplateProvider還有其他兩個子類,分別是MemoryAlarmTemplateProviderJdbcAlarmTemplateProvider。但是這兩個子類暫時還未實現邏輯,后續(xù)可以自行擴展。

@RequiredArgsConstructor
public?class?MemoryAlarmTemplateProvider?extends?BaseAlarmTemplateProvider?{

????private?final?Function<String,?AlarmTemplate>?function;
????@Override
????AlarmTemplate?getAlarmTemplate(String?templateId)?{
????????AlarmTemplate?alarmTemplate?=?function.apply(templateId);
????????if?(ObjectUtils.isEmpty(alarmTemplate))?{
????????????throw?new?AlarmException(400,?"未發(fā)現告警配置模板");
????????}
????????return?alarmTemplate;
????}
}
@RequiredArgsConstructor
public?class?JdbcAlarmTemplateProvider?extends?BaseAlarmTemplateProvider?{

????private?final?Function<String,?AlarmTemplate>?function;

????@Override
????AlarmTemplate?getAlarmTemplate(String?templateId)?{
????????AlarmTemplate?alarmTemplate?=?function.apply(templateId);
????????if?(ObjectUtils.isEmpty(alarmTemplate))?{
????????????throw?new?AlarmException(400,?"未發(fā)現告警配置模板");
????????}
????????return?alarmTemplate;
????}
}

兩個類中都有Function<String, AlarmTemplate>接口,為函數式接口,可以供外部自行去實現邏輯。

5、告警發(fā)送

5.1、AlarmFactoryExecute

該類內部保存了一個容器,主要用于緩存真正的發(fā)送類

public?class?AlarmFactoryExecute?{

????private?static?List<AlarmWarnService>?serviceList?=?new?ArrayList<>();

????public?AlarmFactoryExecute(List<AlarmWarnService>?alarmLogWarnServices)?{
????????serviceList?=?alarmLogWarnServices;
????}

????public?static?void?addAlarmLogWarnService(AlarmWarnService?alarmLogWarnService)?{
????????serviceList.add(alarmLogWarnService);
????}

????public?static?List<AlarmWarnService>?getServiceList()?{
????????return?serviceList;
????}

????public?static?void?execute(NotifyMessage?notifyMessage)?{
????????for?(AlarmWarnService?alarmWarnService?:?getServiceList())?{
????????????alarmWarnService.send(notifyMessage);
????????}
????}
}

5.2、AlarmWarnService

抽象接口,只提供一個發(fā)送的方法

public?interface?AlarmWarnService?{

????/**
?????*?發(fā)送信息
?????*
?????*?@param?notifyMessage?message
?????*/
????void?send(NotifyMessage?notifyMessage);

}

5.3、BaseWarnService

與抽象的模板提供器AlarmTemplateProvider一樣的套路,該接口有一個抽象的實現類BaseWarnService,該類對外暴露send方法,用于發(fā)送消息,內部用doSendMarkdown,doSendText方法實現具體的發(fā)送邏輯,當然具體發(fā)送邏輯還是得由其子類去實現。

@Slf4j
public?abstract?class?BaseWarnService?implements?AlarmWarnService?{

????@Override
????public?void?send(NotifyMessage?notifyMessage)?{
????????if?(notifyMessage.getMessageTye().equals(MessageTye.TEXT))?{
????????????CompletableFuture.runAsync(()?->?{
????????????????try?{
????????????????????doSendText(notifyMessage.getMessage());
????????????????}?catch?(Exception?e)?{
????????????????????log.error("send?text?warn?message?error",?e);
????????????????}
????????????});
????????}?else?if?(notifyMessage.getMessageTye().equals(MessageTye.MARKDOWN))?{
????????????CompletableFuture.runAsync(()?->?{
????????????????try?{
????????????????????doSendMarkdown(notifyMessage.getTitle(),?notifyMessage.getMessage());
????????????????}?catch?(Exception?e)?{
????????????????????log.error("send?markdown?warn?message?error",?e);
????????????????}
????????????});
????????}
?}

????/**
?????*?發(fā)送Markdown消息
?????*
?????*?@param?title???Markdown標題
?????*?@param?message?Markdown消息
?????*?@throws?Exception?異常
?????*/
????protected?abstract?void?doSendMarkdown(String?title,?String?message)?throws?Exception;

????/**
?????*?發(fā)送文本消息
?????*
?????*?@param?message?文本消息
?????*?@throws?Exception?異常
?????*/
????protected?abstract?void?doSendText(String?message)?throws?Exception;
}

5.4、DingTalkWarnService

主要實現了釘釘發(fā)送告警信息的邏輯

@Slf4j
public?class?DingTalkWarnService?extends?BaseWarnService?{

????private?static?final?String?ROBOT_SEND_URL?=?"https://oapi.dingtalk.com/robot/send?access_token=";
????private?final?String?token;

????private?final?String?secret;

????public?DingTalkWarnService(String?token,?String?secret)?{
????????this.token?=?token;
????????this.secret?=?secret;
????}

????public?void?sendRobotMessage(DingTalkSendRequest?dingTalkSendRequest)?throws?Exception?{
????????String?json?=?JSONUtil.toJsonStr(dingTalkSendRequest);
????????String?sign?=?getSign();
????????String?body?=?HttpRequest.post(sign).contentType(ContentType.JSON.getValue()).body(json).execute().body();
????????log.info("釘釘機器人通知結果:{}",?body);
????}

????/**
?????*?獲取簽名
?????*
?????*?@return?返回簽名
?????*/
????private?String?getSign()?throws?Exception?{
????????long?timestamp?=?System.currentTimeMillis();
????????String?stringToSign?=?timestamp?+?"\n"?+?secret;
????????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?ROBOT_SEND_URL?+?token?+?"&timestamp="?+?timestamp?+?"&sign="?+?URLEncoder.encode(new?String(Base64.getEncoder().encode(signData)),?StandardCharsets.UTF_8.toString());
????}

????@Override
????protected?void?doSendText(String?message)?throws?Exception?{
????????DingTalkSendRequest?param?=?new?DingTalkSendRequest();
????????param.setMsgtype(DingTalkSendMsgTypeEnum.TEXT.getType());
????????param.setText(new?DingTalkSendRequest.Text(message));
????????sendRobotMessage(param);
????}

????@Override
????protected?void?doSendMarkdown(String?title,?String?message)?throws?Exception?{
????????DingTalkSendRequest?param?=?new?DingTalkSendRequest();
????????param.setMsgtype(DingTalkSendMsgTypeEnum.MARKDOWN.getType());
????????DingTalkSendRequest.Markdown?markdown?=?new?DingTalkSendRequest.Markdown(title,?message);
????????param.setMarkdown(markdown);
????????sendRobotMessage(param);
????}
}

5.5、WorkWeXinWarnService

主要實現了發(fā)送企業(yè)微信告警信息的邏輯

@Slf4j
public?class?WorkWeXinWarnService?extends?BaseWarnService?{
????private?static?final?String?SEND_MESSAGE_URL?=?"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s";
????private?final?String?key;

????private?final?String?toUser;

????public?WorkWeXinWarnService(String?key,?String?toUser)?{
????????this.key?=?key;
????????this.toUser?=?toUser;
????}

????private?String?createPostData(WorkWeXinSendMsgTypeEnum?messageTye,?String?contentValue)?{
????????WorkWeXinSendRequest?wcd?=?new?WorkWeXinSendRequest();
????????wcd.setMsgtype(messageTye.getType());
????????List<String>?toUsers?=?Arrays.asList("@all");
????????if?(StringUtils.isNotEmpty(toUser))?{
????????????String[]?split?=?toUser.split("\\|");
????????????toUsers?=?Arrays.asList(split);
????????}
????????if?(messageTye.equals(WorkWeXinSendMsgTypeEnum.TEXT))?{
????????????WorkWeXinSendRequest.Text?text?=?new?WorkWeXinSendRequest.Text(contentValue,?toUsers);
????????????wcd.setText(text);
????????}?else?if?(messageTye.equals(WorkWeXinSendMsgTypeEnum.MARKDOWN))?{
????????????WorkWeXinSendRequest.Markdown?markdown?=?new?WorkWeXinSendRequest.Markdown(contentValue,?toUsers);
????????????wcd.setMarkdown(markdown);
????????}
????????return?JSONUtil.toJsonStr(wcd);
????}

????@Override
????protected?void?doSendText(String?message)?{
????????String?data?=?createPostData(WorkWeXinSendMsgTypeEnum.TEXT,?message);
????????String?url?=?String.format(SEND_MESSAGE_URL,?key);
????????String?resp?=?HttpRequest.post(url).body(data).execute().body();
????????log.info("send?work?weixin?message?call?[{}],?param:{},?resp:{}",?url,?data,?resp);
????}

????@Override
????protected?void?doSendMarkdown(String?title,?String?message)?{
????????String?data?=?createPostData(WorkWeXinSendMsgTypeEnum.MARKDOWN,?message);
????????String?url?=?String.format(SEND_MESSAGE_URL,?key);
????????String?resp?=?HttpRequest.post(url).body(data).execute().body();
????????log.info("send?work?weixin?message?call?[{}],?param:{},?resp:{}",?url,?data,?resp);
????}
}

5.6、MailWarnService

主要實現郵件告警邏輯

@Slf4j
public?class?MailWarnService?extends?BaseWarnService?{

????private?final?String?smtpHost;

????private?final?String?smtpPort;

????private?final?String?to;

????private?final?String?from;

????private?final?String?username;

????private?final?String?password;

????private?Boolean?ssl?=?true;

????private?Boolean?debug?=?false;

????public?MailWarnService(String?smtpHost,?String?smtpPort,?String?to,?String?from,?String?username,?String?password)?{
????????this.smtpHost?=?smtpHost;
????????this.smtpPort?=?smtpPort;
????????this.to?=?to;
????????this.from?=?from;
????????this.username?=?username;
????????this.password?=?password;
????}

????public?void?setSsl(Boolean?ssl)?{
????????this.ssl?=?ssl;
????}

????public?void?setDebug(Boolean?debug)?{
????????this.debug?=?debug;
????}

????@Override
????protected?void?doSendText(String?message)?throws?Exception?{
????????Properties?props?=?new?Properties();
????????props.setProperty("mail.smtp.auth",?"true");
????????props.setProperty("mail.transport.protocol",?"smtp");
????????props.setProperty("mail.smtp.host",?smtpHost);
????????props.setProperty("mail.smtp.port",?smtpPort);
????????props.put("mail.smtp.ssl.enable",?true);
????????Session?session?=?Session.getInstance(props);
????????session.setDebug(false);
????????MimeMessage?msg?=?new?MimeMessage(session);
????????msg.setFrom(new?InternetAddress(from));
????????for?(String?toUser?:?to.split(","))?{
????????????msg.setRecipient(MimeMessage.RecipientType.TO,?new?InternetAddress(toUser));
????????}
????????Map<String,?String>?map?=?JSONUtil.toBean(message,?Map.class);
????????msg.setSubject(map.get("subject"),?"UTF-8");
????????msg.setContent(map.get("content"),?"text/html;charset=UTF-8");
????????msg.setSentDate(new?Date());
????????Transport?transport?=?session.getTransport();
????????transport.connect(username,?password);
????????transport.sendMessage(msg,?msg.getAllRecipients());
????????transport.close();
????}

????@Override
????protected?void?doSendMarkdown(String?title,?String?message)?throws?Exception?{
????????log.warn("暫不支持發(fā)送Markdown郵件");
????}
}

6、AlarmAutoConfiguration自動裝配類

運用了springboot自定義的starter,再META-INF包下的配置文件spring.factories下,配置上該類

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
????com.seven.buttemsg.autoconfigure.AlarmAutoConfiguration

自動裝配類,用于裝載自定義的bean

@Slf4j
@Configuration
public?class?AlarmAutoConfiguration?{

????//?郵件相關配置裝載
????@Configuration
????@ConditionalOnProperty(prefix?=?MailConfig.PREFIX,?name?=?"enabled",?havingValue?=?"true")
????@EnableConfigurationProperties(MailConfig.class)
????static?class?MailWarnServiceMethod?{

????????@Bean
????????@ConditionalOnMissingBean(MailWarnService.class)
????????public?MailWarnService?mailWarnService(final?MailConfig?mailConfig)?{
????????????MailWarnService?mailWarnService?=?new?MailWarnService(mailConfig.getSmtpHost(),?mailConfig.getSmtpPort(),?mailConfig.getTo(),?mailConfig.getFrom(),?mailConfig.getUsername(),?mailConfig.getPassword());
????????????mailWarnService.setSsl(mailConfig.getSsl());
????????????mailWarnService.setDebug(mailConfig.getDebug());
????????????AlarmFactoryExecute.addAlarmLogWarnService(mailWarnService);
????????????return?mailWarnService;
????????}
????}

????//?企業(yè)微信相關配置裝載
????@Configuration
????@ConditionalOnProperty(prefix?=?WorkWeXinConfig.PREFIX,?name?=?"enabled",?havingValue?=?"true")
????@EnableConfigurationProperties(WorkWeXinConfig.class)
????static?class?WorkWechatWarnServiceMethod?{

????????@Bean
????????@ConditionalOnMissingBean(MailWarnService.class)
????????public?WorkWeXinWarnService?workWechatWarnService(final?WorkWeXinConfig?workWeXinConfig)?{
????????????return?new?WorkWeXinWarnService(workWeXinConfig.getKey(),?workWeXinConfig.getToUser());
????????}

????????@Autowired
????????void?setDataChangedListener(WorkWeXinWarnService?workWeXinWarnService)?{
????????????AlarmFactoryExecute.addAlarmLogWarnService(workWeXinWarnService);
????????}
????}

????//?釘釘相關配置裝載
????@Configuration
????@ConditionalOnProperty(prefix?=?DingTalkConfig.PREFIX,?name?=?"enabled",?havingValue?=?"true")
????@EnableConfigurationProperties(DingTalkConfig.class)
????static?class?DingTalkWarnServiceMethod?{

????????@Bean
????????@ConditionalOnMissingBean(DingTalkWarnService.class)
????????public?DingTalkWarnService?dingTalkWarnService(final?DingTalkConfig?dingtalkConfig)?{
????????????DingTalkWarnService?dingTalkWarnService?=?new?DingTalkWarnService(dingtalkConfig.getToken(),?dingtalkConfig.getSecret());
????????????AlarmFactoryExecute.addAlarmLogWarnService(dingTalkWarnService);
????????????return?dingTalkWarnService;
????????}
????}

????//?消息模板配置裝載
????@Configuration
????@ConditionalOnProperty(prefix?=?TemplateConfig.PREFIX,?name?=?"enabled",?havingValue?=?"true")
????@EnableConfigurationProperties(TemplateConfig.class)
????static?class?TemplateConfigServiceMethod?{

????????@Bean
????????@ConditionalOnMissingBean
????????public?AlarmTemplateProvider?alarmTemplateProvider(TemplateConfig?templateConfig)?{
????????????if?(TemplateSource.FILE?==?templateConfig.getSource())?{
????????????????return?new?YamlAlarmTemplateProvider(templateConfig);
????????????}?else?if?(TemplateSource.JDBC?==?templateConfig.getSource())?{
????????????????//?數據庫(如mysql)讀取文件,未實現,可自行擴展
????????????????return?new?JdbcAlarmTemplateProvider(templateId?->?null);
????????????}?else?if?(TemplateSource.MEMORY?==?templateConfig.getSource())?{
????????????????//?內存(如redis,本地內存)讀取文件,未實現,可自行擴展
????????????????return?new?MemoryAlarmTemplateProvider(templateId?->?null);
????????????}
????????????return?new?YamlAlarmTemplateProvider(templateConfig);
????????}


????}
????@Bean
????public?AlarmAspect?alarmAspect(@Autowired(required?=?false)?AlarmTemplateProvider?alarmTemplateProvider)?{
????????return?new?AlarmAspect(alarmTemplateProvider);
????}
}

四、總結

主要借助spring的切面技術,以及springboot的自動裝配原理,實現了發(fā)送告警邏輯。對業(yè)務代碼無侵入,只需要在業(yè)務代碼上標記注解,就可實現可插拔的功能,比較輕量。

以上就是利用AOP實現系統(tǒng)告警的方法詳解的詳細內容,更多關于AOP系統(tǒng)告警的資料請關注腳本之家其它相關文章!

相關文章

  • 使用spring的restTemplate注意點

    使用spring的restTemplate注意點

    這篇文章主要介紹了使用spring的restTemplate注意點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringCloud OpenFeign基本介紹與實現示例

    SpringCloud OpenFeign基本介紹與實現示例

    OpenFeign源于Netflix的Feign,是http通信的客戶端。屏蔽了網絡通信的細節(jié),直接面向接口的方式開發(fā),讓開發(fā)者感知不到網絡通信細節(jié)。所有遠程調用,都像調用本地方法一樣完成
    2023-02-02
  • Springboot基于BCrypt非對稱加密字符串的實現

    Springboot基于BCrypt非對稱加密字符串的實現

    本文主要介紹了Springboot基于BCrypt非對稱加密字符串的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • 淺析Java ClassName.this中類名.this關鍵字的理解

    淺析Java ClassName.this中類名.this關鍵字的理解

    Java ClassName.this中類名.this關鍵字 的理解大家都了解多少,有不太了解的朋友可以參考下本文一起學習學習
    2016-05-05
  • Java中的權重算法(如Dubbo的負載均衡權重)詳解

    Java中的權重算法(如Dubbo的負載均衡權重)詳解

    這篇文章主要介紹了Java中的權重算法(如Dubbo的負載均衡權重)詳解,負載均衡,其含義就是指將負載進行平衡、分攤到多個操作單元上進行運行,例如FTP服務器、Web服務器、企業(yè)核心應用服務器和其它主要任務服務器等,從而協同完成工作任務,需要的朋友可以參考下
    2023-08-08
  • 使用list stream:對List中的對象先進行排序再獲取前n個對象

    使用list stream:對List中的對象先進行排序再獲取前n個對象

    這篇文章主要介紹了使用list stream:對List中的對象先進行排序再獲取前n個對象,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 解決springboot項目上傳文件出現臨時文件目錄為空的問題

    解決springboot項目上傳文件出現臨時文件目錄為空的問題

    這篇文章主要介紹了解決springboot項目上傳文件出現臨時文件目錄為空的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 如何解決SpringBoot定時任務報錯Unexpected error occurred in scheduled task問題

    如何解決SpringBoot定時任務報錯Unexpected error occurred 

    這篇文章主要介紹了如何解決SpringBoot定時任務報錯Unexpected error occurred in scheduled task問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot入門編寫第一個程序Helloworld

    SpringBoot入門編寫第一個程序Helloworld

    這篇文章是Springboot入門篇,來教大家編寫第一個Springboot程序Helloworld,文中附有詳細的示例代碼,有需要的同學可以借鑒參考下
    2021-09-09
  • java解析excel文件的方法

    java解析excel文件的方法

    這篇文章主要介紹了java解析excel文件的方法,這里整理相關的代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02

最新評論