🔨 优化执行日志查看逻辑.

This commit is contained in:
lijiahang
2025-02-05 10:14:07 +08:00
parent d13008ce0c
commit 89f6d2cd1c
11 changed files with 79 additions and 185 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -57,6 +57,9 @@ public class TerminalConnectDTO {
@Schema(description = "hostName")
private String hostName;
@Schema(description = "主机编码")
private String hostCode;
@Schema(description = "主机地址")
private String hostAddress;

View File

@@ -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;
}

View File

@@ -35,6 +35,14 @@ import java.util.List;
*/
public interface ExecHostLogService {
/**
* 查询批量执行主机日志
*
* @param id id
* @return row
*/
ExecHostLogVO getExecHostLog(Long id);
/**
* 查询全部批量执行主机日志
*

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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));
}
/**
* 提取参数
*