[Improvement][Monitor] Show master && worker Busy Or Normal Status and Show Commands table list (#15978)
* update * test * add monitor enhance ui * update * update * update doc * fix spotless * update * update * Update dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataAnalysisController.java Co-authored-by: Wenjun Ruan <wenjun@apache.org> * Update dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/DataAnalysisController.java Co-authored-by: Wenjun Ruan <wenjun@apache.org> * Update dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ErrorCommandMapper.java Co-authored-by: Wenjun Ruan <wenjun@apache.org> * Update dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ErrorCommandMapper.xml Co-authored-by: Wenjun Ruan <wenjun@apache.org> * Update dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/CommandMapper.java Co-authored-by: Wenjun Ruan <wenjun@apache.org> * Update dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ErrorCommandMapper.xml Co-authored-by: Wenjun Ruan <wenjun@apache.org> * update * fix spotless * update --------- Co-authored-by: Wenjun Ruan <wenjun@apache.org>
@ -16,6 +16,12 @@
|
||||
|
||||
![worker](../../../img/new_ui/dev/monitor/worker.png)
|
||||
|
||||
### Alert Server
|
||||
|
||||
- Mainly related to alert server information.
|
||||
|
||||
![alert-server](../../../img/new_ui/dev/monitor/alert-server.png)
|
||||
|
||||
### Database
|
||||
|
||||
- Mainly the health status of the DB.
|
||||
@ -26,18 +32,17 @@
|
||||
|
||||
### Statistics
|
||||
|
||||
![statistics](../../../img/new_ui/dev/monitor/statistics.png)
|
||||
![Command Statistics List](../../../img/new_ui/dev/monitor/command-list.png)
|
||||
|
||||
| **Parameter** | **Description** |
|
||||
|----------------------------------------|----------------------------------------------------|
|
||||
| Number of commands wait to be executed | Statistics of the `t_ds_command` table data. |
|
||||
| The number of failed commands | Statistics of the `t_ds_error_command` table data. |
|
||||
| Number of tasks wait to run | Count the data of `task_queue` in the ZooKeeper. |
|
||||
| Number of tasks wait to be killed | Count the data of `task_kill` in the ZooKeeper. |
|
||||
Shows the command list in the system. Data is from the `t_ds_command` table.
|
||||
|
||||
![Failure Command Statistics List](../../../img/new_ui/dev/monitor/failure-command-list.png)
|
||||
|
||||
Shows the failure command list in the system. Data is from the `t_ds_error_command` table.
|
||||
|
||||
### Audit Log
|
||||
|
||||
The audit log provides information about who accesses the system and the operations made to the system and record related
|
||||
time, which strengthen the security of the system and maintenance.
|
||||
|
||||
![audit-log](../../../img/new_ui/dev/monitor/audit-log.jpg)
|
||||
![audit-log](../../../img/new_ui/dev/monitor/audit-log.png)
|
||||
|
@ -16,6 +16,12 @@
|
||||
|
||||
![worker](../../../img/new_ui/dev/monitor/worker.png)
|
||||
|
||||
### Alert Server
|
||||
|
||||
- 主要是 alert server 的相关信息。
|
||||
|
||||
![alert-server](../../../img/new_ui/dev/monitor/alert-server.png)
|
||||
|
||||
### Database
|
||||
|
||||
- 主要是 DB 的健康状况
|
||||
@ -26,15 +32,16 @@
|
||||
|
||||
### Statistics
|
||||
|
||||
![statistics](../../../img/new_ui/dev/monitor/statistics.png)
|
||||
![Command Statistics List](../../../img/new_ui/dev/monitor/command-list.png)
|
||||
|
||||
- 待执行命令数:统计 t_ds_command 表的数据
|
||||
- 执行失败的命令数:统计 t_ds_error_command 表的数据
|
||||
- 待运行任务数:统计 Zookeeper 中 task_queue 的数据
|
||||
- 待杀死任务数:统计 Zookeeper 中 task_kill 的数据
|
||||
展示系统中的命令列表,数据来自`t_ds_command`表。
|
||||
|
||||
![Failure Command Statistics List](../../../img/new_ui/dev/monitor/failure-command-list.png)
|
||||
|
||||
展示系统中的失败命令列表,数据来自`t_ds_error_command`表。
|
||||
|
||||
### 审计日志
|
||||
|
||||
审计日志的记录提供了有关谁访问了系统,以及他或她在给定时间段内执行了哪些操作的信息,他对于维护安全都很有用。
|
||||
审计日志的记录提供了有关谁访问了系统,以及他或她在给定时间段内执行了哪些操作的信息,对于维护安全都很有用。
|
||||
|
||||
![audit-log](../../../img/new_ui/dev/monitor/audit-log.jpg)
|
||||
![audit-log](../../../img/new_ui/dev/monitor/audit-log.png)
|
||||
|
BIN
docs/img/new_ui/dev/monitor/alert-server.png
Normal file
After Width: | Height: | Size: 135 KiB |
Before Width: | Height: | Size: 222 KiB |
BIN
docs/img/new_ui/dev/monitor/audit-log.png
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
docs/img/new_ui/dev/monitor/command-list.png
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
docs/img/new_ui/dev/monitor/failure-command-list.png
Normal file
After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 139 KiB |
@ -20,17 +20,21 @@ package org.apache.dolphinscheduler.api.controller;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.COMMAND_STATE_COUNT_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.COUNT_PROCESS_DEFINITION_USER_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.COUNT_PROCESS_INSTANCE_STATE_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.LIST_PAGING_ALERT_GROUP_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.QUEUE_COUNT_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.TASK_INSTANCE_STATE_COUNT_ERROR;
|
||||
|
||||
import org.apache.dolphinscheduler.api.dto.CommandStateCount;
|
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException;
|
||||
import org.apache.dolphinscheduler.api.service.DataAnalysisService;
|
||||
import org.apache.dolphinscheduler.api.utils.PageInfo;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.api.vo.TaskInstanceCountVO;
|
||||
import org.apache.dolphinscheduler.api.vo.WorkflowDefinitionCountVO;
|
||||
import org.apache.dolphinscheduler.api.vo.WorkflowInstanceCountVO;
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.dao.entity.Command;
|
||||
import org.apache.dolphinscheduler.dao.entity.ErrorCommand;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import java.util.List;
|
||||
@ -148,4 +152,54 @@ public class DataAnalysisController extends BaseController {
|
||||
Map<String, Integer> stringIntegerMap = dataAnalysisService.countQueueState(loginUser);
|
||||
return Result.success(stringIntegerMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* command queue
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return queue state count
|
||||
*/
|
||||
@Operation(summary = "listPendingCommands", description = "LIST_PENDING_COMMANDS")
|
||||
@Parameters({
|
||||
@Parameter(name = "searchVal", description = "SEARCH_VAL", schema = @Schema(implementation = String.class)),
|
||||
@Parameter(name = "pageNo", description = "PAGE_NO", required = true, schema = @Schema(implementation = int.class, example = "1")),
|
||||
@Parameter(name = "pageSize", description = "PAGE_SIZE", required = true, schema = @Schema(implementation = int.class, example = "20"))
|
||||
})
|
||||
@GetMapping("/listCommand")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(LIST_PAGING_ALERT_GROUP_ERROR)
|
||||
public Result<PageInfo<Command>> listPaging(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
|
||||
@RequestParam(value = "projectCode", required = false) Long projectCode,
|
||||
@RequestParam("pageNo") Integer pageNo,
|
||||
@RequestParam("pageSize") Integer pageSize) {
|
||||
checkPageParams(pageNo, pageSize);
|
||||
PageInfo<Command> commandPageInfo =
|
||||
dataAnalysisService.listPendingCommands(loginUser, projectCode, pageNo, pageSize);
|
||||
return Result.success(commandPageInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* error command
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return queue state count
|
||||
*/
|
||||
@Operation(summary = "listErrorCommand", description = "LIST_ERROR_COMMAND_LIST_PAGING_NOTES")
|
||||
@Parameters({
|
||||
@Parameter(name = "searchVal", description = "SEARCH_VAL", schema = @Schema(implementation = String.class)),
|
||||
@Parameter(name = "pageNo", description = "PAGE_NO", required = true, schema = @Schema(implementation = int.class, example = "1")),
|
||||
@Parameter(name = "pageSize", description = "PAGE_SIZE", required = true, schema = @Schema(implementation = int.class, example = "20"))
|
||||
})
|
||||
@GetMapping("/listErrorCommand")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(LIST_PAGING_ALERT_GROUP_ERROR)
|
||||
public Result<PageInfo<ErrorCommand>> listErrorCommand(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
|
||||
@RequestParam(value = "projectCode", required = false) Long projectCode,
|
||||
@RequestParam("pageNo") Integer pageNo,
|
||||
@RequestParam("pageSize") Integer pageSize) {
|
||||
checkPageParams(pageNo, pageSize);
|
||||
PageInfo<ErrorCommand> errorCommandPageInfo =
|
||||
dataAnalysisService.listErrorCommand(loginUser, projectCode, pageNo, pageSize);
|
||||
return Result.success(errorCommandPageInfo);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
package org.apache.dolphinscheduler.api.controller;
|
||||
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.LIST_MASTERS_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.LIST_WORKERS_ERROR;
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_DATABASE_STATE_ERROR;
|
||||
|
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException;
|
||||
@ -26,15 +25,16 @@ import org.apache.dolphinscheduler.api.service.MonitorService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.common.model.Server;
|
||||
import org.apache.dolphinscheduler.common.model.WorkerServerModel;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.plugin.api.monitor.DatabaseMetrics;
|
||||
import org.apache.dolphinscheduler.registry.api.enums.RegistryNodeType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
@ -56,35 +56,19 @@ public class MonitorController extends BaseController {
|
||||
private MonitorService monitorService;
|
||||
|
||||
/**
|
||||
* master list
|
||||
* server list
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return master list
|
||||
* @return server list
|
||||
*/
|
||||
@Operation(summary = "listMaster", description = "MASTER_LIST_NOTES")
|
||||
@GetMapping(value = "/masters")
|
||||
@Operation(summary = "listServer", description = "SERVER_LIST_NOTES")
|
||||
@GetMapping(value = "/{nodeType}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(LIST_MASTERS_ERROR)
|
||||
public Result<List<Server>> listMaster(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
|
||||
List<Server> servers = monitorService.queryMaster(loginUser);
|
||||
public Result<List<Server>> listServer(@PathVariable("nodeType") RegistryNodeType nodeType) {
|
||||
List<Server> servers = monitorService.listServer(nodeType);
|
||||
return Result.success(servers);
|
||||
}
|
||||
|
||||
/**
|
||||
* worker list
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return worker information list
|
||||
*/
|
||||
@Operation(summary = "listWorker", description = "WORKER_LIST_NOTES")
|
||||
@GetMapping(value = "/workers")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(LIST_WORKERS_ERROR)
|
||||
public Result<List<WorkerServerModel>> listWorker(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
|
||||
List<WorkerServerModel> workerServerModels = monitorService.queryWorker(loginUser);
|
||||
return Result.success(workerServerModels);
|
||||
}
|
||||
|
||||
/**
|
||||
* query database state
|
||||
*
|
||||
|
@ -21,9 +21,12 @@ import org.apache.dolphinscheduler.api.dto.CommandStateCount;
|
||||
import org.apache.dolphinscheduler.api.dto.DefineUserDto;
|
||||
import org.apache.dolphinscheduler.api.dto.TaskCountDto;
|
||||
import org.apache.dolphinscheduler.api.dto.project.StatisticsStateRequest;
|
||||
import org.apache.dolphinscheduler.api.utils.PageInfo;
|
||||
import org.apache.dolphinscheduler.api.vo.TaskInstanceCountVO;
|
||||
import org.apache.dolphinscheduler.api.vo.WorkflowDefinitionCountVO;
|
||||
import org.apache.dolphinscheduler.api.vo.WorkflowInstanceCountVO;
|
||||
import org.apache.dolphinscheduler.dao.entity.Command;
|
||||
import org.apache.dolphinscheduler.dao.entity.ErrorCommand;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import java.util.List;
|
||||
@ -117,4 +120,7 @@ public interface DataAnalysisService {
|
||||
*/
|
||||
TaskCountDto countOneTaskStates(User loginUser, Long taskCode);
|
||||
|
||||
PageInfo<Command> listPendingCommands(User loginUser, Long projectCode, Integer pageNo, Integer pageSize);
|
||||
|
||||
PageInfo<ErrorCommand> listErrorCommand(User loginUser, Long projectCode, Integer pageNo, Integer pageSize);
|
||||
}
|
||||
|
@ -18,9 +18,9 @@
|
||||
package org.apache.dolphinscheduler.api.service;
|
||||
|
||||
import org.apache.dolphinscheduler.common.model.Server;
|
||||
import org.apache.dolphinscheduler.common.model.WorkerServerModel;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.plugin.api.monitor.DatabaseMetrics;
|
||||
import org.apache.dolphinscheduler.registry.api.enums.RegistryNodeType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -38,20 +38,10 @@ public interface MonitorService {
|
||||
List<DatabaseMetrics> queryDatabaseState(User loginUser);
|
||||
|
||||
/**
|
||||
* query master list
|
||||
* query server list
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return master information list
|
||||
* @param nodeType RegistryNodeType
|
||||
* @return server information list
|
||||
*/
|
||||
List<Server> queryMaster(User loginUser);
|
||||
|
||||
/**
|
||||
* query worker list
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return worker information list
|
||||
*/
|
||||
List<WorkerServerModel> queryWorker(User loginUser);
|
||||
|
||||
List<Server> getServerListFromRegistry(boolean isMaster);
|
||||
List<Server> listServer(RegistryNodeType nodeType);
|
||||
}
|
||||
|
@ -27,14 +27,18 @@ import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException;
|
||||
import org.apache.dolphinscheduler.api.service.DataAnalysisService;
|
||||
import org.apache.dolphinscheduler.api.service.ProjectService;
|
||||
import org.apache.dolphinscheduler.api.utils.PageInfo;
|
||||
import org.apache.dolphinscheduler.api.vo.TaskInstanceCountVO;
|
||||
import org.apache.dolphinscheduler.api.vo.WorkflowDefinitionCountVO;
|
||||
import org.apache.dolphinscheduler.api.vo.WorkflowInstanceCountVO;
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
|
||||
import org.apache.dolphinscheduler.common.enums.CommandType;
|
||||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
import org.apache.dolphinscheduler.common.utils.DateUtils;
|
||||
import org.apache.dolphinscheduler.dao.entity.Command;
|
||||
import org.apache.dolphinscheduler.dao.entity.CommandCount;
|
||||
import org.apache.dolphinscheduler.dao.entity.ErrorCommand;
|
||||
import org.apache.dolphinscheduler.dao.entity.ExecuteStatusCount;
|
||||
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
|
||||
import org.apache.dolphinscheduler.dao.entity.Project;
|
||||
@ -71,6 +75,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
@ -380,6 +386,66 @@ public class DataAnalysisServiceImpl extends BaseServiceImpl implements DataAnal
|
||||
return new TaskCountDto(executeStatusCounts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<Command> listPendingCommands(User loginUser, Long projectCode, Integer pageNo, Integer pageSize) {
|
||||
Page<Command> page = new Page<>(pageNo, pageSize);
|
||||
if (loginUser.getUserType().equals(UserType.ADMIN_USER)) {
|
||||
IPage<Command> commandIPage = commandMapper.queryCommandPage(page);
|
||||
return PageInfo.of(commandIPage);
|
||||
}
|
||||
|
||||
List<Long> workflowDefinitionCodes = getAuthDefinitionCodes(loginUser, projectCode);
|
||||
|
||||
if (workflowDefinitionCodes.isEmpty()) {
|
||||
return PageInfo.of(pageNo, pageSize);
|
||||
}
|
||||
|
||||
IPage<Command> commandIPage =
|
||||
commandMapper.queryCommandPageByIds(page, new ArrayList<>(workflowDefinitionCodes));
|
||||
return PageInfo.of(commandIPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<ErrorCommand> listErrorCommand(User loginUser, Long projectCode, Integer pageNo, Integer pageSize) {
|
||||
Page<ErrorCommand> page = new Page<>(pageNo, pageSize);
|
||||
if (loginUser.getUserType().equals(UserType.ADMIN_USER)) {
|
||||
IPage<ErrorCommand> commandIPage = errorCommandMapper.queryErrorCommandPage(page);
|
||||
return PageInfo.of(commandIPage);
|
||||
}
|
||||
|
||||
List<Long> workflowDefinitionCodes = getAuthDefinitionCodes(loginUser, projectCode);
|
||||
|
||||
if (workflowDefinitionCodes.isEmpty()) {
|
||||
return PageInfo.of(pageNo, pageSize);
|
||||
}
|
||||
|
||||
IPage<ErrorCommand> commandIPage =
|
||||
errorCommandMapper.queryErrorCommandPageByIds(page, new ArrayList<>(workflowDefinitionCodes));
|
||||
return PageInfo.of(commandIPage);
|
||||
}
|
||||
|
||||
private List<Long> getAuthDefinitionCodes(User loginUser, Long projectCode) {
|
||||
Set<Integer> projectIds = resourcePermissionCheckService
|
||||
.userOwnedResourceIdsAcquisition(AuthorizationType.PROJECTS, loginUser.getId(), log);
|
||||
if (CollectionUtils.isEmpty(projectIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Long> projectCodes = projectMapper.selectBatchIds(projectIds)
|
||||
.stream()
|
||||
.map(Project::getCode)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (projectCode != null) {
|
||||
if (!projectCodes.contains(projectCode)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
projectCodes = Collections.singletonList(projectCode);
|
||||
}
|
||||
|
||||
return processDefinitionMapper.queryDefinitionCodeListByProjectCodes(projectCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* statistics the process definition quantities of a certain person
|
||||
* <p>
|
||||
|
@ -90,6 +90,7 @@ import org.apache.dolphinscheduler.extract.master.transportor.StreamingTaskTrigg
|
||||
import org.apache.dolphinscheduler.extract.master.transportor.StreamingTaskTriggerResponse;
|
||||
import org.apache.dolphinscheduler.extract.master.transportor.WorkflowInstanceStateChangeEvent;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskConstants;
|
||||
import org.apache.dolphinscheduler.registry.api.enums.RegistryNodeType;
|
||||
import org.apache.dolphinscheduler.service.command.CommandService;
|
||||
import org.apache.dolphinscheduler.service.cron.CronUtils;
|
||||
import org.apache.dolphinscheduler.service.exceptions.CronParseException;
|
||||
@ -289,7 +290,7 @@ public class ExecutorServiceImpl extends BaseServiceImpl implements ExecutorServ
|
||||
|
||||
private void checkMasterExists() {
|
||||
// check master server exists
|
||||
List<Server> masterServers = monitorService.getServerListFromRegistry(true);
|
||||
List<Server> masterServers = monitorService.listServer(RegistryNodeType.MASTER);
|
||||
|
||||
// no master
|
||||
if (masterServers.isEmpty()) {
|
||||
@ -1142,7 +1143,7 @@ public class ExecutorServiceImpl extends BaseServiceImpl implements ExecutorServ
|
||||
checkValidTenant(tenantCode);
|
||||
checkMasterExists();
|
||||
// todo dispatch improvement
|
||||
List<Server> masterServerList = monitorService.getServerListFromRegistry(true);
|
||||
List<Server> masterServerList = monitorService.listServer(RegistryNodeType.MASTER);
|
||||
Server server = masterServerList.get(0);
|
||||
|
||||
StreamingTaskTriggerRequest taskExecuteStartMessage = new StreamingTaskTriggerRequest();
|
||||
|
@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.api.service.impl;
|
||||
|
||||
import org.apache.dolphinscheduler.api.service.MonitorService;
|
||||
import org.apache.dolphinscheduler.common.model.Server;
|
||||
import org.apache.dolphinscheduler.common.model.WorkerServerModel;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.plugin.api.monitor.DatabaseMetrics;
|
||||
import org.apache.dolphinscheduler.dao.plugin.api.monitor.DatabaseMonitor;
|
||||
@ -27,7 +26,6 @@ import org.apache.dolphinscheduler.registry.api.RegistryClient;
|
||||
import org.apache.dolphinscheduler.registry.api.enums.RegistryNodeType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -35,7 +33,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* monitor service impl
|
||||
@ -61,48 +58,8 @@ public class MonitorServiceImpl extends BaseServiceImpl implements MonitorServic
|
||||
return Lists.newArrayList(databaseMonitor.getDatabaseMetrics());
|
||||
}
|
||||
|
||||
/**
|
||||
* query master list
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return master information list
|
||||
*/
|
||||
@Override
|
||||
public List<Server> queryMaster(User loginUser) {
|
||||
return registryClient.getServerList(RegistryNodeType.MASTER);
|
||||
public List<Server> listServer(RegistryNodeType nodeType) {
|
||||
return registryClient.getServerList(nodeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* query worker list
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @return worker information list
|
||||
*/
|
||||
@Override
|
||||
public List<WorkerServerModel> queryWorker(User loginUser) {
|
||||
|
||||
return registryClient.getServerList(RegistryNodeType.WORKER)
|
||||
.stream()
|
||||
.map((Server server) -> {
|
||||
WorkerServerModel model = new WorkerServerModel();
|
||||
model.setId(server.getId());
|
||||
model.setHost(server.getHost());
|
||||
model.setPort(server.getPort());
|
||||
model.setZkDirectories(Sets.newHashSet(server.getZkDirectory()));
|
||||
model.setResInfo(server.getResInfo());
|
||||
model.setCreateTime(server.getCreateTime());
|
||||
model.setLastHeartbeatTime(server.getLastHeartbeatTime());
|
||||
return model;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getServerListFromRegistry(boolean isMaster) {
|
||||
return isMaster
|
||||
? registryClient.getServerList(RegistryNodeType.MASTER)
|
||||
: registryClient.getServerList(RegistryNodeType.WORKER);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,8 +41,7 @@ public class MonitorControllerTest extends AbstractControllerTest {
|
||||
|
||||
@Test
|
||||
public void testListMaster() throws Exception {
|
||||
|
||||
MvcResult mvcResult = mockMvc.perform(get("/monitor/masters")
|
||||
MvcResult mvcResult = mockMvc.perform(get("/monitor/MASTER")
|
||||
.header(SESSION_ID, sessionId)
|
||||
/* .param("type", ResourceType.FILE.name()) */)
|
||||
.andExpect(status().isOk())
|
||||
@ -59,7 +58,24 @@ public class MonitorControllerTest extends AbstractControllerTest {
|
||||
@Test
|
||||
public void testListWorker() throws Exception {
|
||||
|
||||
MvcResult mvcResult = mockMvc.perform(get("/monitor/workers")
|
||||
MvcResult mvcResult = mockMvc.perform(get("/monitor/WORKER")
|
||||
.header(SESSION_ID, sessionId)
|
||||
/* .param("type", ResourceType.FILE.name()) */)
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andReturn();
|
||||
|
||||
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
|
||||
result.getCode().equals(Status.SUCCESS.getCode());
|
||||
|
||||
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
|
||||
logger.info(mvcResult.getResponse().getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListAlert() throws Exception {
|
||||
|
||||
MvcResult mvcResult = mockMvc.perform(get("/monitor/ALERT_SERVER")
|
||||
.header(SESSION_ID, sessionId)
|
||||
/* .param("type", ResourceType.FILE.name()) */)
|
||||
.andExpect(status().isOk())
|
||||
@ -76,8 +92,7 @@ public class MonitorControllerTest extends AbstractControllerTest {
|
||||
@Test
|
||||
public void testQueryDatabaseState() throws Exception {
|
||||
MvcResult mvcResult = mockMvc.perform(get("/monitor/databases")
|
||||
.header(SESSION_ID, sessionId)
|
||||
/* .param("type", ResourceType.FILE.name()) */)
|
||||
.header(SESSION_ID, sessionId))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andReturn();
|
||||
|
@ -67,6 +67,7 @@ import org.apache.dolphinscheduler.dao.mapper.TaskDefinitionMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.TaskGroupQueueMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
|
||||
import org.apache.dolphinscheduler.dao.repository.ProcessInstanceDao;
|
||||
import org.apache.dolphinscheduler.registry.api.enums.RegistryNodeType;
|
||||
import org.apache.dolphinscheduler.service.command.CommandService;
|
||||
import org.apache.dolphinscheduler.service.process.ProcessService;
|
||||
import org.apache.dolphinscheduler.service.process.TriggerRelationService;
|
||||
@ -242,7 +243,7 @@ public class ExecuteFunctionServiceTest {
|
||||
Mockito.when(processService.getTenantForProcess(tenantCode, userId)).thenReturn(tenantCode);
|
||||
doReturn(1).when(commandService).createCommand(argThat(c -> c.getId() == null));
|
||||
doReturn(0).when(commandService).createCommand(argThat(c -> c.getId() != null));
|
||||
Mockito.when(monitorService.getServerListFromRegistry(true)).thenReturn(getMasterServersList());
|
||||
Mockito.when(monitorService.listServer(RegistryNodeType.MASTER)).thenReturn(getMasterServersList());
|
||||
Mockito.when(processService.findProcessInstanceDetailById(processInstanceId))
|
||||
.thenReturn(Optional.ofNullable(processInstance));
|
||||
Mockito.when(processService.findProcessDefinition(1L, 1)).thenReturn(this.processDefinition);
|
||||
@ -498,7 +499,7 @@ public class ExecuteFunctionServiceTest {
|
||||
|
||||
@Test
|
||||
public void testNoMasterServers() {
|
||||
Mockito.when(monitorService.getServerListFromRegistry(true)).thenReturn(new ArrayList<>());
|
||||
Mockito.when(monitorService.listServer(RegistryNodeType.MASTER)).thenReturn(new ArrayList<>());
|
||||
|
||||
Assertions.assertThrows(ServiceException.class, () -> executorService.execProcessInstance(
|
||||
loginUser,
|
||||
|
@ -98,13 +98,13 @@ public class MonitorServiceTest {
|
||||
public void testQueryMaster() {
|
||||
mockPermissionCheck(ApiFuncIdentificationConstant.MONITOR_MASTER_VIEW, true);
|
||||
Mockito.when(registryClient.getServerList(RegistryNodeType.MASTER)).thenReturn(getServerList());
|
||||
assertDoesNotThrow(() -> monitorService.queryMaster(user));
|
||||
assertDoesNotThrow(() -> monitorService.listServer(RegistryNodeType.MASTER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryWorker() {
|
||||
Mockito.when(registryClient.getServerList(RegistryNodeType.WORKER)).thenReturn(getServerList());
|
||||
AssertionsHelper.assertDoesNotThrow(() -> monitorService.queryWorker(user));
|
||||
AssertionsHelper.assertDoesNotThrow(() -> monitorService.listServer(RegistryNodeType.WORKER));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -26,6 +26,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
/**
|
||||
* command mapper interface
|
||||
@ -50,7 +52,7 @@ public interface CommandMapper extends BaseMapper<Command> {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Command> queryCommandPage(@Param("limit") int limit, @Param("offset") int offset);
|
||||
IPage<Command> queryCommandPage(Page<Command> page);
|
||||
|
||||
List<Command> queryCommandByIdSlot(@Param("currentSlotIndex") int currentSlotIndex,
|
||||
@Param("totalSlot") int totalSlot,
|
||||
@ -58,4 +60,7 @@ public interface CommandMapper extends BaseMapper<Command> {
|
||||
@Param("fetchNumber") int fetchNum);
|
||||
|
||||
void deleteByWorkflowInstanceIds(@Param("workflowInstanceIds") List<Integer> workflowInstanceIds);
|
||||
|
||||
IPage<Command> queryCommandPageByIds(Page<Command> page,
|
||||
@Param("workflowDefinitionCodes") List<Long> workflowDefinitionCodes);
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
/**
|
||||
* error command mapper interface
|
||||
@ -43,4 +45,9 @@ public interface ErrorCommandMapper extends BaseMapper<ErrorCommand> {
|
||||
@Param("startTime") Date startTime,
|
||||
@Param("endTime") Date endTime,
|
||||
@Param("projectCodes") List<Long> projectCodes);
|
||||
|
||||
IPage<ErrorCommand> queryErrorCommandPage(Page<ErrorCommand> page);
|
||||
|
||||
IPage<ErrorCommand> queryErrorCommandPageByIds(Page<ErrorCommand> page,
|
||||
@Param("workflowDefinitionCodes") List<Long> workflowDefinitionCodes);
|
||||
}
|
||||
|
@ -188,4 +188,5 @@ public interface ProcessDefinitionMapper extends BaseMapper<ProcessDefinition> {
|
||||
* @return project ids list
|
||||
*/
|
||||
List<Integer> listProjectIds();
|
||||
List<Long> queryDefinitionCodeListByProjectCodes(@Param("projectCodes") List<Long> projectCodes);
|
||||
}
|
||||
|
@ -34,10 +34,22 @@
|
||||
group by cmd.command_type
|
||||
</select>
|
||||
<select id="queryCommandPage" resultType="org.apache.dolphinscheduler.dao.entity.Command">
|
||||
select *
|
||||
select
|
||||
*
|
||||
from t_ds_command
|
||||
where 1 = 1
|
||||
order by process_instance_priority, id asc
|
||||
</select>
|
||||
|
||||
<select id="queryCommandPageByIds" resultType="org.apache.dolphinscheduler.dao.entity.Command">
|
||||
select
|
||||
*
|
||||
from t_ds_command
|
||||
where process_definition_code in
|
||||
<foreach item="id" index="index" collection="workflowDefinitionCodes" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
order by process_instance_priority, id asc
|
||||
limit #{limit} offset #{offset}
|
||||
</select>
|
||||
|
||||
<select id="queryCommandByIdSlot" resultType="org.apache.dolphinscheduler.dao.entity.Command">
|
||||
|
@ -33,4 +33,23 @@
|
||||
</if>
|
||||
group by cmd.command_type
|
||||
</select>
|
||||
|
||||
<select id="queryErrorCommandPage" resultType="org.apache.dolphinscheduler.dao.entity.ErrorCommand">
|
||||
select
|
||||
*
|
||||
from t_ds_error_command
|
||||
|
||||
order by process_instance_priority, id asc
|
||||
</select>
|
||||
|
||||
<select id="queryErrorCommandPageByIds" resultType="org.apache.dolphinscheduler.dao.entity.ErrorCommand">
|
||||
select
|
||||
*
|
||||
from t_ds_error_command
|
||||
where process_definition_code in
|
||||
<foreach item="id" index="index" collection="workflowDefinitionCodes" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
order by process_instance_priority, id asc
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -208,4 +208,14 @@
|
||||
SELECT DISTINCT(id) as project_id
|
||||
FROM t_ds_project
|
||||
</select>
|
||||
|
||||
<select id="queryDefinitionCodeListByProjectCodes" resultType="java.lang.Long">
|
||||
select
|
||||
code
|
||||
from t_ds_process_definition
|
||||
where project_code in
|
||||
<foreach collection="projectCodes" index="index" item="i" open="(" separator="," close=")">
|
||||
#{i}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -42,6 +42,7 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
@ -135,7 +136,7 @@ public class CommandMapperTest extends BaseDaoTest {
|
||||
|
||||
createCommand(CommandType.START_PROCESS, processDefinition.getCode());
|
||||
|
||||
List<Command> actualCommand = commandMapper.queryCommandPage(1, 0);
|
||||
List<Command> actualCommand = commandMapper.selectList(new QueryWrapper<>());
|
||||
|
||||
Assertions.assertNotNull(actualCommand);
|
||||
}
|
||||
|
@ -37,5 +37,4 @@ public enum RegistryNodeType {
|
||||
private final String name;
|
||||
|
||||
private final String registryPath;
|
||||
|
||||
}
|
||||
|
@ -255,6 +255,10 @@ export function useDataList() {
|
||||
label: t('menu.worker'),
|
||||
key: '/monitor/worker'
|
||||
},
|
||||
{
|
||||
label: t('menu.alert_server'),
|
||||
key: '/monitor/alert_server'
|
||||
},
|
||||
{
|
||||
label: t('menu.db'),
|
||||
key: '/monitor/db'
|
||||
|
@ -40,6 +40,7 @@ export default {
|
||||
service_manage: 'Service Manage',
|
||||
master: 'Master',
|
||||
worker: 'Worker',
|
||||
alert_server: 'Alert Server',
|
||||
db: 'DB',
|
||||
statistical_manage: 'Statistical Manage',
|
||||
statistics: 'Statistics',
|
||||
|
@ -35,6 +35,7 @@ export default {
|
||||
memory_usage: 'Memory Usage',
|
||||
disk_available: 'Disk Available',
|
||||
load_average: 'Load Average',
|
||||
thread_pool_usage: 'Thread Pool Usage',
|
||||
create_time: 'Create Time',
|
||||
last_heartbeat_time: 'Last Heartbeat Time',
|
||||
directory_detail: 'Directory Detail',
|
||||
@ -44,6 +45,11 @@ export default {
|
||||
worker_no_data_result_desc:
|
||||
'Currently, there are no worker nodes exist, please create a worker node and refresh this page'
|
||||
},
|
||||
alert_server: {
|
||||
alert_server_no_data_result_title: 'No Alert Server Nodes Exist',
|
||||
alert_server_no_data_result_desc:
|
||||
'Currently, there are no alert server nodes exist, please create a alert server node and refresh this page'
|
||||
},
|
||||
db: {
|
||||
health_state: 'Health State',
|
||||
max_connections: 'Max Connections',
|
||||
|
@ -41,6 +41,7 @@ export default {
|
||||
service_manage: '服务管理',
|
||||
master: 'Master',
|
||||
worker: 'Worker',
|
||||
alert_server: 'Alert Server',
|
||||
db: 'DB',
|
||||
statistical_manage: '统计管理',
|
||||
statistics: 'Statistics',
|
||||
|
@ -35,6 +35,7 @@ export default {
|
||||
memory_usage: '内存使用量',
|
||||
disk_available: '磁盘可用容量',
|
||||
load_average: '平均负载量',
|
||||
thread_pool_usage: '线程池使用量',
|
||||
create_time: '创建时间',
|
||||
last_heartbeat_time: '最后心跳时间',
|
||||
directory_detail: '目录详情',
|
||||
@ -44,6 +45,11 @@ export default {
|
||||
worker_no_data_result_desc:
|
||||
'目前没有任何Worker节点,请先创建Worker节点,再访问该页面'
|
||||
},
|
||||
alert_server: {
|
||||
alert_server_no_data_result_title: 'Alert Server节点不存在',
|
||||
alert_server_no_data_result_desc:
|
||||
'目前没有任何Alert Server节点,请先创建Alert Server节点,再访问该页面'
|
||||
},
|
||||
db: {
|
||||
health_state: '健康状态',
|
||||
max_connections: '最大连接数',
|
||||
|
@ -51,6 +51,17 @@ export default {
|
||||
auth: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/monitor/alert_server',
|
||||
name: 'servers-alert-server',
|
||||
component: components['monitor-servers-alert_server'],
|
||||
meta: {
|
||||
title: '服务管理-Alert Server',
|
||||
activeMenu: 'monitor',
|
||||
showSide: true,
|
||||
auth: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/monitor/db',
|
||||
name: 'servers-db',
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
import { axios } from '@/service/service'
|
||||
import type { ServerNodeType } from './types'
|
||||
|
||||
export function queryDatabaseState(): any {
|
||||
return axios({
|
||||
@ -37,3 +38,10 @@ export function listWorker(): any {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function listMonitorServerNode(nodeType: ServerNodeType): any {
|
||||
return axios({
|
||||
url: `/monitor/${nodeType}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
@ -25,7 +25,9 @@ interface DatabaseRes {
|
||||
date: string
|
||||
}
|
||||
|
||||
interface MasterNode {
|
||||
type ServerNodeType = 'MASTER' | 'WORKER' | 'ALERT_SERVER'
|
||||
|
||||
interface ServerNode {
|
||||
id: number
|
||||
host: string
|
||||
port: number
|
||||
@ -35,14 +37,23 @@ interface MasterNode {
|
||||
lastHeartbeatTime: string
|
||||
}
|
||||
|
||||
interface WorkerNode {
|
||||
id: number
|
||||
host: string
|
||||
port: number
|
||||
zkDirectories: Array<string>
|
||||
resInfo: string
|
||||
createTime: string
|
||||
lastHeartbeatTime: string
|
||||
interface MasterNode extends ServerNode {
|
||||
serverStatus?: 'NORMAL' | 'BUZY'
|
||||
}
|
||||
|
||||
export { DatabaseRes, MasterNode, WorkerNode }
|
||||
interface WorkerNode extends ServerNode {
|
||||
serverStatus?: 'NORMAL' | 'BUZY'
|
||||
workerHostWeight?: number
|
||||
threadPoolUsage?: number
|
||||
}
|
||||
|
||||
interface AlertNode extends MasterNode {}
|
||||
|
||||
export {
|
||||
DatabaseRes,
|
||||
MasterNode,
|
||||
WorkerNode,
|
||||
ServerNodeType,
|
||||
ServerNode,
|
||||
AlertNode
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { axios } from '@/service/service'
|
||||
import { CodeReq, StateReq } from './types'
|
||||
import { ListReq, CodeReq, StateReq } from './types'
|
||||
|
||||
export function countCommandState(): any {
|
||||
return axios({
|
||||
@ -55,3 +55,19 @@ export function countTaskState(params: StateReq): any {
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function queryListCommandPaging(params: ListReq): any {
|
||||
return axios({
|
||||
url: '/projects/analysis/listCommand',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function queryListErrorCommandPaging(params: ListReq): any {
|
||||
return axios({
|
||||
url: '/projects/analysis/listErrorCommand',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
@ -66,6 +66,12 @@ interface CommandStateRes {
|
||||
commandState: string
|
||||
}
|
||||
|
||||
interface ListReq {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
searchVal?: string
|
||||
}
|
||||
|
||||
export {
|
||||
CodeReq,
|
||||
StateReq,
|
||||
@ -73,5 +79,6 @@ export {
|
||||
WorkflowInstanceCountVo,
|
||||
TaskInstanceCountVo,
|
||||
TaskQueueRes,
|
||||
CommandStateRes
|
||||
CommandStateRes,
|
||||
ListReq
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@mixin base {
|
||||
font-size: 5vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.card {
|
||||
@include base;
|
||||
}
|
||||
|
||||
.load-average {
|
||||
@include base;
|
||||
color: var(--n-color-target);
|
||||
}
|
||||
|
||||
.link-btn {
|
||||
color: var(--n-color-target);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: var(--n-color-target);
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineComponent, onMounted, ref, toRefs } from 'vue'
|
||||
import { NGrid, NGi, NCard, NNumberAnimation, NSpace, NTag } from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useServerNode } from './use-server-node'
|
||||
import styles from './index.module.scss'
|
||||
import Card from '@/components/card'
|
||||
import Result from '@/components/result'
|
||||
import Gauge from '@/components/chart/modules/Gauge'
|
||||
import NodeModal from './node-modal'
|
||||
import type { Ref } from 'vue'
|
||||
import type { RowData } from 'naive-ui/es/data-table/src/interface'
|
||||
import type { AlertNode } from '@/service/modules/monitor/types'
|
||||
import { capitalize } from 'lodash'
|
||||
|
||||
const alertServer = defineComponent({
|
||||
name: 'alertServer',
|
||||
setup() {
|
||||
const showModalRef = ref(false)
|
||||
const { t } = useI18n()
|
||||
const { variables, getTableData } = useServerNode()
|
||||
const zkDirectoryRef: Ref<Array<RowData>> = ref([])
|
||||
|
||||
const clickDetails = (zkDirectories: string) => {
|
||||
zkDirectoryRef.value = [{ directory: zkDirectories, index: 1 }]
|
||||
showModalRef.value = true
|
||||
}
|
||||
|
||||
const onConfirmModal = () => {
|
||||
showModalRef.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
})
|
||||
|
||||
return {
|
||||
t,
|
||||
...toRefs(variables),
|
||||
clickDetails,
|
||||
onConfirmModal,
|
||||
showModalRef,
|
||||
zkDirectoryRef
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { t, clickDetails, onConfirmModal, showModalRef, zkDirectoryRef } =
|
||||
this
|
||||
|
||||
const renderNodeServerStatusTag = (item: AlertNode) => {
|
||||
const serverStatus = JSON.parse(item.resInfo)?.serverStatus
|
||||
|
||||
if (!serverStatus) return ''
|
||||
|
||||
return (
|
||||
<NTag type={serverStatus === 'NORMAL' ? 'info' : 'warning'}>
|
||||
{capitalize(serverStatus)}
|
||||
</NTag>
|
||||
)
|
||||
}
|
||||
|
||||
return this.data.length < 1 ? (
|
||||
<Result
|
||||
title={t('monitor.alert_server.alert_server_no_data_result_title')}
|
||||
description={t('monitor.alert_server.alert_server_no_data_result_desc')}
|
||||
status={'info'}
|
||||
size={'medium'}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<NSpace vertical size={25}>
|
||||
{this.data.map((item: AlertNode) => {
|
||||
return (
|
||||
<NSpace vertical>
|
||||
<NCard>
|
||||
<NSpace
|
||||
justify='space-between'
|
||||
style={{
|
||||
'line-height': '28px'
|
||||
}}
|
||||
>
|
||||
<NSpace>
|
||||
{renderNodeServerStatusTag(item)}
|
||||
|
||||
<span>{`${t('monitor.master.host')}: ${
|
||||
item ? item.host : ' - '
|
||||
}`}</span>
|
||||
<span
|
||||
class={styles['link-btn']}
|
||||
onClick={() => clickDetails(item.zkDirectory)}
|
||||
>
|
||||
{t('monitor.master.directory_detail')}
|
||||
</span>
|
||||
</NSpace>
|
||||
<NSpace>
|
||||
<span>{`${t('monitor.master.create_time')}: ${
|
||||
item ? item.createTime : ' - '
|
||||
}`}</span>
|
||||
<span>{`${t('monitor.master.last_heartbeat_time')}: ${
|
||||
item ? item.lastHeartbeatTime : ' - '
|
||||
}`}</span>
|
||||
</NSpace>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
<NGrid x-gap='12' cols='4'>
|
||||
<NGi>
|
||||
<Card title={t('monitor.master.cpu_usage')}>
|
||||
<div class={styles.card}>
|
||||
{item && (
|
||||
<Gauge
|
||||
data={(
|
||||
JSON.parse(item.resInfo).cpuUsage * 100
|
||||
).toFixed(2)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<Card title={t('monitor.master.memory_usage')}>
|
||||
<div class={styles.card}>
|
||||
{item && (
|
||||
<Gauge
|
||||
data={(
|
||||
JSON.parse(item.resInfo).memoryUsage * 100
|
||||
).toFixed(2)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<Card title={t('monitor.master.disk_available')}>
|
||||
<div class={[styles.card, styles['load-average']]}>
|
||||
{item && (
|
||||
<NNumberAnimation
|
||||
precision={2}
|
||||
from={0}
|
||||
to={JSON.parse(item.resInfo).diskAvailable}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<Card title={t('monitor.master.load_average')}>
|
||||
<div class={[styles.card, styles['load-average']]}>
|
||||
{item && (
|
||||
<NNumberAnimation
|
||||
precision={2}
|
||||
from={0}
|
||||
to={JSON.parse(item.resInfo).loadAverage}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
</NGrid>
|
||||
</NSpace>
|
||||
)
|
||||
})}
|
||||
</NSpace>
|
||||
<NodeModal
|
||||
showModal={showModalRef}
|
||||
data={zkDirectoryRef}
|
||||
onConfirmModal={onConfirmModal}
|
||||
></NodeModal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default alertServer
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { NDataTable } from 'naive-ui'
|
||||
import Modal from '@/components/modal'
|
||||
import type { PropType } from 'vue'
|
||||
import type {
|
||||
RowData,
|
||||
TableColumns
|
||||
} from 'naive-ui/es/data-table/src/interface'
|
||||
|
||||
const props = {
|
||||
showModal: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: Array as PropType<Array<RowData>>,
|
||||
default: () => []
|
||||
}
|
||||
}
|
||||
|
||||
const NodeModal = defineComponent({
|
||||
props,
|
||||
emits: ['confirmModal'],
|
||||
setup(props, ctx) {
|
||||
const { t } = useI18n()
|
||||
const columnsRef: TableColumns<any> = [
|
||||
{ title: '#', key: 'index', render: (row, index) => index + 1 },
|
||||
{ title: t('monitor.master.directory'), key: 'directory' }
|
||||
]
|
||||
|
||||
const onConfirm = () => {
|
||||
ctx.emit('confirmModal')
|
||||
}
|
||||
|
||||
return { t, columnsRef, onConfirm }
|
||||
},
|
||||
render() {
|
||||
const { t, columnsRef, onConfirm } = this
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={t('monitor.master.directory_detail')}
|
||||
show={this.showModal}
|
||||
cancelShow={false}
|
||||
onConfirm={onConfirm}
|
||||
>
|
||||
{{
|
||||
default: () => (
|
||||
<NDataTable
|
||||
columns={columnsRef}
|
||||
data={this.data}
|
||||
striped
|
||||
size={'small'}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default NodeModal
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { reactive } from 'vue'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { listMonitorServerNode } from '@/service/modules/monitor'
|
||||
import type { AlertNode } from '@/service/modules/monitor/types'
|
||||
|
||||
export function useServerNode() {
|
||||
const variables = reactive({
|
||||
data: []
|
||||
})
|
||||
const getTableData = () => {
|
||||
const { state } = useAsyncState(
|
||||
listMonitorServerNode('ALERT_SERVER').then((res: Array<AlertNode>) => {
|
||||
variables.data = res as any
|
||||
}),
|
||||
[]
|
||||
)
|
||||
|
||||
return state
|
||||
}
|
||||
return { variables, getTableData }
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { defineComponent, onMounted, ref, toRefs } from 'vue'
|
||||
import { NGrid, NGi, NCard, NNumberAnimation, NSpace } from 'naive-ui'
|
||||
import { NGrid, NGi, NCard, NNumberAnimation, NSpace, NTag } from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useMaster } from './use-master'
|
||||
import styles from './index.module.scss'
|
||||
@ -27,6 +27,7 @@ import MasterModal from './master-modal'
|
||||
import type { Ref } from 'vue'
|
||||
import type { RowData } from 'naive-ui/es/data-table/src/interface'
|
||||
import type { MasterNode } from '@/service/modules/monitor/types'
|
||||
import { capitalize } from 'lodash'
|
||||
|
||||
const master = defineComponent({
|
||||
name: 'master',
|
||||
@ -62,6 +63,18 @@ const master = defineComponent({
|
||||
const { t, clickDetails, onConfirmModal, showModalRef, zkDirectoryRef } =
|
||||
this
|
||||
|
||||
const renderNodeServerStatusTag = (item: MasterNode) => {
|
||||
const serverStatus = JSON.parse(item.resInfo)?.serverStatus
|
||||
|
||||
if (!serverStatus) return ''
|
||||
|
||||
return (
|
||||
<NTag type={serverStatus === 'NORMAL' ? 'info' : 'warning'}>
|
||||
{capitalize(serverStatus)}
|
||||
</NTag>
|
||||
)
|
||||
}
|
||||
|
||||
return this.data.length < 1 ? (
|
||||
<Result
|
||||
title={t('monitor.master.master_no_data_result_title')}
|
||||
@ -76,8 +89,15 @@ const master = defineComponent({
|
||||
return (
|
||||
<NSpace vertical>
|
||||
<NCard>
|
||||
<NSpace justify='space-between'>
|
||||
<NSpace
|
||||
justify='space-between'
|
||||
style={{
|
||||
'line-height': '28px'
|
||||
}}
|
||||
>
|
||||
<NSpace>
|
||||
{renderNodeServerStatusTag(item)}
|
||||
|
||||
<span>{`${t('monitor.master.host')}: ${
|
||||
item ? item.host : ' - '
|
||||
}`}</span>
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { reactive } from 'vue'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { listMaster } from '@/service/modules/monitor'
|
||||
import { listMonitorServerNode } from '@/service/modules/monitor'
|
||||
import type { MasterNode } from '@/service/modules/monitor/types'
|
||||
|
||||
export function useMaster() {
|
||||
@ -26,7 +26,7 @@ export function useMaster() {
|
||||
})
|
||||
const getTableMaster = () => {
|
||||
const { state } = useAsyncState(
|
||||
listMaster().then((res: Array<MasterNode>) => {
|
||||
listMonitorServerNode('MASTER').then((res: Array<MasterNode>) => {
|
||||
variables.data = res as any
|
||||
}),
|
||||
[]
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { defineComponent, onMounted, ref, toRefs } from 'vue'
|
||||
import { NGrid, NGi, NCard, NNumberAnimation, NSpace } from 'naive-ui'
|
||||
import { NGrid, NGi, NCard, NNumberAnimation, NSpace, NTag } from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useWorker } from './use-worker'
|
||||
import styles from './index.module.scss'
|
||||
@ -27,6 +27,7 @@ import WorkerModal from './worker-modal'
|
||||
import type { Ref } from 'vue'
|
||||
import type { RowData } from 'naive-ui/es/data-table/src/interface'
|
||||
import type { WorkerNode } from '@/service/modules/monitor/types'
|
||||
import { capitalize } from 'lodash'
|
||||
|
||||
const worker = defineComponent({
|
||||
name: 'worker',
|
||||
@ -36,12 +37,8 @@ const worker = defineComponent({
|
||||
const { variables, getTableWorker } = useWorker()
|
||||
const zkDirectoryRef: Ref<Array<RowData>> = ref([])
|
||||
|
||||
const clickDetails = (zkDirectories: Array<string>) => {
|
||||
zkDirectoryRef.value = zkDirectories.map((zkItem) => {
|
||||
return {
|
||||
directory: zkItem
|
||||
}
|
||||
})
|
||||
const clickDetails = (zkDirectories: string) => {
|
||||
zkDirectoryRef.value = [{ directory: zkDirectories, index: 1 }]
|
||||
showModalRef.value = true
|
||||
}
|
||||
|
||||
@ -66,6 +63,18 @@ const worker = defineComponent({
|
||||
const { t, clickDetails, onConfirmModal, showModalRef, zkDirectoryRef } =
|
||||
this
|
||||
|
||||
const renderNodeServerStatusTag = (item: WorkerNode) => {
|
||||
const serverStatus = JSON.parse(item.resInfo)?.serverStatus
|
||||
|
||||
if (!serverStatus) return ''
|
||||
|
||||
return (
|
||||
<NTag type={serverStatus === 'NORMAL' ? 'info' : 'warning'}>
|
||||
{capitalize(serverStatus)}
|
||||
</NTag>
|
||||
)
|
||||
}
|
||||
|
||||
return this.data.length < 1 ? (
|
||||
<Result
|
||||
title={t('monitor.worker.worker_no_data_result_title')}
|
||||
@ -80,14 +89,21 @@ const worker = defineComponent({
|
||||
return (
|
||||
<NSpace vertical>
|
||||
<NCard>
|
||||
<NSpace justify='space-between'>
|
||||
<NSpace
|
||||
justify='space-between'
|
||||
style={{
|
||||
'line-height': '28px'
|
||||
}}
|
||||
>
|
||||
<NSpace>
|
||||
{renderNodeServerStatusTag(item)}
|
||||
|
||||
<span>{`${t('monitor.worker.host')}: ${
|
||||
item ? item.host : ' - '
|
||||
}`}</span>
|
||||
<span
|
||||
class={styles['link-btn']}
|
||||
onClick={() => clickDetails(item.zkDirectories)}
|
||||
onClick={() => clickDetails(item.zkDirectory)}
|
||||
>
|
||||
{t('monitor.worker.directory_detail')}
|
||||
</span>
|
||||
@ -102,7 +118,7 @@ const worker = defineComponent({
|
||||
</NSpace>
|
||||
</NSpace>
|
||||
</NCard>
|
||||
<NGrid x-gap='12' cols='4'>
|
||||
<NGrid x-gap='12' cols='5'>
|
||||
<NGi>
|
||||
<Card title={t('monitor.worker.cpu_usage')}>
|
||||
<div class={styles.card}>
|
||||
@ -155,6 +171,33 @@ const worker = defineComponent({
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
|
||||
<NGi>
|
||||
<Card title={t('monitor.worker.thread_pool_usage')}>
|
||||
<div
|
||||
class={[styles.card, styles['load-average']]}
|
||||
style={{
|
||||
'font-size': '90px'
|
||||
}}
|
||||
>
|
||||
{item && (
|
||||
<>
|
||||
<NNumberAnimation
|
||||
precision={0}
|
||||
from={0}
|
||||
to={JSON.parse(item.resInfo).threadPoolUsage}
|
||||
/>
|
||||
/
|
||||
<NNumberAnimation
|
||||
precision={0}
|
||||
from={0}
|
||||
to={JSON.parse(item.resInfo).workerHostWeight}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
</NGrid>
|
||||
</NSpace>
|
||||
)
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { reactive } from 'vue'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { listWorker } from '@/service/modules/monitor'
|
||||
import { listMonitorServerNode } from '@/service/modules/monitor'
|
||||
import type { WorkerNode } from '@/service/modules/monitor/types'
|
||||
|
||||
export function useWorker() {
|
||||
@ -27,7 +27,7 @@ export function useWorker() {
|
||||
|
||||
const getTableWorker = () => {
|
||||
const { state } = useAsyncState(
|
||||
listWorker().then((res: Array<WorkerNode>) => {
|
||||
listMonitorServerNode('WORKER').then((res: Array<WorkerNode>) => {
|
||||
variables.data = res as any
|
||||
}),
|
||||
[]
|
||||
|
@ -15,58 +15,44 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { NGrid, NGi, NNumberAnimation } from 'naive-ui'
|
||||
import { useStatistics } from './use-statistics'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Card from '@/components/card'
|
||||
import styles from './index.module.scss'
|
||||
import { defineComponent } from 'vue'
|
||||
import { NGrid, NGi, NTabs, NTabPane, NCard } from 'naive-ui'
|
||||
import ListCommandTable from './list-command-table'
|
||||
import ListErrorCommandTable from './list-error-command-table'
|
||||
|
||||
const statistics = defineComponent({
|
||||
name: 'statistics',
|
||||
setup() {
|
||||
const { t } = useI18n()
|
||||
const { getStatistics } = useStatistics()
|
||||
const statisticsRef = ref(getStatistics())
|
||||
setup() {},
|
||||
|
||||
return { t, statisticsRef }
|
||||
},
|
||||
render() {
|
||||
const { t, statisticsRef } = this
|
||||
|
||||
return (
|
||||
<NGrid x-gap='12' y-gap='8' cols='2' responsive='screen'>
|
||||
<NGrid x-gap='12' y-gap='8' cols='1' responsive='screen'>
|
||||
<NGi>
|
||||
<Card
|
||||
title={t(
|
||||
'monitor.statistics.command_number_of_waiting_for_running'
|
||||
)}
|
||||
>
|
||||
<div class={styles.connections}>
|
||||
{statisticsRef.command.length > 0 && (
|
||||
<NNumberAnimation
|
||||
from={0}
|
||||
to={statisticsRef.command
|
||||
.map((item) => item.normalCount)
|
||||
.reduce((prev, next) => prev + next)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</NGi>
|
||||
<NGi>
|
||||
<Card title={t('monitor.statistics.failure_command_number')}>
|
||||
<div class={styles.connections}>
|
||||
{statisticsRef.command.length > 0 && (
|
||||
<NNumberAnimation
|
||||
from={0}
|
||||
to={statisticsRef.command
|
||||
.map((item) => item.errorCount)
|
||||
.reduce((prev, next) => prev + next)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
<NCard>
|
||||
<NTabs
|
||||
type='card'
|
||||
animated
|
||||
pane-style={{
|
||||
padding: '0px',
|
||||
border: 'none'
|
||||
}}
|
||||
>
|
||||
<NTabPane
|
||||
name='command'
|
||||
tab='Command Statistics List'
|
||||
display-directiv='show'
|
||||
>
|
||||
<ListCommandTable></ListCommandTable>
|
||||
</NTabPane>
|
||||
<NTabPane
|
||||
name='command-error'
|
||||
tab='Failure Command Statistics List'
|
||||
display-directiv='show'
|
||||
>
|
||||
<ListErrorCommandTable></ListErrorCommandTable>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</NCard>
|
||||
</NGi>
|
||||
</NGrid>
|
||||
)
|
||||
|
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
defineComponent,
|
||||
onMounted,
|
||||
toRefs,
|
||||
watch,
|
||||
reactive,
|
||||
ref,
|
||||
h
|
||||
} from 'vue'
|
||||
import { NSpace, NDataTable, NPagination } from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Card from '@/components/card'
|
||||
import {
|
||||
COLUMN_WIDTH_CONFIG,
|
||||
calculateTableWidth,
|
||||
DefaultTableWidth
|
||||
} from '@/common/column-width-config'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { queryListCommandPaging } from '@/service/modules/projects-analysis'
|
||||
|
||||
const ListCommandTable = defineComponent({
|
||||
name: 'list-command-table',
|
||||
setup() {
|
||||
const { t } = useI18n()
|
||||
|
||||
const variables = reactive({
|
||||
columns: [],
|
||||
tableWidth: DefaultTableWidth,
|
||||
tableData: [],
|
||||
page: ref(1),
|
||||
pageSize: ref(10),
|
||||
userName: ref(null),
|
||||
totalPage: ref(1),
|
||||
loadingRef: ref(false)
|
||||
})
|
||||
|
||||
const createColumns = (variables: any) => {
|
||||
variables.columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
key: 'id',
|
||||
...COLUMN_WIDTH_CONFIG['index']
|
||||
},
|
||||
{
|
||||
title: 'Command Type',
|
||||
key: 'commandType',
|
||||
...COLUMN_WIDTH_CONFIG['userName']
|
||||
},
|
||||
{
|
||||
title: 'Command Param',
|
||||
key: 'commandParam',
|
||||
...COLUMN_WIDTH_CONFIG['linkName']
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Task Info',
|
||||
key: 'id',
|
||||
width: 300,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Definition Code:${row.processDefinitionCode} `,
|
||||
h('br'),
|
||||
`Definition Version:${row.processDefinitionVersion} `,
|
||||
h('br'),
|
||||
`Instance Id:${row.processInstanceId} `,
|
||||
h('br'),
|
||||
`Instance Priority:${row.processInstancePriority} `
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Task Params',
|
||||
key: 'id',
|
||||
width: 300,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`DryRun:${row.dryRun} `,
|
||||
h('br'),
|
||||
`Environment Code:${row.environmentCode} `,
|
||||
h('br'),
|
||||
`Failure Strategy:${row.failureStrategy} `,
|
||||
h('br'),
|
||||
`Task Depend Type:${row.taskDependType} `
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Worker Info',
|
||||
key: 'id',
|
||||
width: 220,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Worker Group:${row.workerGroup} `,
|
||||
h('br'),
|
||||
`Tenant Code:${row.tenantCode} `,
|
||||
h('br'),
|
||||
`Test Flag:${row.testFlag} `
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Warning Info',
|
||||
key: 'id',
|
||||
width: 200,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Warning Group Id:${row.warningGroupId} `,
|
||||
h('br'),
|
||||
`Warning Type:${row.warningType} `
|
||||
])
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Executor Id',
|
||||
key: 'executorId',
|
||||
...COLUMN_WIDTH_CONFIG['type']
|
||||
},
|
||||
{
|
||||
title: 'Time',
|
||||
key: 'startTime',
|
||||
width: 280,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Start Time:${row.startTime} `,
|
||||
h('br'),
|
||||
`Update Time:${row.updateTime} `,
|
||||
h('br'),
|
||||
`Schedule Time:${row.scheduleTime} `
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
if (variables.tableWidth) {
|
||||
variables.tableWidth = calculateTableWidth(variables.columns)
|
||||
}
|
||||
}
|
||||
|
||||
const getTableData = () => {
|
||||
if (variables.loadingRef) return
|
||||
variables.loadingRef = true
|
||||
const data = {
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page
|
||||
}
|
||||
|
||||
const { state } = useAsyncState(
|
||||
queryListCommandPaging(data).then((res: any) => {
|
||||
variables.totalPage = res.totalPage
|
||||
variables.tableData = res.totalList
|
||||
variables.loadingRef = false
|
||||
}),
|
||||
{}
|
||||
)
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
const onUpdatePageSize = () => {
|
||||
variables.page = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
createColumns(variables)
|
||||
getTableData()
|
||||
})
|
||||
|
||||
watch(useI18n().locale, () => {
|
||||
createColumns(variables)
|
||||
})
|
||||
|
||||
return {
|
||||
t,
|
||||
...toRefs(variables),
|
||||
getTableData,
|
||||
onUpdatePageSize
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { getTableData, onUpdatePageSize, loadingRef } = this
|
||||
|
||||
return (
|
||||
<NSpace vertical>
|
||||
<Card>
|
||||
<NSpace vertical>
|
||||
<NDataTable
|
||||
size={'small'}
|
||||
loading={loadingRef}
|
||||
columns={this.columns}
|
||||
scrollX={this.tableWidth}
|
||||
data={this.tableData}
|
||||
/>
|
||||
<NSpace justify='center'>
|
||||
<NPagination
|
||||
v-model:page={this.page}
|
||||
v-model:page-size={this.pageSize}
|
||||
page-count={this.totalPage}
|
||||
show-size-picker
|
||||
page-sizes={[10, 30, 50]}
|
||||
show-quick-jumper
|
||||
onUpdatePage={getTableData}
|
||||
onUpdatePageSize={onUpdatePageSize}
|
||||
/>
|
||||
</NSpace>
|
||||
</NSpace>
|
||||
</Card>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default ListCommandTable
|
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
defineComponent,
|
||||
onMounted,
|
||||
toRefs,
|
||||
watch,
|
||||
reactive,
|
||||
ref,
|
||||
h
|
||||
} from 'vue'
|
||||
import { NSpace, NDataTable, NPagination } from 'naive-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Card from '@/components/card'
|
||||
import {
|
||||
COLUMN_WIDTH_CONFIG,
|
||||
calculateTableWidth,
|
||||
DefaultTableWidth
|
||||
} from '@/common/column-width-config'
|
||||
import { useAsyncState } from '@vueuse/core'
|
||||
import { queryListErrorCommandPaging } from '@/service/modules/projects-analysis'
|
||||
|
||||
const ListErrorCommandTable = defineComponent({
|
||||
name: 'list-error-command-table',
|
||||
setup() {
|
||||
const { t } = useI18n()
|
||||
|
||||
const variables = reactive({
|
||||
columns: [],
|
||||
tableWidth: DefaultTableWidth,
|
||||
tableData: [],
|
||||
page: ref(1),
|
||||
pageSize: ref(10),
|
||||
userName: ref(null),
|
||||
totalPage: ref(1),
|
||||
loadingRef: ref(false)
|
||||
})
|
||||
|
||||
const createColumns = (variables: any) => {
|
||||
variables.columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
key: 'id',
|
||||
...COLUMN_WIDTH_CONFIG['index']
|
||||
},
|
||||
{
|
||||
title: 'Command Type',
|
||||
key: 'commandType',
|
||||
...COLUMN_WIDTH_CONFIG['userName']
|
||||
},
|
||||
{
|
||||
title: 'Command Param',
|
||||
key: 'commandParam',
|
||||
...COLUMN_WIDTH_CONFIG['linkName']
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Task Info',
|
||||
key: 'id',
|
||||
width: 300,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Definition Code:${row.processDefinitionCode} `,
|
||||
h('br'),
|
||||
`Definition Version:${row.processDefinitionVersion} `,
|
||||
h('br'),
|
||||
`Instance Id:${row.processInstanceId} `,
|
||||
h('br'),
|
||||
`Instance Priority:${row.processInstancePriority} `
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Task Params',
|
||||
key: 'id',
|
||||
width: 300,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`DryRun:${row.dryRun} `,
|
||||
h('br'),
|
||||
`Environment Code:${row.environmentCode} `,
|
||||
h('br'),
|
||||
`Failure Strategy:${row.failureStrategy} `,
|
||||
h('br'),
|
||||
`Task Depend Type:${row.taskDependType} `
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Worker Info',
|
||||
key: 'id',
|
||||
width: 220,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Worker Group:${row.workerGroup} `,
|
||||
h('br'),
|
||||
`Tenant Code:${row.tenantCode} `,
|
||||
h('br'),
|
||||
`Test Flag:${row.testFlag} `
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Warning Info',
|
||||
key: 'id',
|
||||
width: 200,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Warning Group Id:${row.warningGroupId} `,
|
||||
h('br'),
|
||||
`Warning Type:${row.warningType} `
|
||||
])
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Message',
|
||||
key: 'message',
|
||||
...COLUMN_WIDTH_CONFIG['linkName']
|
||||
},
|
||||
{
|
||||
title: 'Executor Id',
|
||||
key: 'executorId',
|
||||
...COLUMN_WIDTH_CONFIG['type']
|
||||
},
|
||||
{
|
||||
title: 'Time',
|
||||
key: 'startTime',
|
||||
width: 280,
|
||||
render: (row: any) => {
|
||||
return h('div', [
|
||||
`Start Time:${row.startTime || '-'} `,
|
||||
h('br'),
|
||||
`Update Time:${row.updateTime || '-'} `,
|
||||
h('br'),
|
||||
`Schedule Time:${row.scheduleTime || '-'} `
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
if (variables.tableWidth) {
|
||||
variables.tableWidth = calculateTableWidth(variables.columns)
|
||||
}
|
||||
}
|
||||
|
||||
const getTableData = () => {
|
||||
if (variables.loadingRef) return
|
||||
variables.loadingRef = true
|
||||
const data = {
|
||||
pageSize: variables.pageSize,
|
||||
pageNo: variables.page
|
||||
}
|
||||
|
||||
const { state } = useAsyncState(
|
||||
queryListErrorCommandPaging(data).then((res: any) => {
|
||||
variables.totalPage = res.totalPage
|
||||
variables.tableData = res.totalList
|
||||
variables.loadingRef = false
|
||||
}),
|
||||
{}
|
||||
)
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
const onUpdatePageSize = () => {
|
||||
variables.page = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
createColumns(variables)
|
||||
getTableData()
|
||||
})
|
||||
|
||||
watch(useI18n().locale, () => {
|
||||
createColumns(variables)
|
||||
})
|
||||
|
||||
return {
|
||||
t,
|
||||
...toRefs(variables),
|
||||
getTableData,
|
||||
onUpdatePageSize
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const { getTableData, onUpdatePageSize, loadingRef } = this
|
||||
|
||||
return (
|
||||
<NSpace vertical>
|
||||
<Card>
|
||||
<NSpace vertical>
|
||||
<NDataTable
|
||||
loading={loadingRef}
|
||||
columns={this.columns}
|
||||
scrollX={this.tableWidth}
|
||||
data={this.tableData}
|
||||
/>
|
||||
<NSpace justify='center'>
|
||||
<NPagination
|
||||
v-model:page={this.page}
|
||||
v-model:page-size={this.pageSize}
|
||||
page-count={this.totalPage}
|
||||
show-size-picker
|
||||
page-sizes={[10, 30, 50]}
|
||||
show-quick-jumper
|
||||
onUpdatePage={getTableData}
|
||||
onUpdatePageSize={onUpdatePageSize}
|
||||
/>
|
||||
</NSpace>
|
||||
</NSpace>
|
||||
</Card>
|
||||
</NSpace>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default ListErrorCommandTable
|