ソースを参照

新增调度,仪表盘

xueli.xue 8 年 前
コミット
6e3e24a909

+ 1 - 2
README.md

@@ -780,8 +780,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
 - 3、任务权限管理;
 - 4、执行器,server启动,注册逻辑调整;
 - 5、调度失败重试机制;
-
-- 7、JobHandler开启多线程时,支持记录执行日志;
+- 6、JobHandler开启多线程时,支持记录执行日志;
 
 
 ## 七、其他

+ 17 - 6
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java

@@ -3,6 +3,7 @@ package com.xxl.job.admin.controller;
 import com.xxl.job.admin.controller.annotation.PermessionLimit;
 import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
 import com.xxl.job.admin.core.util.PropertiesUtil;
+import com.xxl.job.admin.service.IXxlJobService;
 import com.xxl.job.core.biz.model.ReturnT;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.stereotype.Controller;
@@ -11,8 +12,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
 
 /**
  * index controller
@@ -21,13 +24,16 @@ import javax.servlet.http.HttpServletResponse;
 @Controller
 public class IndexController {
 
+	@Resource
+	private IXxlJobService xxlJobService;
+
 	@RequestMapping("/")
-	@PermessionLimit(limit=false)
-	public String index(Model model, HttpServletRequest request) {
-		if (!PermissionInterceptor.ifLogin(request)) {
-			return "redirect:/toLogin";
-		}
-		return "redirect:/jobinfo";
+	public String index(Model model) {
+
+		Map<String, Object> dashboardMap = xxlJobService.dashboardInfo();
+		model.addAllAttributes(dashboardMap);
+
+		return "index";
 	}
 	
 	@RequestMapping("/toLogin")
@@ -71,6 +77,11 @@ public class IndexController {
 	
 	@RequestMapping("/help")
 	public String help() {
+
+		/*if (!PermissionInterceptor.ifLogin(request)) {
+			return "redirect:/toLogin";
+		}*/
+
 		return "help";
 	}
 	

+ 6 - 4
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java

@@ -120,10 +120,12 @@ public class JobLogController {
 			ReturnT<LogResult> logResult = executorBiz.log(triggerTime, logId, fromLineNum);
 
 			// is end
-			/*XxlJobLog jobLog = xxlJobLogDao.load(logId);
-			if (jobLog.getHandleCode() > 0) {
-				logResult.getContent().setEnd(true);
-			}*/
+            if (logResult.getContent()!=null && logResult.getContent().getFromLineNum() > logResult.getContent().getToLineNum()) {
+                XxlJobLog jobLog = xxlJobLogDao.load(logId);
+                if (jobLog.getHandleCode() > 0) {
+                    logResult.getContent().setEnd(true);
+                }
+            }
 
 			return logResult;
 		} catch (Exception e) {

+ 3 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/IXxlJobInfoDao.java

@@ -23,4 +23,7 @@ public interface IXxlJobInfoDao {
 	public int delete(int id);
 
 	public List<XxlJobInfo> getJobsByGroup(String jobGroup);
+
+	public int findAllCount();
+
 }

+ 3 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/IXxlJobLogDao.java

@@ -23,5 +23,7 @@ public interface IXxlJobLogDao {
 	public int updateHandleInfo(XxlJobLog xxlJobLog);
 	
 	public int delete(int jobId);
-	
+
+	public int findByHandleCodeCount(int handleCode);
+
 }

+ 5 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobInfoDaoImpl.java

@@ -66,4 +66,9 @@ public class XxlJobInfoDaoImpl implements IXxlJobInfoDao {
 		return sqlSessionTemplate.selectList("XxlJobInfoMapper.getJobsByGroup", jobGroup);
 	}
 
+	@Override
+	public int findAllCount() {
+		return sqlSessionTemplate.selectOne("XxlJobInfoMapper.findAllCount");
+	}
+
 }

+ 6 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobLogDaoImpl.java

@@ -76,5 +76,10 @@ public class XxlJobLogDaoImpl implements IXxlJobLogDao {
 	public int delete(int jobId) {
 		return sqlSessionTemplate.delete("XxlJobLogMapper.delete", jobId);
 	}
-	
+
+	@Override
+	public int findByHandleCodeCount(int handleCode) {
+		return sqlSessionTemplate.selectOne("XxlJobLogMapper.findByHandleCodeCount", handleCode);
+	}
+
 }

+ 2 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java

@@ -26,5 +26,6 @@ public interface IXxlJobService {
 	public ReturnT<String> resume(int id);
 	
 	public ReturnT<String> triggerJob(int id);
-	
+
+    Map<String,Object> dashboardInfo();
 }

+ 41 - 8
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java

