🔨 优化执行日志查看逻辑.
This commit is contained in:
@@ -38,7 +38,6 @@ import org.dromara.visor.module.asset.define.operator.ExecCommandLogOperatorType
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecInterruptRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogClearRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogQueryRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogTailRequest;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecHostLogVO;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecLogStatusVO;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecLogVO;
|
||||
@@ -93,6 +92,14 @@ public class ExecCommandLogController {
|
||||
return execLogService.getExecLog(id, SOURCE);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/get-host")
|
||||
@Operation(summary = "查询执行主机日志")
|
||||
@PreAuthorize("@ss.hasPermission('asset:exec-command-log:query')")
|
||||
public ExecHostLogVO getExecCommandHostLog(@RequestParam("id") Long id) {
|
||||
return execHostLogService.getExecHostLog(id);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/host-list")
|
||||
@Operation(summary = "查询全部执行主机日志")
|
||||
@@ -164,12 +171,12 @@ public class ExecCommandLogController {
|
||||
return execLogService.clearExecLog(request);
|
||||
}
|
||||
|
||||
@PostMapping("/tail")
|
||||
@GetMapping("/tail")
|
||||
@Operation(summary = "查看批量执行日志")
|
||||
@Parameter(name = "id", description = "id", required = true)
|
||||
@PreAuthorize("@ss.hasAnyPermission('asset:exec-command-log:query', 'asset:exec-command:exec')")
|
||||
public String getExecCommandLogTailToken(@Validated @RequestBody ExecLogTailRequest request) {
|
||||
request.setSource(SOURCE);
|
||||
return execLogService.getExecLogTailToken(request);
|
||||
public String getExecCommandLogTailToken(@RequestParam("id") Long id) {
|
||||
return execLogService.getExecLogTailToken(id);
|
||||
}
|
||||
|
||||
@OperatorLog(ExecCommandLogOperatorType.DOWNLOAD)
|
||||
|
||||
@@ -37,7 +37,6 @@ import org.dromara.visor.module.asset.define.operator.ExecJobLogOperatorType;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecInterruptRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogClearRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogQueryRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogTailRequest;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecHostLogVO;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecLogStatusVO;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecLogVO;
|
||||
@@ -92,6 +91,14 @@ public class ExecJobLogController {
|
||||
return execLogService.getExecLog(id, SOURCE);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/get-host")
|
||||
@Operation(summary = "查询执行主机日志")
|
||||
@PreAuthorize("@ss.hasPermission('exec:exec-job-log:query')")
|
||||
public ExecHostLogVO getExecJobHostLog(@RequestParam("id") Long id) {
|
||||
return execHostLogService.getExecHostLog(id);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/host-list")
|
||||
@Operation(summary = "查询全部执行主机日志")
|
||||
@@ -153,12 +160,12 @@ public class ExecJobLogController {
|
||||
return execLogService.clearExecLog(request);
|
||||
}
|
||||
|
||||
@PostMapping("/tail")
|
||||
@GetMapping("/tail")
|
||||
@Operation(summary = "查看计划任务日志")
|
||||
@PreAuthorize("@ss.hasPermission('asset:exec-job-log:query')")
|
||||
public String getExecJobLogTailToken(@Validated @RequestBody ExecLogTailRequest request) {
|
||||
request.setSource(SOURCE);
|
||||
return execLogService.getExecLogTailToken(request);
|
||||
@Parameter(name = "id", description = "id", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('exec:exec-job-log:query')")
|
||||
public String getExecJobLogTailToken(@RequestParam("id") Long id) {
|
||||
return execLogService.getExecLogTailToken(id);
|
||||
}
|
||||
|
||||
@OperatorLog(ExecJobLogOperatorType.DOWNLOAD)
|
||||
|
||||
@@ -52,4 +52,20 @@ public interface ExecHostLogDAO extends IMapper<ExecHostLogDO> {
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 logId 查询
|
||||
*
|
||||
* @param id id
|
||||
* @param logId logId
|
||||
* @return row
|
||||
*/
|
||||
default ExecHostLogDO selectByIdAndLogId(Long id, Long logId) {
|
||||
return this.of()
|
||||
.createWrapper()
|
||||
.eq(ExecHostLogDO::getId, id)
|
||||
.eq(ExecHostLogDO::getLogId, logId)
|
||||
.then()
|
||||
.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023 - present Dromara, All rights reserved.
|
||||
*
|
||||
* https://visor.dromara.org
|
||||
* https://visor.dromara.org.cn
|
||||
* https://visor.orionsec.cn
|
||||
*
|
||||
* Members:
|
||||
* Jiahang Li - ljh1553488six@139.com - author
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
package org.dromara.visor.module.asset.entity.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 执行主机日志查看 缓存对象
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/3/18 16:34
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "ExecHostLogTailDTO", description = "执行主机日志查看 缓存对象")
|
||||
public class ExecHostLogTailDTO implements Serializable {
|
||||
|
||||
@Schema(description = "id")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "hostId")
|
||||
private Long hostId;
|
||||
|
||||
@Schema(description = "文件路径")
|
||||
private String path;
|
||||
|
||||
@Schema(description = "输出编码")
|
||||
private String charset;
|
||||
|
||||
}
|
||||
@@ -29,7 +29,6 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行日志查看 缓存对象
|
||||
@@ -45,8 +44,8 @@ import java.util.List;
|
||||
@Schema(name = "ExecLogTailDTO", description = "执行日志查看 缓存对象")
|
||||
public class ExecLogTailDTO implements Serializable {
|
||||
|
||||
@Schema(description = "id")
|
||||
private Long id;
|
||||
@Schema(description = "execId")
|
||||
private Long execId;
|
||||
|
||||
@Schema(description = "用户id")
|
||||
private Long userId;
|
||||
@@ -54,7 +53,4 @@ public class ExecLogTailDTO implements Serializable {
|
||||
@Schema(description = "token")
|
||||
private String token;
|
||||
|
||||
@Schema(description = "执行主机")
|
||||
private List<ExecHostLogTailDTO> hosts;
|
||||
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ public class TerminalConnectDTO {
|
||||
@Schema(description = "hostName")
|
||||
private String hostName;
|
||||
|
||||
@Schema(description = "主机编码")
|
||||
private String hostCode;
|
||||
|
||||
@Schema(description = "主机地址")
|
||||
private String hostAddress;
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2023 - present Dromara, All rights reserved.
|
||||
*
|
||||
* https://visor.dromara.org
|
||||
* https://visor.dromara.org.cn
|
||||
* https://visor.orionsec.cn
|
||||
*
|
||||
* Members:
|
||||
* Jiahang Li - ljh1553488six@139.com - author
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
package org.dromara.visor.module.asset.entity.request.exec;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 执行日志查看 请求对象
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/3/11 11:46
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "ExecLogTailRequest", description = "执行日志查看 请求对象")
|
||||
public class ExecLogTailRequest {
|
||||
|
||||
@Schema(description = "执行来源")
|
||||
private String source;
|
||||
|
||||
@NotNull
|
||||
@Schema(description = "执行id")
|
||||
private Long execId;
|
||||
|
||||
@Schema(description = "执行主机id")
|
||||
private List<Long> hostExecIdList;
|
||||
|
||||
}
|
||||
@@ -35,6 +35,14 @@ import java.util.List;
|
||||
*/
|
||||
public interface ExecHostLogService {
|
||||
|
||||
/**
|
||||
* 查询批量执行主机日志
|
||||
*
|
||||
* @param id id
|
||||
* @return row
|
||||
*/
|
||||
ExecHostLogVO getExecHostLog(Long id);
|
||||
|
||||
/**
|
||||
* 查询全部批量执行主机日志
|
||||
*
|
||||
|
||||
@@ -60,6 +60,13 @@ public class ExecHostLogServiceImpl implements ExecHostLogService {
|
||||
@Resource
|
||||
private ExecTaskManager execTaskManager;
|
||||
|
||||
@Override
|
||||
public ExecHostLogVO getExecHostLog(Long id) {
|
||||
ExecHostLogDO record = execHostLogDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
return ExecHostLogConvert.MAPPER.to(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExecHostLogVO> getExecHostLogList(Long logId) {
|
||||
return execHostLogDAO.of()
|
||||
|
||||
@@ -26,7 +26,6 @@ import cn.orionsec.kit.lang.annotation.Keep;
|
||||
import cn.orionsec.kit.lang.define.wrapper.DataGrid;
|
||||
import cn.orionsec.kit.lang.id.UUIds;
|
||||
import cn.orionsec.kit.lang.utils.Arrays1;
|
||||
import cn.orionsec.kit.lang.utils.Objects1;
|
||||
import cn.orionsec.kit.lang.utils.Strings;
|
||||
import cn.orionsec.kit.lang.utils.collect.Lists;
|
||||
import cn.orionsec.kit.lang.utils.io.Files1;
|
||||
@@ -53,24 +52,19 @@ import org.dromara.visor.module.asset.dao.ExecLogDAO;
|
||||
import org.dromara.visor.module.asset.define.cache.ExecCacheKeyDefine;
|
||||
import org.dromara.visor.module.asset.entity.domain.ExecHostLogDO;
|
||||
import org.dromara.visor.module.asset.entity.domain.ExecLogDO;
|
||||
import org.dromara.visor.module.asset.entity.dto.ExecHostLogTailDTO;
|
||||
import org.dromara.visor.module.asset.entity.dto.ExecLogTailDTO;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogClearRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogQueryRequest;
|
||||
import org.dromara.visor.module.asset.entity.request.exec.ExecLogTailRequest;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecHostLogVO;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecLogStatusVO;
|
||||
import org.dromara.visor.module.asset.entity.vo.ExecLogVO;
|
||||
import org.dromara.visor.module.asset.enums.ExecHostStatusEnum;
|
||||
import org.dromara.visor.module.asset.enums.ExecStatusEnum;
|
||||
import org.dromara.visor.module.asset.enums.HostTypeEnum;
|
||||
import org.dromara.visor.module.asset.handler.host.config.model.HostSshConfigModel;
|
||||
import org.dromara.visor.module.asset.handler.host.exec.command.handler.IExecCommandHandler;
|
||||
import org.dromara.visor.module.asset.handler.host.exec.command.handler.IExecTaskHandler;
|
||||
import org.dromara.visor.module.asset.handler.host.exec.command.manager.ExecTaskManager;
|
||||
import org.dromara.visor.module.asset.service.ExecHostLogService;
|
||||
import org.dromara.visor.module.asset.service.ExecLogService;
|
||||
import org.dromara.visor.module.asset.service.HostConfigService;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -79,7 +73,10 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -105,9 +102,6 @@ public class ExecLogServiceImpl implements ExecLogService {
|
||||
@Resource
|
||||
private ExecTaskManager execTaskManager;
|
||||
|
||||
@Resource
|
||||
private HostConfigService hostConfigService;
|
||||
|
||||
@Keep
|
||||
@Resource
|
||||
private FileClient logsFileClient;
|
||||
@@ -366,55 +360,17 @@ public class ExecLogServiceImpl implements ExecLogService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecLogTailToken(ExecLogTailRequest request) {
|
||||
String source = request.getSource();
|
||||
Long execId = request.getExecId();
|
||||
List<Long> hostExecIdList = request.getHostExecIdList();
|
||||
log.info("ExecLogService.getExecLogTailToken start execId: {}, hostExecIdList: {}", execId, hostExecIdList);
|
||||
// 查询执行日志
|
||||
ExecLogDO execLog = execLogDAO.selectByIdSource(execId, source);
|
||||
Valid.notNull(execLog, ErrorMessage.LOG_ABSENT);
|
||||
// 查询主机日志
|
||||
List<ExecHostLogDO> hostLogs;
|
||||
if (hostExecIdList == null) {
|
||||
hostLogs = execHostLogDAO.selectByLogId(execId);
|
||||
} else {
|
||||
hostLogs = execHostLogDAO.of()
|
||||
.createWrapper()
|
||||
.eq(ExecHostLogDO::getLogId, execId)
|
||||
.in(ExecHostLogDO::getId, hostExecIdList)
|
||||
.then()
|
||||
.list();
|
||||
}
|
||||
Valid.notEmpty(hostLogs, ErrorMessage.LOG_ABSENT);
|
||||
// 获取编码集
|
||||
// TODO 待优化
|
||||
List<Long> hostIdList = hostLogs.stream()
|
||||
.map(ExecHostLogDO::getHostId)
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, HostSshConfigModel> configMap = hostConfigService.getHostConfigMap(hostIdList, HostTypeEnum.SSH);
|
||||
public String getExecLogTailToken(Long id) {
|
||||
// 生成缓存
|
||||
String token = UUIds.random19();
|
||||
String cacheKey = ExecCacheKeyDefine.EXEC_TAIL.format(token);
|
||||
ExecLogTailDTO cache = ExecLogTailDTO.builder()
|
||||
.execId(id)
|
||||
.token(token)
|
||||
.id(execId)
|
||||
.userId(SecurityUtils.getLoginUserId())
|
||||
.hosts(hostLogs.stream()
|
||||
.map(s -> ExecHostLogTailDTO.builder()
|
||||
.id(s.getId())
|
||||
.hostId(s.getHostId())
|
||||
.path(s.getLogPath())
|
||||
.charset(Optional.ofNullable(configMap.get(s.getHostId()))
|
||||
.map(HostSshConfigModel::getCharset)
|
||||
.map(Objects1::toString)
|
||||
.orElse(Const.UTF_8))
|
||||
.build())
|
||||
.collect(Collectors.toList()))
|
||||
.build();
|
||||
// 设置缓存
|
||||
RedisStrings.setJson(cacheKey, ExecCacheKeyDefine.EXEC_TAIL, cache);
|
||||
log.info("ExecLogService.getExecLogTailToken finish token: {}, execId: {}, hostExecIdList: {}", token, execId, hostExecIdList);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ import java.util.stream.Collectors;
|
||||
public class ExecUtils {
|
||||
|
||||
private static final ReplacementFormatter FORMATTER = ReplacementFormatters.create("@{{ ", " }}")
|
||||
.noMatchStrategy(NoMatchStrategy.KEEP);
|
||||
.noMatchStrategy(NoMatchStrategy.EMPTY);
|
||||
|
||||
private ExecUtils() {
|
||||
}
|
||||
@@ -63,6 +63,17 @@ public class ExecUtils {
|
||||
return Strings.replaceCRLF(FORMATTER.format(command, params));
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换命令
|
||||
*
|
||||
* @param command command
|
||||
* @param json json
|
||||
* @return command
|
||||
*/
|
||||
public static String format(String command, String json) {
|
||||
return Strings.replaceCRLF(FORMATTER.format(command, json));
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取参数
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user