i18n
中文数据
alarm_field_alarmflag=告警开关
alarm_field_messageid=消息ID
alarm_field_messageid_placeholder=请输入消息ID
switch.css
开关样式表
/static/adminlte/bower_components/switch/alarmflag_switch.css
.switch-box {
width: 48px;
height: 34px;
value:'0';
}
.switch-box .switch {
/* 隐藏checkbox默认样式 */
display: none;
}
.switch-box label {
/* 通过label扩大点击热区 */
position: relative;
display: block;
margin: 1px;
height: 28px;
cursor: pointer;
}
.switch-box label::before {
/* before设置前滚动小圆球 */
content: '';
position: absolute;
top: 50%;
left: 50%;
margin-top: -13px;
margin-left: -14px;
width: 26px;
height: 26px;
border-radius: 100%;
background-color: #fff;
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.06);
/* 通过transform、transition属性控制元素过渡进而形成css3动画 */
-webkit-transform: translateX(-9px);
-moz-transform: translateX(-9px);
transform: translateX(-9px);
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.switch-box .switch:checked~label::before {
/* 语义:被选中的类名为"switch"元素后面的label元素里的伪类元素,进行更改css样式 */
/* 形成伪类结构选择器:":"冒号加布尔值"checked" */
/* " Ele1 ~ Ele2 "波浪号在css的作用:连接的元素必须有相同的父元素,选择出现在Ele1后的Ele2(但不必跟在Ele1,也就是说可以并列) */
-webkit-transform: translateX(10px);
-moz-transform: translateX(10px);
transform: translateX(10px);
}
.switch-box label::after {
/* after设置滚动前背景色 */
content: "";
display: block;
border-radius: 30px;
height: 28px;
width:46px;
background-color: #dcdfe6;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
transition: all 0.3s ease;
}
.switch-box .switch:checked~label::after {
background-color: #13ce66;
}
info.ftl
任务信息界面
<#--switch.css-->
<link rel="stylesheet" href="${request.contextPath}/static/adminlte/bower_components/switch/alarmflag_switch.css">
<div class="form-group">
<#--alarmFlag-->
<label for="lastname" class="col-sm-2 control-label">${I18n.alarm_field_alarmflag}</label>
<div class="col-sm-4">
<div class="switch-box">
<input id="alarmFlag" type="checkbox" class="switch" name="alarmFlag"/>
<label for="alarmFlag"></label>
</div>
</div>
<#--messageId-->
<div id="messageId" >
<label for="lastname" class="col-sm-2 control-label">${I18n.alarm_field_messageid}<font color="red">*</font></label>
<div class="col-sm-4">
<input type="text" class="form-control" name="messageId" placeholder="${I18n.alarm_field_messageid_placeholder}" maxlength="50" >
</div>
</div>
</div>
group.ftl
执行器界面
<#--switch.css-->
<link rel="stylesheet" href="${request.contextPath}/static/adminlte/bower_components/switch/alarmflag_switch.css">
<div class="form-group">
<#--groupAlarmFlag-->
<label for="lastname" class="col-sm-2 control-label">${I18n.alarm_field_alarmflag}</label>
<div class="col-sm-4">
<div class="switch-box">
<input id="groupAlarmFlag" type="checkbox" class="switch" name="groupAlarmFlag"/>
<label for="groupAlarmFlag"></label>
</div>
</div>
<#--groupMessageId-->
<div id="groupMessageId" >
<label for="lastname" class="col-sm-2 control-label">${I18n.alarm_field_messageid}<font color="red">*</font></label>
<div class="col-sm-4">
<input type="text" class="form-control" name="groupMessageId" placeholder="${I18n.alarm_field_messageid_placeholder}" maxlength="50" >
</div>
</div>
</div>
jobinfo.js
// 消息id框显示隐藏
$("#updateModal .form input[name='alarmFlag']").change(function(){
if ($(this).is(':checked')){
$(this).parents("form").find("#messageId").show();
$("#updateModal .form input[name='messageId']").prop("disabled", false);
}else {
$(this).parents("form").find("#messageId").hide();
$("#updateModal .form input[name='messageId']").prop("disabled", true);
}
});
// 初始化滑动开关是否选中
if (row.alarmFlag == '1'){
$("#updateModal .form input[name='alarmFlag']").prop("checked", true);
} else{
$("#updateModal .form input[name='alarmFlag']").prop("checked", false);
}
// 初始化消息id
$("#updateModal .form input[name='messageId']").val( row.messageId );
// 初始化消息id框显示隐藏
$("#updateModal .form input[name='alarmFlag']").change();
jobgroup.js
// 消息id框显示隐藏
$("#updateModal .form input[name='groupAlarmFlag']").change(function(){
if ($(this).is(':checked')){
$(this).parents("form").find("#groupMessageId").show();
$("#updateModal .form input[name='groupMessageId']").prop("disabled", false);
}else {
$(this).parents("form").find("#groupMessageId").hide();
$("#updateModal .form input[name='groupMessageId']").prop("disabled", true);
}
});
// 初始化滑动开关是否选中
if (row.groupAlarmFlag == '1'){
$("#updateModal .form input[name='groupAlarmFlag']").prop("checked", true);
} else{
$("#updateModal .form input[name='groupAlarmFlag']").prop("checked", false);
}
// 初始化消息id
$("#updateModal .form input[name='groupMessageId']").val( row.groupMessageId );
// 初始化消息id框显示隐藏
$("#updateModal .form input[name='groupAlarmFlag']").change();
XxlJobServiceImp
// 检查消息id非空
if (jobInfo.getAlarmFlag() != null && jobInfo.getMessageId().isEmpty()) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("alarm_field_messageid")+I18nUtil.getString("system_unvalid")) );
}
// 告警关闭
if (jobInfo.getAlarmFlag() == null){
exists_jobInfo.setAlarmFlag("0");
exists_jobInfo.setMessageId("");
// 告警打开
}else{
exists_jobInfo.setAlarmFlag("1");
exists_jobInfo.setMessageId(jobInfo.getMessageId());
}
System.out.println(exists_jobInfo);
jobGroupController
// 检查消息id非空
if (xxlJobGroup.getGroupAlarmFlag() != null && xxlJobGroup.getGroupMessageId().isEmpty()) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("alarm_field_messageid")+I18nUtil.getString("system_unvalid")) );
}
// 告警关闭
if (xxlJobGroup.getGroupAlarmFlag() == null){
xxlJobGroup.setGroupAlarmFlag("0");
xxlJobGroup.setGroupMessageId("");
// 告警打开
}else{
xxlJobGroup.setGroupAlarmFlag("1");
}
System.out.println(xxlJobGroup);
XxlJobInfo
private String alarmFlag;
private String messageId;
public String getAlarmFlag() {
return alarmFlag;
}
public void setAlarmFlag(String alarmFlag) {
this.alarmFlag = alarmFlag;
}
public String getMessageId() {
return messageId;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
XxlJobGroup
private String groupAlarmFlag;
private String groupMessageId;
public String getGroupAlarmFlag() {
return groupAlarmFlag;
}
public void setGroupAlarmFlag(String groupAlarmFlag) {
this.groupAlarmFlag = groupAlarmFlag;
}
public String getGroupMessageId() {
return groupMessageId;
}
public void setGroupMessageId(String groupMessageId) {
this.groupMessageId = groupMessageId;
}
tables_xxl_job.sql
DROP TABLE xxl_job_info;
CREATE TABLE IF NOT EXISTS `xxl_job_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT '执行器主键ID',
`job_desc` varchar(255) NOT NULL,
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`author` varchar(64) DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
`schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
`schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
`misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
`executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
`executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
`glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
`glue_source` mediumtext COMMENT 'GLUE源代码',
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
`glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
`child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
`trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次调度时间',
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次调度时间',
`alarm_flag` varchar(2) NOT NULL DEFAULT '0' COMMENT '告警开关:0-关,1-开',
`message_id` varchar(255) DEFAULT NULL COMMENT '消息ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
DROP TABLE xxl_job_group;
CREATE TABLE IF NOT EXISTS `xxl_job_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
`title` varchar(12) NOT NULL COMMENT '执行器名称',
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
`address_list` text COMMENT '执行器地址列表,多地址逗号分隔',
`update_time` datetime DEFAULT NULL,
`alarm_flag` varchar(2) NOT NULL DEFAULT '0' COMMENT '告警开关:0-关,1-开',
`message_id` varchar(255) DEFAULT NULL COMMENT '消息ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT IGNORE INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (1, 'xxl-job-executor-sample', '示例执行器', 0, NULL, '2018-11-03 22:21:31' );
DELETE FROM `xxl_job_info`;
INSERT IGNORE INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`)
VALUES (1, 1, '测试任务1', now(), now(), 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代码初始化', now(), '');
commit;
XxlJobInfoMapper
<resultMap id="XxlJobInfo" type="com.xxl.job.admin.core.model.XxlJobInfo" >
<result column="alarm_flag" property="alarmFlag" />
<result column="message_id" property="messageId" />
</resultMap>
<sql id="Base_Column_List">
t.alarm_flag,
t.message_id
</sql>
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobInfo" >
UPDATE xxl_job_info
SET
alarm_flag = #{alarmFlag},
message_id = #{messageId}
WHERE id = #{id}
</update>
XxlJobGroupMapper
<resultMap id="XxlJobGroup" type="com.xxl.job.admin.core.model.XxlJobGroup" >
<result column="alarm_flag" property="groupAlarmFlag" />
<result column="message_id" property="groupMessageId" />
</resultMap>
<sql id="Base_Column_List">
t.alarm_flag,
t.message_id
</sql>
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" >
UPDATE xxl_job_group
SET
`alarm_flag` = #{groupAlarmFlag},
`message_id` = #{groupMessageId}
WHERE id = #{id}
</update>
LogJobAlarm
package com.xxl.job.admin.core.alarm.impl;
import com.xxl.job.admin.core.alarm.JobAlarm;
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.core.biz.model.ReturnT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class EmailJobAlarm implements JobAlarm {
private static Logger logger = LoggerFactory.getLogger(EmailJobAlarm.class);
@Override
public boolean doAlarm(XxlJobInfo info, XxlJobLog jobLog){
boolean alarmResult = true;
// 任务信息 日志信息 执行器信息
XxlJobGroup group = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().load(jobLog.getJobGroup());
System.out.println(info);
System.out.println(jobLog);
System.out.println(group);
// 是否告警
boolean isAlarm = false;
if ("1".equals(group.getGroupAlarmFlag()) && "1".equals(info.getAlarmFlag())){
isAlarm = true;
}else if ("1".equals(group.getGroupAlarmFlag()) && "0".equals(info.getAlarmFlag())){
if (group.getRegistryList() == null || group.getRegistryList().isEmpty()){
isAlarm = true;
}
}
if (info!=null && isAlarm) {
// 告警内容
String alarmContent = "Alarm Job LogId= " + jobLog.getId() +
" jobGroup = " + jobLog.getJobGroup() +
" jobId = " + jobLog.getJobId() +
" executorAddress = " + jobLog.getExecutorAddress() +
" executorHandler = " + jobLog.getExecutorHandler() +
" executorParam = " + jobLog.getExecutorParam() +
" triggerCode = " + jobLog.getTriggerCode() +
" handleCode = " + jobLog.getHandleCode()
;
// 调度失败内容
if (jobLog.getTriggerCode() != ReturnT.SUCCESS_CODE) {
alarmContent += " triggerTime = " + jobLog.getTriggerTime() +
" triggerMsg = " + jobLog.getTriggerMsg();
}
// 执行失败内容
if (jobLog.getHandleCode()>0 && jobLog.getHandleCode() != ReturnT.SUCCESS_CODE) {
alarmContent += " handleTime = " + jobLog.getHandleTime() +
" handleMsg = " + jobLog.getHandleMsg();
}
// 消息ID
String messageId = "";
if ("1".equals(group.getGroupAlarmFlag()) && "1".equals(info.getAlarmFlag()) && !info.getMessageId().isEmpty()){
messageId = info.getMessageId();
}else if ("1".equals(group.getGroupAlarmFlag()) && "0".equals(info.getAlarmFlag()) && !group.getGroupMessageId().isEmpty()){
messageId = group.getGroupMessageId();
}
alarmContent += " messageId = " + messageId;
// 打印告警日志
logger.warn(alarmContent);
}
return alarmResult;
}
}