@@ -4,12 +4,12 @@ import com.xxl.job.admin.core.model.XxlJobGroup;
 import com.xxl.job.admin.core.model.XxlJobInfo;
 import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
-import com.xxl.job.admin.dao.IXxlJobGroupDao;
-import com.xxl.job.admin.dao.IXxlJobInfoDao;
-import com.xxl.job.admin.dao.IXxlJobLogDao;
-import com.xxl.job.admin.dao.IXxlJobLogGlueDao;
+import com.xxl.job.admin.core.thread.JobRegistryHelper;
+import com.xxl.job.admin.dao.*;
 import com.xxl.job.admin.service.IXxlJobService;
 import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.registry.RegistHelper;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.quartz.CronExpression;
 import org.quartz.SchedulerException;
@@ -19,9 +19,7 @@ import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * core job action for xxl-job
@@ -257,5 +255,40 @@ public class XxlJobServiceImpl implements IXxlJobService {
 			return ReturnT.FAIL;
 		}
 	}
-	
+
+	@Override
+	public Map<String, Object> dashboardInfo() {
+
+		int jobInfoCount = xxlJobInfoDao.findAllCount();
+		int jobLogCount = xxlJobLogDao.findByHandleCodeCount(-1);
+		int jobLogSuccessCount = xxlJobLogDao.findByHandleCodeCount(ReturnT.SUCCESS_CODE);
+
+		// executor count
+		Set<String> executerAddressSet = new HashSet<String>();
+		List<XxlJobGroup> groupList = xxlJobGroupDao.findAll();
+		if (CollectionUtils.isNotEmpty(groupList)) {
+			for (XxlJobGroup group: groupList) {
+				List<String> registryList = null;
+				if (group.getAddressType() == 0) {
+					registryList = JobRegistryHelper.discover(RegistHelper.RegistType.EXECUTOR.name(), group.getAppName());
+				} else {
+					if (StringUtils.isNotBlank(group.getAddressList())) {
+						registryList = Arrays.asList(group.getAddressList().split(","));
+					}
+				}
+				if (CollectionUtils.isNotEmpty(registryList)) {
+					executerAddressSet.addAll(registryList);
+				}
+			}
+		}
+		int executorCount = executerAddressSet.size();
+
+		Map<String, Object> dashboardMap = new HashMap<String, Object>();
+		dashboardMap.put("jobInfoCount", jobInfoCount);
+		dashboardMap.put("jobLogCount", jobLogCount);
+		dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount);
+		dashboardMap.put("executorCount", executorCount);
+		return dashboardMap;
+	}
+
 }

+ 6 - 1
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml

@@ -151,5 +151,10 @@
 		FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
 		WHERE t.job_group = #{jobGroup}
 	</select>
-	
+
+	<select id="findAllCount" resultType="int">
+		SELECT count(1)
+		FROM XXL_JOB_QRTZ_TRIGGER_INFO
+	</select>
+
 </mapper>

+ 10 - 0
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml

@@ -123,5 +123,15 @@
 		delete from XXL_JOB_QRTZ_TRIGGER_LOG
 		WHERE job_id = #{jobId}
 	</delete>
+
+	<select id="findByHandleCodeCount" parameterType="java.lang.Integer" resultType="java.lang.Integer">
+		SELECT count(1)
+		FROM XXL_JOB_QRTZ_TRIGGER_LOG AS t
+		<trim prefix="WHERE" prefixOverrides="AND | OR" >
+			<if test="_parameter gt 0">
+				AND t.handle_code = #{handleCode}
+			</if>
+		</trim>
+	</select>
 	
 </mapper>

+ 3 - 3
xxl-job-admin/src/main/webapp/WEB-INF/template/common/common.macro.ftl

@@ -81,10 +81,10 @@
 			<!-- sidebar menu: : style can be found in sidebar.less -->
 			<ul class="sidebar-menu">
 				<li class="header">常用模块</li>
-				<li class="nav-click <#if pageName == "jobinfo">active</#if>" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-red"></i> <span>调度管理</span></a></li>
+				<li class="nav-click <#if pageName == "jobinfo">active</#if>" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-aqua"></i> <span>任务管理</span></a></li>
 				<li class="nav-click <#if pageName == "joblog">active</#if>" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-yellow"></i><span>调度日志</span></a></li>
-                <li class="nav-click <#if pageName == "jobgroup">active</#if>" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-aqua"></i> <span>执行器管理</span></a></li>
-				<li class="nav-click <#if pageName == "help">active</#if>" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-red"></i><span>使用教程</span></a></li>
+                <li class="nav-click <#if pageName == "jobgroup">active</#if>" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-green"></i> <span>执行器管理</span></a></li>
+				<li class="nav-click <#if pageName == "help">active</#if>" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-gray"></i><span>使用教程</span></a></li>
 			</ul>
 		</section>
 		<!-- /.sidebar -->

