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**: {}
From 9249a0eaa7fa35dcd77a8c32e34a3f6e90ca8817 Mon Sep 17 00:00:00 2001
From: AprilWind <2100166581@qq.com>
Date: Thu, 25 Jul 2024 17:43:46 +0800
Subject: [PATCH 2/7] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E4=BA=8B?=
=?UTF-8?q?=E4=BB=B6=E5=8F=91=E9=80=81=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../monitor/admin/notifier/InfoNotifier.java | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
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
index 2f2538986..da917fe12 100644
--- 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
@@ -31,26 +31,31 @@ public class InfoNotifier {
private final NotifyProperties notifyProperties;
/**
- * 服务上线或者离线
+ * 处理服务通知事件
+ *
+ * 此方法会在服务状态发生变化时触发,并且会异步地发送 WebHook 通知
+ * 适用于服务的正常状态变更,不包括异常情况
*
- * @param notifier 通知事件
+ * @param notifier 通知事件对象,包含服务的状态和其他相关信息
*/
@Async
- @EventListener(condition = "#notifier.status == 'UP' || #notifier.status == 'OFFLINE'")
+ @EventListener
public void infoNotification(NotifierEvent notifier) {
sendWebHook(notifier);
}
/**
- * 服务下线或者发送异常
+ * 处理服务下线,离线或异常的通知事件
+ *
+ * 当服务的状态为“OFFLINE”、“DOWN”或“UNKNOWN”时,会触发此方法
+ * 该方法会异步发送邮件通知,以便及时处理服务问题
*
- * @param notifier 通知事件
+ * @param notifier 通知事件对象,包含服务的状态和其他相关信息
*/
@Async
- @EventListener(condition = "#notifier.status == 'DOWN' || #notifier.status == 'UNKNOWN'")
+ @EventListener(condition = "#notifier.status == 'OFFLINE' || #notifier.status == 'DOWN' || #notifier.status == 'UNKNOWN'")
public void errNotification(NotifierEvent notifier) {
sendMail(notifier);
- sendWebHook(notifier);
}
/**
From 0b967b48348b6fc29686cc205082f9e435dc506a Mon Sep 17 00:00:00 2001
From: AprilWind <2100166581@qq.com>
Date: Fri, 26 Jul 2024 10:23:56 +0800
Subject: [PATCH 3/7] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E5=8A=A0?=
=?UTF-8?q?=E7=AD=BE=EF=BC=8C=E6=94=AF=E6=8C=81=E9=92=89=E9=92=89=EF=BC=8C?=
=?UTF-8?q?=E9=A3=9E=E4=B9=A6=EF=BC=8C=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../config/properties/NotifyProperties.java | 7 +-
.../monitor/admin/notifier/InfoNotifier.java | 95 +++++++++++++++----
.../src/main/resources/application.yml | 1 +
3 files changed, 86 insertions(+), 17 deletions(-)
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
index 870122efe..40f7172a2 100644
--- 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
@@ -63,7 +63,12 @@ public class NotifyProperties {
/**
* 0默认 1密码 2签名密钥
*/
- private String type;
+ private String type = "0";
+
+ /**
+ * 签名密钥
+ */
+ private String secret;
/**
* Post地址
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
index da917fe12..c944db2ba 100644
--- 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
@@ -12,10 +12,15 @@ import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
import java.net.URI;
+import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
@@ -89,7 +94,7 @@ public class InfoNotifier {
String message = StringUtils.format(webHook.getTemplate(), title,
notifier.getRegistName(), notifier.getInstanceId(), notifier.getStatus(), notifier.getServiceUrl());
try {
- sendWebHookMessage(webHook.getUrl(), title, message);
+ sendWebHookMessage(webHook, title, message);
log.info("WebHook消息已发送至: {}", webHook.getUrl());
} catch (Exception e) {
log.error("WebHook消息发送失败: ", e);
@@ -97,32 +102,90 @@ public class InfoNotifier {
}
}
- private void sendWebHookMessage(String url, String title, String markdownMessage) throws Exception {
- // 构造消息体
+ /**
+ * 发送WebHook消息
+ *
+ * @param webHook WebHook配置信息
+ * @param title 消息标题
+ * @param markdownMessage 消息内容
+ * @throws Exception 处理过程中可能抛出的异常
+ */
+ private void sendWebHookMessage(NotifyProperties.WebHook webHook, String title, String markdownMessage) throws Exception {
+ String jsonMessage = createJsonMessage(title, markdownMessage);
+ HttpClient client = HttpClient.newHttpClient();
+ HttpRequest request = createHttpRequest(webHook, jsonMessage);
+ HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ handleResponse(response);
+ }
+
+ /**
+ * 创建消息体的JSON字符串
+ *
+ * @param title 消息标题
+ * @param markdownMessage 消息内容
+ * @return JSON格式的消息体
+ * @throws Exception 处理过程中可能抛出的异常
+ */
+ private String createJsonMessage(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);
+ return objectMapper.writeValueAsString(messageBody);
+ }
- // 创建HTTP客户端
- HttpClient client = HttpClient.newHttpClient();
- HttpRequest request = HttpRequest.newBuilder()
- .uri(new URI(url))
+ /**
+ * 根据WebHook配置创建HTTP请求
+ *
+ * @param webHook WebHook配置信息
+ * @param jsonMessage JSON格式的消息体
+ * @return 创建的HTTP请求
+ * @throws Exception 处理过程中可能抛出的异常
+ */
+ private HttpRequest createHttpRequest(NotifyProperties.WebHook webHook, String jsonMessage) throws Exception {
+ HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.header("Content-Type", "application/json")
- .POST(HttpRequest.BodyPublishers.ofString(jsonMessage))
- .build();
+ .POST(HttpRequest.BodyPublishers.ofString(jsonMessage));
- // 发送请求
- HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
+ if ("2".equals(webHook.getType())) {
+ String signedUrl = generateSignedUrl(webHook);
+ requestBuilder.uri(new URI(signedUrl));
+ } else {
+ requestBuilder.uri(new URI(webHook.getUrl()));
+ }
- // 处理响应
+ return requestBuilder.build();
+ }
+
+ /**
+ * 生成带签名的URL
+ *
+ * @param webHook WebHook配置信息
+ * @return 带签名的URL
+ * @throws Exception 处理过程中可能抛出的异常
+ */
+ private String generateSignedUrl(NotifyProperties.WebHook webHook) throws Exception {
+ long timestamp = System.currentTimeMillis();
+ String secret = webHook.getSecret();
+ 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));
+ String sign = URLEncoder.encode(Base64.getEncoder().encodeToString(signData), StandardCharsets.UTF_8);
+
+ return String.format("%s×tamp=%d&sign=%s", webHook.getUrl(), timestamp, sign);
+ }
+
+ /**
+ * 处理HTTP响应
+ *
+ * @param response HTTP响应
+ */
+ private void handleResponse(HttpResponse response) {
if (response.statusCode() == 200) {
log.info("WebHook消息发送成功");
} else {
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 18d845caa..f6730ce6d 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
@@ -84,6 +84,7 @@ notify:
enabled: false
type: 0
url:
+ secret:
template: |
### {}通知
- **服务名**: {}
From 4408206d486cd01785ca206311daf97bfd49c7db Mon Sep 17 00:00:00 2001
From: AprilWind <2100166581@qq.com>
Date: Fri, 26 Jul 2024 10:32:58 +0800
Subject: [PATCH 4/7] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=E5=A4=84=E7=90=86H?=
=?UTF-8?q?TTP=E5=93=8D=E5=BA=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../monitor/admin/notifier/InfoNotifier.java | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
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
index c944db2ba..49d6c100c 100644
--- 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
@@ -1,5 +1,6 @@
package org.dromara.monitor.admin.notifier;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -186,10 +187,19 @@ public class InfoNotifier {
* @param response HTTP响应
*/
private void handleResponse(HttpResponse response) {
- if (response.statusCode() == 200) {
- log.info("WebHook消息发送成功");
- } else {
- log.error("WebHook消息发送失败: {}", response.body());
+ try {
+ // 解析响应体
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode jsonNode = objectMapper.readTree(response.body());
+ int errcode = jsonNode.has("errcode") ? jsonNode.get("errcode").asInt() : -1;
+ String errmsg = jsonNode.has("errmsg") ? jsonNode.get("errmsg").asText() : "Unknown error";
+ if (errcode == 0) {
+ log.info("WebHook消息发送成功");
+ } else {
+ log.error("WebHook消息发送失败: errcode={}, errmsg={}", errcode, errmsg);
+ }
+ } catch (Exception e) {
+ log.error("处理WebHook响应时发生异常: {}", e.getMessage());
}
}
From 4fad76397a0b306578cf48b439144c6a64a55db2 Mon Sep 17 00:00:00 2001
From: AprilWind <2100166581@qq.com>
Date: Fri, 26 Jul 2024 11:02:29 +0800
Subject: [PATCH 5/7] =?UTF-8?q?fix=20=E8=BF=BD=E5=8A=A0=E5=85=B3=E9=94=AE?=
=?UTF-8?q?=E8=AF=8D=E5=88=B0=E6=A0=87=E9=A2=98=E4=B8=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../monitor/admin/config/properties/NotifyProperties.java | 5 +++++
.../org/dromara/monitor/admin/notifier/InfoNotifier.java | 5 ++++-
.../ruoyi-monitor-admin/src/main/resources/application.yml | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
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
index 40f7172a2..8dba895be 100644
--- 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
@@ -70,6 +70,11 @@ public class NotifyProperties {
*/
private String secret;
+ /**
+ * 关键词
+ */
+ private String keywords;
+
/**
* Post地址
*/
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
index 49d6c100c..da6dbdbb0 100644
--- 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
@@ -6,7 +6,6 @@ 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;
@@ -94,6 +93,10 @@ public class InfoNotifier {
String title = notifier.getRegistName() + notifier.getStatusName();
String message = StringUtils.format(webHook.getTemplate(), title,
notifier.getRegistName(), notifier.getInstanceId(), notifier.getStatus(), notifier.getServiceUrl());
+ if (StringUtils.isNotBlank(webHook.getKeywords())) {
+ //追加关键词到标题中
+ title += "——" + webHook.getKeywords();
+ }
try {
sendWebHookMessage(webHook, title, message);
log.info("WebHook消息已发送至: {}", webHook.getUrl());
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 f6730ce6d..f134a68a6 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
@@ -85,6 +85,7 @@ notify:
type: 0
url:
secret:
+ keywords:
template: |
### {}通知
- **服务名**: {}
From 3f1f74151f2f9bd4d8f5781b0ced0583d109c6f7 Mon Sep 17 00:00:00 2001
From: AprilWind <2100166581@qq.com>
Date: Fri, 26 Jul 2024 11:40:40 +0800
Subject: [PATCH 6/7] =?UTF-8?q?fix=20=E8=BF=BD=E5=8A=A0=E6=97=B6=E9=97=B4?=
=?UTF-8?q?=E6=88=B3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../org/dromara/monitor/admin/notifier/InfoNotifier.java | 7 ++++---
.../ruoyi-monitor-admin/src/main/resources/application.yml | 4 +++-
2 files changed, 7 insertions(+), 4 deletions(-)
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
index da6dbdbb0..f53a1bb6d 100644
--- 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
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mail.utils.MailUtils;
import org.dromara.monitor.admin.config.properties.NotifyProperties;
@@ -72,7 +73,7 @@ public class InfoNotifier {
NotifyProperties.Mail mail = notifyProperties.getMail();
if (mail.getEnabled()) {
String message = StringUtils.format(mail.getTemplate(), notifier.getRegistName(), notifier.getInstanceId(),
- notifier.getStatusName(), notifier.getStatus(), notifier.getServiceUrl());
+ notifier.getStatusName(), notifier.getStatus(), notifier.getServiceUrl(), DateUtils.getTime());
try {
MailUtils.sendHtml(mail.getTo(), notifier.getRegistName() + notifier.getStatusName(), message);
log.info("邮件已发送至: {}", mail.getTo());
@@ -91,8 +92,8 @@ public class InfoNotifier {
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());
+ String message = StringUtils.format(webHook.getTemplate(), title, notifier.getRegistName(),
+ notifier.getInstanceId(), notifier.getStatus(), notifier.getServiceUrl(), DateUtils.getTime());
if (StringUtils.isNotBlank(webHook.getKeywords())) {
//追加关键词到标题中
title += "——" + webHook.getKeywords();
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 f134a68a6..832338102 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
+++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml
@@ -79,6 +79,7 @@ notify:
服务名: {} ({})
状态: {} ({})
服务IP: {}
+ 时间: {}