diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/WeiUtils/WebHookMessage.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/WeiUtils/WebHookMessage.java new file mode 100644 index 00000000..bee8ce6a --- /dev/null +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/WeiUtils/WebHookMessage.java @@ -0,0 +1,50 @@ +package com.xxl.job.admin.core.alarm.WeiUtils; + + +/** + * @author change + * @date 2022-09-22 0022 02:52:55 + */ +public class WebHookMessage { + private String webHook; + private String msgtype; + private Markdown markdown; + + public String getWebHook() { + return webHook; + } + + public void setWebHook(String webHook) { + this.webHook = webHook; + } + + public String getMsgtype() { + return msgtype; + } + + public void setMsgtype(String msgtype) { + this.msgtype = msgtype; + } + + public Markdown getMarkdown() { + return markdown; + } + + public void setMarkdown(Markdown markdown) { + this.markdown = markdown; + } + + public static class Markdown { + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + } + + +} diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/WeiJobAlarm.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/WeiJobAlarm.java new file mode 100644 index 00000000..629fa303 --- /dev/null +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/alarm/impl/WeiJobAlarm.java @@ -0,0 +1,89 @@ +package com.xxl.job.admin.core.alarm.impl; + +import com.xxl.job.admin.core.alarm.JobAlarm; +import com.xxl.job.admin.core.alarm.WeiUtils.WebHookMessage; +import com.xxl.job.admin.core.conf.XxlJobAdminConfig; +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.model.XxlJobLog; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.util.DateUtil; +import com.xxl.job.core.util.GsonTool; +import com.xxl.job.core.util.XxlJobRemotingUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * 发送企业微信机器人消息 + * + * @author change + * @date 2023-03-22 0022 11:20:30 + */ +@Component +public class WeiJobAlarm implements JobAlarm { + private static final Logger logger = LoggerFactory.getLogger(WeiJobAlarm.class); + + /** + * fail alarm + * + * @param jobLog + */ + @Override + public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) { + boolean alarmResult = true; + + // send monitor webhook + if (info != null && info.getAlarmWei() != null && info.getAlarmWei().trim().length() > 0) { + + // alarmContent + String alarmContent = "Alarm Job LogId=" + jobLog.getId(); + if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) { + alarmContent += "\nTriggerMsg=\n" + jobLog.getTriggerMsg().replaceAll("
", "|| "); + } + if (jobLog.getHandleCode() > 0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) { + alarmContent += "\nHandleCode=" + jobLog.getHandleMsg(); + } + + // info + XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(info.getJobGroup()); + + String content = loadEmailJobAlarmTemplate(info.getJobDesc(), group.getTitle(), info.getId(), alarmContent); + + String webhookUrl = info.getAlarmWei().trim(); + + WebHookMessage message = new WebHookMessage(); + message.setMsgtype("markdown"); + WebHookMessage.Markdown markdown = new WebHookMessage.Markdown(); + markdown.setContent(content); + message.setMarkdown(markdown); + ReturnT returnT = XxlJobRemotingUtil.postBody(webhookUrl, null, 3, message, String.class); + logger.info("请求结果:{}", GsonTool.toJson(returnT)); + } + + return alarmResult; + } + + /** + * 企业微信机器人消息模板 + * + * @return 模板 + */ + private static String loadEmailJobAlarmTemplate(String jobDesc, String jobGroup, int taskId, String content) { + return "# " + jobDesc + "\n" + + "> 时间: " + DateUtil.formatDateTime(new Date()) + "\n" + + "> `**事项详情**` \n" + //执行器 + + "> " + I18nUtil.getString("jobinfo_field_jobgroup") + ":" + jobGroup + " \n" + //任务id + + "> " + I18nUtil.getString("jobinfo_field_id") + ":" + taskId + "\n" + //告警类型 + + "> " + I18nUtil.getString("jobconf_monitor_alarm_title") + ":" + I18nUtil.getString("jobconf_monitor_alarm_type") + "\n" + //告警内容 + + "> " + I18nUtil.getString("jobconf_monitor_alarm_content") + ":\n" + content + " \n"; + } + +} diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java index e47b6dc6..7ffbcfdb 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java @@ -19,6 +19,7 @@ public class XxlJobInfo { private String author; // 负责人 private String alarmEmail; // 报警邮件 + private String alarmWei; // 企业微信群机器人告警 private String scheduleType; // 调度类型 private String scheduleConf; // 调度配置,值含义取决于调度类型 @@ -99,6 +100,14 @@ public class XxlJobInfo { this.alarmEmail = alarmEmail; } + public String getAlarmWei() { + return alarmWei; + } + + public void setAlarmWei(String alarmWei) { + this.alarmWei = alarmWei; + } + public String getScheduleType() { return scheduleType; } diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java index 8409d7b3..2834e1dc 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobFailMonitorHelper.java @@ -60,7 +60,8 @@ public class JobFailMonitorHelper { // 2、fail alarm monitor int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败 - if (info != null) { + if (info != null && ((info.getAlarmEmail() != null && info.getAlarmEmail().trim().length() > 0) + || (info.getAlarmWei() != null && info.getAlarmWei().trim().length() > 0))) { boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log); newAlarmStatus = alarmResult?2:3; } else { diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java index 530ee41c..c611749e 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java @@ -268,6 +268,7 @@ public class XxlJobServiceImpl implements XxlJobService { exists_jobInfo.setJobDesc(jobInfo.getJobDesc()); exists_jobInfo.setAuthor(jobInfo.getAuthor()); exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail()); + exists_jobInfo.setAlarmWei(jobInfo.getAlarmWei()); exists_jobInfo.setScheduleType(jobInfo.getScheduleType()); exists_jobInfo.setScheduleConf(jobInfo.getScheduleConf()); exists_jobInfo.setMisfireStrategy(jobInfo.getMisfireStrategy()); diff --git a/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties b/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties index 7891570d..41582a23 100644 --- a/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties +++ b/xxl-job-admin/src/main/resources/i18n/message_zh_CN.properties @@ -120,6 +120,8 @@ jobinfo_field_author=负责人 jobinfo_field_timeout=任务超时时间 jobinfo_field_alarmemail=报警邮件 jobinfo_field_alarmemail_placeholder=请输入报警邮件,多个邮件地址则逗号分隔 +jobinfo_field_weimail=企业微信告警 +jobinfo_field_weimail_placeholder=请输入机器人地址 jobinfo_field_executorRouteStrategy=路由策略 jobinfo_field_childJobId=子任务ID jobinfo_field_childJobId_placeholder=请输入子任务的任务ID,如存在多个则逗号分隔 diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml index 7b3c3a3e..65cabfef 100644 --- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml +++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml @@ -14,6 +14,7 @@ + @@ -46,6 +47,7 @@ t.update_time, t.author, t.alarm_email, + t.alarm_wei, t.schedule_type, t.schedule_conf, t.misfire_strategy, @@ -119,6 +121,7 @@ update_time, author, alarm_email, + alarm_wei, schedule_type, schedule_conf, misfire_strategy, @@ -143,6 +146,7 @@ #{updateTime}, #{author}, #{alarmEmail}, + #{alarmWei}, #{scheduleType}, #{scheduleConf}, #{misfireStrategy}, @@ -182,6 +186,7 @@ author = #{author}, alarm_email = #{alarmEmail}, schedule_type = #{scheduleType}, + alarm_wei = #{alarmWei}, schedule_conf = #{scheduleConf}, misfire_strategy = #{misfireStrategy}, executor_route_strategy = #{executorRouteStrategy}, diff --git a/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js b/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js index b479e972..8c36673f 100644 --- a/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js +++ b/xxl-job-admin/src/main/resources/static/js/jobinfo.index.1.js @@ -542,6 +542,7 @@ $(function() { $("#updateModal .form input[name='jobDesc']").val( row.jobDesc ); $("#updateModal .form input[name='author']").val( row.author ); $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail ); + $("#updateModal .form input[name='alarmWei']").val( row.alarmWei ); // fill trigger $('#updateModal .form select[name=scheduleType] option[value='+ row.scheduleType +']').prop('selected', true); @@ -697,6 +698,7 @@ $(function() { $("#addModal .form input[name='jobDesc']").val( row.jobDesc ); $("#addModal .form input[name='author']").val( row.author ); $("#addModal .form input[name='alarmEmail']").val( row.alarmEmail ); + $("#addModal .form input[name='alarmWei']").val( row.alarmWei ); // fill trigger $('#addModal .form select[name=scheduleType] option[value='+ row.scheduleType +']').prop('selected', true); diff --git a/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl b/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl index 3a5d7d8a..750bbd7f 100644 --- a/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl +++ b/xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl @@ -135,7 +135,10 @@
- +
+ +
+

${I18n.jobinfo_conf_schedule}

<#-- 调度 -->
@@ -380,6 +383,10 @@ exit 0
+
+ +
+

${I18n.jobinfo_conf_schedule}

<#-- 调度配置 -->