+ 100 - 0
xxl-job-admin/src/main/webapp/WEB-INF/template/index.ftl

@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+  	<title>任务调度中心</title>
+  	<#import "/common/common.macro.ftl" as netCommon>
+	<@netCommon.commonStyle />
+</head>
+<body class="hold-transition skin-blue sidebar-mini <#if cookieMap?exists && "off" == cookieMap["adminlte_settings"].value >sidebar-collapse</#if> ">
+<div class="wrapper">
+	<!-- header -->
+	<@netCommon.commonHeader />
+	<!-- left -->
+	<@netCommon.commonLeft "index" />
+	
+	<!-- Content Wrapper. Contains page content -->
+	<div class="content-wrapper">
+		<!-- Content Header (Page header) -->
+		<section class="content-header">
+			<h1>仪表盘<small>任务调度中心</small></h1>
+			<!--
+			<ol class="breadcrumb">
+				<li><a><i class="fa fa-dashboard"></i>调度中心</a></li>
+				<li class="active">使用教程</li>
+			</ol>
+			-->
+		</section>
+
+		<!-- Main content -->
+		<section class="content">
+
+            <!-- 简要报表 -->
+            <div class="row">
+
+                <#-- 任务信息 -->
+                <div class="col-md-4 col-sm-6 col-xs-12">
+                    <div class="info-box bg-aqua">
+                        <span class="info-box-icon"><i class="fa fa-flag-o"></i></span>
+
+                        <div class="info-box-content">
+                            <span class="info-box-text">任务数量</span>
+                            <span class="info-box-number">${jobInfoCount}</span>
+
+                            <div class="progress">
+                                <div class="progress-bar" style="width: 100%"></div>
+                            </div>
+                            <span class="progress-description">系统中配置的任务数量</span>
+                        </div>
+                    </div>
+                </div>
+
+                <#-- 调度信息 -->
+                <div class="col-md-4 col-sm-6 col-xs-12">
+                    <div class="info-box bg-yellow">
+                        <span class="info-box-icon"><i class="fa fa-calendar"></i></span>
+
+                        <div class="info-box-content">
+                            <span class="info-box-text">调度次数</span>
+                            <span class="info-box-number">${jobLogCount}</span>
+
+                            <div class="progress">
+                                <div class="progress-bar" style="width: ${(jobLogSuccessCount*100/jobLogCount)?string("0.00")}%"></div>
+                            </div>
+                            <span class="progress-description">
+                                调度成功率:${(jobLogSuccessCount*100/jobLogCount)?string("0.00")}<small>%</small>
+                            </span>
+                        </div>
+                    </div>
+                </div>
+
+                <#-- 执行器 -->
+                <div class="col-md-4 col-sm-6 col-xs-12">
+                    <div class="info-box bg-green">
+                        <span class="info-box-icon"><i class="fa fa-thumbs-o-up"></i></span>
+
+                        <div class="info-box-content">
+                            <span class="info-box-text">执行器数量</span>
+                            <span class="info-box-number">${executorCount}</span>
+
+                            <div class="progress">
+                                <div class="progress-bar" style="width: 100%"></div>
+                            </div>
+                            <span class="progress-description">心跳检测成功的执行器机器数量</span>
+                        </div>
+                    </div>
+                </div>
+
+            </div>
+            <!-- /.row -->
+
+		</section>
+		<!-- /.content -->
+	</div>
+	<!-- /.content-wrapper -->
+	
+	<!-- footer -->
+	<@netCommon.commonFooter />
+</div>
+<@netCommon.commonScript />
+</body>
+</html>

+ 1 - 1
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl

@@ -25,7 +25,7 @@
 	<div class="content-wrapper">
 		<!-- Content Header (Page header) -->
 		<section class="content-header">
-			<h1>调度管理<small>任务调度中心</small></h1>
+			<h1>任务管理<small>任务调度中心</small></h1>
 			<!--
 			<ol class="breadcrumb">
 				<li><a><i class="fa fa-dashboard"></i>调度管理</a></li>

+ 1 - 1
xxl-job-admin/src/main/webapp/static/js/joblog.detail.1.js

@@ -47,7 +47,7 @@ $(function() {
 
                         // valid end
                         if (data.content.end) {
-                            logRunStop('<span style="color: green;">[Rolling Log Finish]</span>');
+                            logRunStop('<br><span style="color: green;">[Rolling Log Finish]</span>');
                             return;
                         }