From 5d6f706a9537eb4375e7d89233d02a45b19d688b Mon Sep 17 00:00:00 2001 From: AprilWind <2100166581@qq.com> Date: Thu, 25 Jul 2024 15:09:58 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=96=B0=E5=A2=9E=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9B=91=E6=8E=A7=E9=82=AE=E4=BB=B6=E9=80=9A=E7=9F=A5=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E9=92=89=E9=92=89=E6=9C=BA=E5=99=A8=E4=BA=BA=E9=80=9A?= =?UTF-8?q?=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-extend/ruoyi-monitor-admin/pom.xml | 5 + .../config/properties/NotifyProperties.java | 80 +++++++++++ .../monitor/admin/event/NotifierEvent.java | 44 ++++++ .../admin/notifier/CustomNotifier.java | 9 ++ .../monitor/admin/notifier/InfoNotifier.java | 128 ++++++++++++++++++ .../src/main/resources/application.yml | 44 ++++++ 6 files changed, 310 insertions(+) create mode 100644 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/properties/NotifyProperties.java create mode 100644 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/event/NotifierEvent.java create mode 100644 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/InfoNotifier.java diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml index 91194c61b..e14d3ab04 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml +++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml @@ -39,6 +39,11 @@ lombok + + org.dromara + ruoyi-common-mail + + diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/properties/NotifyProperties.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/properties/NotifyProperties.java new file mode 100644 index 000000000..870122efe --- /dev/null +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/properties/NotifyProperties.java @@ -0,0 +1,80 @@ +package org.dromara.monitor.admin.config.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * 通知配置 + * + * @author AprilWind + */ +@Data +@ConfigurationProperties(prefix = "notify") +@Configuration +public class NotifyProperties { + + /** + * 邮件设置 + */ + private Mail mail; + + /** + * WebHooks 设置 + */ + private WebHook webHook; + + @Data + @NoArgsConstructor + public static class Mail { + + /** + * 发送开关 + */ + private Boolean enabled = false; + + /** + * 收件人 + */ + private String to; + + /** + * 主题 + */ + private String subject; + + /** + * 邮件模版 + */ + private String template; + + } + + @Data + @NoArgsConstructor + public static class WebHook { + + /** + * 发送开关 + */ + private Boolean enabled = false; + + /** + * 0默认 1密码 2签名密钥 + */ + private String type; + + /** + * Post地址 + */ + private String url; + + /** + * WebHook发送模版 + */ + private String template; + + } + +} diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/event/NotifierEvent.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/event/NotifierEvent.java new file mode 100644 index 000000000..7df53e460 --- /dev/null +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/event/NotifierEvent.java @@ -0,0 +1,44 @@ +package org.dromara.monitor.admin.event; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 通知事件 + * + * @author AprilWind + */ +@Data +public class NotifierEvent implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 实例注册名称 + */ + private String registName; + + /** + * 实例状态名称 + */ + private String statusName; + + /** + * 实例ID + */ + private String instanceId; + + /** + * 实例状态 + */ + private String status; + + /** + * 服务URL + */ + private String serviceUrl; + +} diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java index 838eefc47..e2b529449 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java @@ -6,6 +6,8 @@ import de.codecentric.boot.admin.server.domain.events.InstanceEvent; import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent; import de.codecentric.boot.admin.server.notify.AbstractEventNotifier; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.monitor.admin.event.NotifierEvent; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; @@ -49,6 +51,13 @@ public class CustomNotifier extends AbstractEventNotifier { }; log.info("Instance Status Change: 状态名称【{}】, 注册名称【{}】, 实例ID【{}】, 状态【{}】, 服务URL【{}】", statusName, registName, instanceId, status, serviceUrl); + NotifierEvent notifier = new NotifierEvent(); + notifier.setRegistName(registName); + notifier.setStatusName(statusName); + notifier.setInstanceId(instanceId); + notifier.setStatus(status); + notifier.setServiceUrl(serviceUrl); + SpringUtils.context().publishEvent(notifier); } }); } diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/InfoNotifier.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/InfoNotifier.java new file mode 100644 index 000000000..2f2538986 --- /dev/null +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/InfoNotifier.java @@ -0,0 +1,128 @@ +package org.dromara.monitor.admin.notifier; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mail.utils.MailUtils; + +import org.dromara.monitor.admin.config.properties.NotifyProperties; +import org.dromara.monitor.admin.event.NotifierEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.HashMap; +import java.util.Map; + +/** + * 信息通知 + * + * @author AprilWind + */ +@RequiredArgsConstructor +@Slf4j +@Service +public class InfoNotifier { + private final NotifyProperties notifyProperties; + + /** + * 服务上线或者离线 + * + * @param notifier 通知事件 + */ + @Async + @EventListener(condition = "#notifier.status == 'UP' || #notifier.status == 'OFFLINE'") + public void infoNotification(NotifierEvent notifier) { + sendWebHook(notifier); + } + + /** + * 服务下线或者发送异常 + * + * @param notifier 通知事件 + */ + @Async + @EventListener(condition = "#notifier.status == 'DOWN' || #notifier.status == 'UNKNOWN'") + public void errNotification(NotifierEvent notifier) { + sendMail(notifier); + sendWebHook(notifier); + } + + /** + * 发送邮件通知 + * + * @param notifier 包含通知信息的对象 + */ + public void sendMail(NotifierEvent notifier) { + NotifyProperties.Mail mail = notifyProperties.getMail(); + if (mail.getEnabled()) { + String message = StringUtils.format(mail.getTemplate(), notifier.getRegistName(), notifier.getInstanceId(), + notifier.getStatusName(), notifier.getStatus(), notifier.getServiceUrl()); + try { + MailUtils.sendHtml(mail.getTo(), notifier.getRegistName() + notifier.getStatusName(), message); + log.info("邮件已发送至: {}", mail.getTo()); + } catch (Exception e) { + log.error("邮件发送失败: ", e); + } + } + } + + /** + * 发送WebHook通知 + * + * @param notifier 包含通知信息的对象 + */ + public void sendWebHook(NotifierEvent notifier) { + NotifyProperties.WebHook webHook = notifyProperties.getWebHook(); + if (webHook.getEnabled()) { + String title = notifier.getRegistName() + notifier.getStatusName(); + String message = StringUtils.format(webHook.getTemplate(), title, + notifier.getRegistName(), notifier.getInstanceId(), notifier.getStatus(), notifier.getServiceUrl()); + try { + sendWebHookMessage(webHook.getUrl(), title, message); + log.info("WebHook消息已发送至: {}", webHook.getUrl()); + } catch (Exception e) { + log.error("WebHook消息发送失败: ", e); + } + } + } + + private void sendWebHookMessage(String url, String title, String markdownMessage) throws Exception { + // 构造消息体 + Map messageBody = new HashMap<>(); + messageBody.put("msgtype", "markdown"); + + Map markdownContent = new HashMap<>(); + markdownContent.put("title", title + "通知"); + markdownContent.put("text", markdownMessage); + messageBody.put("markdown", markdownContent); + + // 将消息体转换为JSON字符串 + ObjectMapper objectMapper = new ObjectMapper(); + String jsonMessage = objectMapper.writeValueAsString(messageBody); + + // 创建HTTP客户端 + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(new URI(url)) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(jsonMessage)) + .build(); + + // 发送请求 + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + // 处理响应 + if (response.statusCode() == 200) { + log.info("WebHook消息发送成功"); + } else { + log.error("WebHook消息发送失败: {}", response.body()); + } + } + +} diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml index beee58775..18d845caa 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml @@ -46,3 +46,47 @@ spring.boot.admin.client: userpassword: ${spring.boot.admin.client.password} username: ruoyi password: 123456 + +--- # mail 邮件发送 +mail: + enabled: false + host: smtp.163.com + port: 465 + # 是否需要用户名密码验证 + auth: true + # 发送方,遵循RFC-822标准 + from: xxx@163.com + # 用户名(注意:如果使用foxmail邮箱,此处user为qq号) + user: xxx@163.com + # 密码(注意,某些邮箱需要为SMTP服务单独设置密码,详情查看相关帮助) + pass: xxxxxxxxxx + # 使用 STARTTLS安全连接,STARTTLS是对纯文本通信协议的扩展。 + starttlsEnable: true + # 使用SSL安全连接 + sslEnable: true + # SMTP超时时长,单位毫秒,缺省值不超时 + timeout: 0 + # Socket连接超时值,单位毫秒,缺省值不超时 + connectionTimeout: 0 + +# 服务通知 +notify: + mail: + enabled: false + to: + subject: 系统通知 + template: " +

服务名: {} ({})

+

状态: {} ({})

+

服务IP: {}

+ " + web-hook: + enabled: false + type: 0 + url: + template: | + ### {}通知 + - **服务名**: {} + - **实例ID**: {} + - **状态**: {} + - **服务IP**: {}