Skip to content

Commit e3f3ee1

Browse files
author
zhengrukai
committed
钉钉告警接入
1 parent 1f4ba7b commit e3f3ee1

2 files changed

Lines changed: 125 additions & 0 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package com.xxl.job.admin.scheduler.alarm.impl;
2+
3+
import com.xxl.job.admin.model.XxlJobGroup;
4+
import com.xxl.job.admin.model.XxlJobInfo;
5+
import com.xxl.job.admin.model.XxlJobLog;
6+
import com.xxl.job.admin.scheduler.alarm.JobAlarm;
7+
import com.xxl.job.admin.scheduler.config.XxlJobAdminBootstrap;
8+
import com.xxl.job.admin.util.I18nUtil;
9+
import com.xxl.job.core.context.XxlJobContext;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
12+
import org.springframework.beans.factory.annotation.Value;
13+
import org.springframework.http.HttpEntity;
14+
import org.springframework.http.HttpHeaders;
15+
import org.springframework.http.MediaType;
16+
import org.springframework.http.ResponseEntity;
17+
import org.springframework.stereotype.Component;
18+
import org.springframework.web.client.RestTemplate;
19+
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
23+
/**
24+
* 钉钉告警通知
25+
*
26+
* @author zrk on 2026/2/17
27+
*/
28+
@Component
29+
public class DingtalkJobAlarm implements JobAlarm {
30+
31+
private static Logger logger = LoggerFactory.getLogger(DingtalkJobAlarm.class);
32+
33+
@Value("${xxl.job.alarm.dingtalk.webhook:}")
34+
private String dingtalkWebhook;
35+
36+
private RestTemplate restTemplate = new RestTemplate();
37+
38+
@Override
39+
public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog) {
40+
boolean alarmResult = true;
41+
42+
// check dingtalk webhook config
43+
if (dingtalkWebhook == null || dingtalkWebhook.trim().isEmpty()) {
44+
logger.warn(">>>>>>>>>>> xxl-job, dingtalk webhook is not configured, skip alarm.");
45+
return true;
46+
}
47+
48+
try {
49+
// build alarm content
50+
String alarmContent = buildAlarmContent(info, jobLog);
51+
52+
// build dingtalk message
53+
Map<String, Object> message = new HashMap<>();
54+
message.put("msgtype", "text");
55+
56+
Map<String, String> textContent = new HashMap<>();
57+
textContent.put("content", alarmContent);
58+
message.put("text", textContent);
59+
60+
// send to dingtalk
61+
HttpHeaders headers = new HttpHeaders();
62+
headers.setContentType(MediaType.APPLICATION_JSON);
63+
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(message, headers);
64+
65+
ResponseEntity<String> response = restTemplate.postForEntity(dingtalkWebhook, entity, String.class);
66+
67+
if (!response.getStatusCode().is2xxSuccessful()) {
68+
logger.error(">>>>>>>>>>> xxl-job, dingtalk alarm send failed, status: {}, body: {}",
69+
response.getStatusCode(), response.getBody());
70+
alarmResult = false;
71+
} else {
72+
logger.info(">>>>>>>>>>> xxl-job, dingtalk alarm send success, response: {}", response.getBody());
73+
}
74+
75+
} catch (Exception e) {
76+
logger.error(">>>>>>>>>>> xxl-job, dingtalk alarm send error, JobLogId:{}", jobLog.getId(), e);
77+
alarmResult = false;
78+
}
79+
80+
return alarmResult;
81+
}
82+
83+
/**
84+
* build alarm content
85+
*/
86+
private String buildAlarmContent(XxlJobInfo info, XxlJobLog jobLog) {
87+
StringBuilder content = new StringBuilder();
88+
89+
// title
90+
content.append(I18nUtil.getString("jobconf_monitor")).append("\n");
91+
content.append("====================\n");
92+
93+
// job info
94+
XxlJobGroup group = XxlJobAdminBootstrap.getInstance().getXxlJobGroupMapper().load(Integer.valueOf(info.getJobGroup()));
95+
content.append(I18nUtil.getString("jobinfo_field_jobgroup")).append(": ")
96+
.append(group != null ? group.getTitle() : "null").append("\n");
97+
content.append(I18nUtil.getString("jobinfo_field_id")).append(": ")
98+
.append(info.getId()).append("\n");
99+
content.append(I18nUtil.getString("jobinfo_field_jobdesc")).append(": ")
100+
.append(info.getJobDesc()).append("\n");
101+
102+
// alarm type
103+
content.append(I18nUtil.getString("jobconf_monitor_alarm_title")).append(": ")
104+
.append(I18nUtil.getString("jobconf_monitor_alarm_type")).append("\n");
105+
106+
// alarm content
107+
content.append(I18nUtil.getString("jobconf_monitor_alarm_content")).append(":\n");
108+
content.append("Job LogId=").append(jobLog.getId()).append("\n");
109+
110+
if (jobLog.getTriggerCode() != XxlJobContext.HANDLE_CODE_SUCCESS) {
111+
content.append("TriggerMsg: ").append(jobLog.getTriggerMsg()).append("\n");
112+
}
113+
if (jobLog.getHandleCode() > 0 && jobLog.getHandleCode() != XxlJobContext.HANDLE_CODE_SUCCESS) {
114+
content.append("HandleMsg: ").append(jobLog.getHandleMsg()).append("\n");
115+
}
116+
117+
return content.toString();
118+
}
119+
120+
}

xxl-job-admin/src/main/resources/application.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ spring.mail.properties.mail.smtp.starttls.enable=true
5151
spring.mail.properties.mail.smtp.starttls.required=true
5252
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
5353

54+
### xxl-job, dingtalk
55+
xxl.job.alarm.dingtalk.webhook=
56+
5457
### xxl-job, access token
5558
xxl.job.accessToken=default_token
5659

@@ -72,3 +75,5 @@ xxl-sso.token.key=xxl_job_login_token
7275
xxl-sso.token.timeout=604800000
7376
xxl-sso.client.excluded.paths=
7477
xxl-sso.client.login.path=/auth/login
78+
79+

0 commit comments

Comments
 (0)