🔨 查看执行日志.
This commit is contained in:
@@ -31,4 +31,6 @@ public interface Const extends com.orion.lang.constant.Const, FieldConst, CnCons
|
|||||||
|
|
||||||
Integer DEFAULT_VERSION = 1;
|
Integer DEFAULT_VERSION = 1;
|
||||||
|
|
||||||
|
String ERROR_LOG = "error.log";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,4 +89,6 @@ public interface ErrorMessage {
|
|||||||
|
|
||||||
String CHECK_AUTHORIZED_HOST = "请选择已授权的主机";
|
String CHECK_AUTHORIZED_HOST = "请选择已授权的主机";
|
||||||
|
|
||||||
|
String FILE_READ_ERROR = "文件读取失败";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ Authorization: {{token}}
|
|||||||
{
|
{
|
||||||
"description": 1,
|
"description": 1,
|
||||||
"timeout": 10,
|
"timeout": 10,
|
||||||
"command": "echo @{{ hostAddress }}\nsleep 10\necho @{{ str }}",
|
"command": "echo 这是日志@{{ hostAddress }}\nsleep 1\necho @{{ hostName }}",
|
||||||
"parameter": "{\"str\":\"end\"}",
|
"parameterSchema": "[]",
|
||||||
"hostIdList": [1,7]
|
"hostIdList": [1,7]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,4 +22,19 @@ Authorization: {{token}}
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 查看执行日志
|
||||||
|
POST {{baseUrl}}/asset/exec/tail-log
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: {{token}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"execId": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 下载执行日志文件
|
||||||
|
GET {{baseUrl}}/asset/exec/download-log?id=83
|
||||||
|
Authorization: {{token}}
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.orion.ops.framework.web.core.annotation.RestWrapper;
|
|||||||
import com.orion.ops.module.asset.define.operator.ExecOperatorType;
|
import com.orion.ops.module.asset.define.operator.ExecOperatorType;
|
||||||
import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest;
|
import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest;
|
||||||
import com.orion.ops.module.asset.entity.request.exec.ExecInterruptRequest;
|
import com.orion.ops.module.asset.entity.request.exec.ExecInterruptRequest;
|
||||||
|
import com.orion.ops.module.asset.entity.request.exec.ExecLogTailRequest;
|
||||||
import com.orion.ops.module.asset.entity.request.exec.ReExecCommandRequest;
|
import com.orion.ops.module.asset.entity.request.exec.ReExecCommandRequest;
|
||||||
import com.orion.ops.module.asset.entity.vo.ExecCommandVO;
|
import com.orion.ops.module.asset.entity.vo.ExecCommandVO;
|
||||||
import com.orion.ops.module.asset.service.ExecService;
|
import com.orion.ops.module.asset.service.ExecService;
|
||||||
@@ -18,6 +19,7 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量执行
|
* 批量执行
|
||||||
@@ -74,6 +76,19 @@ public class ExecController {
|
|||||||
return HttpWrapper.ok();
|
return HttpWrapper.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO tail log
|
@PostMapping("/tail-log")
|
||||||
|
@Operation(summary = "查看批量执行日志")
|
||||||
|
@PreAuthorize("@ss.hasAnyPermission('asset:exec:exec-command', 'asset:exec-log:query')")
|
||||||
|
public String getExecLogTailToken(@Validated @RequestBody ExecLogTailRequest request) {
|
||||||
|
return execService.getExecLogTailToken(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperatorLog(ExecOperatorType.DOWNLOAD_HOST_LOG)
|
||||||
|
@GetMapping("/download-log")
|
||||||
|
@Operation(summary = "下载执行日志文件")
|
||||||
|
@PreAuthorize("@ss.hasAnyPermission('asset:exec:exec-command', 'asset:exec-log:query')")
|
||||||
|
public void downloadLogFile(@RequestParam("id") Long id, HttpServletResponse response) {
|
||||||
|
execService.downloadLogFile(id, response);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.orion.ops.module.asset.define.cache;
|
||||||
|
|
||||||
|
import com.orion.lang.define.cache.key.CacheKeyBuilder;
|
||||||
|
import com.orion.lang.define.cache.key.CacheKeyDefine;
|
||||||
|
import com.orion.lang.define.cache.key.struct.RedisCacheStruct;
|
||||||
|
import com.orion.ops.module.asset.entity.dto.ExecLogTailDTO;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 命令执行服务缓存 key
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/3/18 16:31
|
||||||
|
*/
|
||||||
|
public interface ExecCacheKeyDefine {
|
||||||
|
|
||||||
|
CacheKeyDefine EXEC_TAIL = new CacheKeyBuilder()
|
||||||
|
.key("exec:tail:{}")
|
||||||
|
.desc("命令执行日志查看 ${token}")
|
||||||
|
.type(ExecLogTailDTO.class)
|
||||||
|
.struct(RedisCacheStruct.STRING)
|
||||||
|
.timeout(5, TimeUnit.MINUTES)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,8 +4,7 @@ import com.orion.ops.framework.biz.operator.log.core.annotation.Module;
|
|||||||
import com.orion.ops.framework.biz.operator.log.core.factory.InitializingOperatorTypes;
|
import com.orion.ops.framework.biz.operator.log.core.factory.InitializingOperatorTypes;
|
||||||
import com.orion.ops.framework.biz.operator.log.core.model.OperatorType;
|
import com.orion.ops.framework.biz.operator.log.core.model.OperatorType;
|
||||||
|
|
||||||
import static com.orion.ops.framework.biz.operator.log.core.enums.OperatorRiskLevel.H;
|
import static com.orion.ops.framework.biz.operator.log.core.enums.OperatorRiskLevel.*;
|
||||||
import static com.orion.ops.framework.biz.operator.log.core.enums.OperatorRiskLevel.M;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量执行 操作记录类型
|
* 批量执行 操作记录类型
|
||||||
@@ -23,21 +22,24 @@ public class ExecOperatorType extends InitializingOperatorTypes {
|
|||||||
|
|
||||||
public static final String INTERRUPT_HOST = "exec:interrupt-host";
|
public static final String INTERRUPT_HOST = "exec:interrupt-host";
|
||||||
|
|
||||||
public static final String DELETE_HOST_LOG = "exec:delete-host-log";
|
|
||||||
|
|
||||||
public static final String DELETE_LOG = "exec:delete-log";
|
public static final String DELETE_LOG = "exec:delete-log";
|
||||||
|
|
||||||
public static final String CLEAR_LOG = "exec:clear-log";
|
public static final String CLEAR_LOG = "exec:clear-log";
|
||||||
|
|
||||||
|
public static final String DELETE_HOST_LOG = "exec:delete-host-log";
|
||||||
|
|
||||||
|
public static final String DOWNLOAD_HOST_LOG = "exec:download-host-log";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OperatorType[] types() {
|
public OperatorType[] types() {
|
||||||
return new OperatorType[]{
|
return new OperatorType[]{
|
||||||
new OperatorType(M, EXEC_COMMAND, "执行主机命令"),
|
new OperatorType(M, EXEC_COMMAND, "执行主机命令"),
|
||||||
new OperatorType(M, INTERRUPT_EXEC, "中断执行命令"),
|
new OperatorType(M, INTERRUPT_EXEC, "中断执行命令"),
|
||||||
new OperatorType(M, INTERRUPT_HOST, "中断主机执行命令 ${logId} ${hostName}"),
|
new OperatorType(M, INTERRUPT_HOST, "中断主机执行命令 ${logId} ${hostName}"),
|
||||||
new OperatorType(H, DELETE_HOST_LOG, "删除主机执行记录 ${logId} ${hostName}"),
|
|
||||||
new OperatorType(H, DELETE_LOG, "删除执行记录 ${count} 条"),
|
new OperatorType(H, DELETE_LOG, "删除执行记录 ${count} 条"),
|
||||||
new OperatorType(H, CLEAR_LOG, "清理执行记录 ${count} 条"),
|
new OperatorType(H, CLEAR_LOG, "清理执行记录 ${count} 条"),
|
||||||
|
new OperatorType(H, DELETE_HOST_LOG, "删除主机执行记录 ${logId} ${hostName}"),
|
||||||
|
new OperatorType(L, DOWNLOAD_HOST_LOG, "下载主机执行日志 ${logId} ${hostName}"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.orion.ops.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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.orion.ops.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;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行日志查看 缓存对象
|
||||||
|
*
|
||||||
|
* @author Jiahang Li
|
||||||
|
* @version 1.0.0
|
||||||
|
* @since 2024/3/18 16:34
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Schema(name = "ExecLogTailDTO", description = "执行日志查看 缓存对象")
|
||||||
|
public class ExecLogTailDTO implements Serializable {
|
||||||
|
|
||||||
|
@Schema(description = "id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "用户id")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "token")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Schema(description = "执行主机")
|
||||||
|
private List<ExecHostLogTailDTO> hosts;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.orion.ops.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 {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Schema(description = "执行id")
|
||||||
|
private Long execId;
|
||||||
|
|
||||||
|
@Schema(description = "执行主机id")
|
||||||
|
private List<Long> execHostIdList;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -51,7 +51,6 @@ public class TerminalAccessInterceptor implements HandshakeInterceptor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
|
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
|
||||||
log.info("afterHandshake");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
package com.orion.ops.module.asset.service;
|
package com.orion.ops.module.asset.service;
|
||||||
|
|
||||||
|
import com.orion.ops.module.asset.entity.dto.ExecLogTailDTO;
|
||||||
import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest;
|
import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest;
|
||||||
|
import com.orion.ops.module.asset.entity.request.exec.ExecLogTailRequest;
|
||||||
import com.orion.ops.module.asset.entity.vo.ExecCommandVO;
|
import com.orion.ops.module.asset.entity.vo.ExecCommandVO;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量执行服务
|
* 批量执行服务
|
||||||
*
|
*
|
||||||
@@ -42,4 +46,28 @@ public interface ExecService {
|
|||||||
*/
|
*/
|
||||||
void interruptHostExec(Long hostLogId);
|
void interruptHostExec(Long hostLogId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看执行日志
|
||||||
|
*
|
||||||
|
* @param request request
|
||||||
|
* @return token
|
||||||
|
*/
|
||||||
|
String getExecLogTailToken(ExecLogTailRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取查看执行日志参数
|
||||||
|
*
|
||||||
|
* @param token token
|
||||||
|
* @return log
|
||||||
|
*/
|
||||||
|
ExecLogTailDTO getExecLogTailInfo(String token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载执行日志文件
|
||||||
|
*
|
||||||
|
* @param id id
|
||||||
|
* @param response response
|
||||||
|
*/
|
||||||
|
void downloadLogFile(Long id, HttpServletResponse response);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ package com.orion.ops.module.asset.service.impl;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.orion.lang.exception.argument.InvalidArgumentException;
|
||||||
import com.orion.lang.function.Functions;
|
import com.orion.lang.function.Functions;
|
||||||
import com.orion.lang.id.UUIds;
|
import com.orion.lang.id.UUIds;
|
||||||
import com.orion.lang.utils.Strings;
|
import com.orion.lang.utils.Strings;
|
||||||
import com.orion.lang.utils.collect.Lists;
|
import com.orion.lang.utils.collect.Lists;
|
||||||
import com.orion.lang.utils.collect.Maps;
|
import com.orion.lang.utils.collect.Maps;
|
||||||
|
import com.orion.lang.utils.io.Files1;
|
||||||
import com.orion.lang.utils.json.matcher.NoMatchStrategy;
|
import com.orion.lang.utils.json.matcher.NoMatchStrategy;
|
||||||
import com.orion.lang.utils.json.matcher.ReplacementFormatter;
|
import com.orion.lang.utils.json.matcher.ReplacementFormatter;
|
||||||
import com.orion.lang.utils.json.matcher.ReplacementFormatters;
|
import com.orion.lang.utils.json.matcher.ReplacementFormatters;
|
||||||
@@ -17,15 +19,20 @@ import com.orion.ops.framework.common.constant.ErrorMessage;
|
|||||||
import com.orion.ops.framework.common.file.FileClient;
|
import com.orion.ops.framework.common.file.FileClient;
|
||||||
import com.orion.ops.framework.common.security.LoginUser;
|
import com.orion.ops.framework.common.security.LoginUser;
|
||||||
import com.orion.ops.framework.common.utils.Valid;
|
import com.orion.ops.framework.common.utils.Valid;
|
||||||
|
import com.orion.ops.framework.redis.core.utils.RedisStrings;
|
||||||
import com.orion.ops.framework.security.core.utils.SecurityUtils;
|
import com.orion.ops.framework.security.core.utils.SecurityUtils;
|
||||||
import com.orion.ops.module.asset.dao.ExecHostLogDAO;
|
import com.orion.ops.module.asset.dao.ExecHostLogDAO;
|
||||||
import com.orion.ops.module.asset.dao.ExecLogDAO;
|
import com.orion.ops.module.asset.dao.ExecLogDAO;
|
||||||
import com.orion.ops.module.asset.dao.HostDAO;
|
import com.orion.ops.module.asset.dao.HostDAO;
|
||||||
|
import com.orion.ops.module.asset.define.cache.ExecCacheKeyDefine;
|
||||||
import com.orion.ops.module.asset.entity.domain.ExecHostLogDO;
|
import com.orion.ops.module.asset.entity.domain.ExecHostLogDO;
|
||||||
import com.orion.ops.module.asset.entity.domain.ExecLogDO;
|
import com.orion.ops.module.asset.entity.domain.ExecLogDO;
|
||||||
import com.orion.ops.module.asset.entity.domain.HostDO;
|
import com.orion.ops.module.asset.entity.domain.HostDO;
|
||||||
|
import com.orion.ops.module.asset.entity.dto.ExecHostLogTailDTO;
|
||||||
|
import com.orion.ops.module.asset.entity.dto.ExecLogTailDTO;
|
||||||
import com.orion.ops.module.asset.entity.dto.ExecParameterSchemaDTO;
|
import com.orion.ops.module.asset.entity.dto.ExecParameterSchemaDTO;
|
||||||
import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest;
|
import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest;
|
||||||
|
import com.orion.ops.module.asset.entity.request.exec.ExecLogTailRequest;
|
||||||
import com.orion.ops.module.asset.entity.vo.ExecCommandHostVO;
|
import com.orion.ops.module.asset.entity.vo.ExecCommandHostVO;
|
||||||
import com.orion.ops.module.asset.entity.vo.ExecCommandVO;
|
import com.orion.ops.module.asset.entity.vo.ExecCommandVO;
|
||||||
import com.orion.ops.module.asset.enums.ExecHostStatusEnum;
|
import com.orion.ops.module.asset.enums.ExecHostStatusEnum;
|
||||||
@@ -40,11 +47,14 @@ import com.orion.ops.module.asset.handler.host.exec.handler.IExecTaskHandler;
|
|||||||
import com.orion.ops.module.asset.handler.host.exec.manager.ExecManager;
|
import com.orion.ops.module.asset.handler.host.exec.manager.ExecManager;
|
||||||
import com.orion.ops.module.asset.service.AssetAuthorizedDataService;
|
import com.orion.ops.module.asset.service.AssetAuthorizedDataService;
|
||||||
import com.orion.ops.module.asset.service.ExecService;
|
import com.orion.ops.module.asset.service.ExecService;
|
||||||
|
import com.orion.web.servlet.web.Servlets;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -275,6 +285,92 @@ public class ExecServiceImpl implements ExecService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExecLogTailToken(ExecLogTailRequest request) {
|
||||||
|
Long execId = request.getExecId();
|
||||||
|
List<Long> execHostIdList = request.getExecHostIdList();
|
||||||
|
log.info("ExecService.getExecLogTailToken start execId: {}, execHostIdList: {}", execId, execHostIdList);
|
||||||
|
// 查询执行日志
|
||||||
|
ExecLogDO execLog = execLogDAO.selectById(execId);
|
||||||
|
Valid.notNull(execLog, ErrorMessage.LOG_ABSENT);
|
||||||
|
// 查询主机日志
|
||||||
|
List<ExecHostLogDO> hostLogs;
|
||||||
|
if (execHostIdList == null) {
|
||||||
|
hostLogs = execHostLogDAO.selectByLogId(execId);
|
||||||
|
} else {
|
||||||
|
hostLogs = execHostLogDAO.of()
|
||||||
|
.createWrapper()
|
||||||
|
.eq(ExecHostLogDO::getLogId, execId)
|
||||||
|
.in(ExecHostLogDO::getId, execHostIdList)
|
||||||
|
.then()
|
||||||
|
.list();
|
||||||
|
}
|
||||||
|
Valid.notEmpty(hostLogs, ErrorMessage.LOG_ABSENT);
|
||||||
|
// 生成缓存
|
||||||
|
String token = UUIds.random19();
|
||||||
|
String cacheKey = ExecCacheKeyDefine.EXEC_TAIL.format(token);
|
||||||
|
ExecLogTailDTO cache = ExecLogTailDTO.builder()
|
||||||
|
.token(token)
|
||||||
|
.id(execId)
|
||||||
|
.userId(SecurityUtils.getLoginUserId())
|
||||||
|
.hosts(hostLogs.stream()
|
||||||
|
.map(s -> ExecHostLogTailDTO.builder()
|
||||||
|
.id(s.getId())
|
||||||
|
.hostId(s.getHostId())
|
||||||
|
.path(s.getLogPath())
|
||||||
|
.build())
|
||||||
|
.collect(Collectors.toList()))
|
||||||
|
.build();
|
||||||
|
// 设置缓存
|
||||||
|
RedisStrings.setJson(cacheKey, ExecCacheKeyDefine.EXEC_TAIL, cache);
|
||||||
|
log.info("ExecService.getExecLogTailToken finish token: {}, execId: {}, execHostIdList: {}", token, execId, execHostIdList);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecLogTailDTO getExecLogTailInfo(String token) {
|
||||||
|
String cacheKey = ExecCacheKeyDefine.EXEC_TAIL.format(token);
|
||||||
|
// 获取缓存
|
||||||
|
ExecLogTailDTO tail = RedisStrings.getJson(cacheKey, ExecCacheKeyDefine.EXEC_TAIL);
|
||||||
|
if (tail != null) {
|
||||||
|
// 删除缓存
|
||||||
|
RedisStrings.delete(cacheKey);
|
||||||
|
}
|
||||||
|
return tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void downloadLogFile(Long id, HttpServletResponse response) {
|
||||||
|
log.info("ExecService.downloadLogFile id: {}", id);
|
||||||
|
try {
|
||||||
|
// 获取主机执行日志
|
||||||
|
ExecHostLogDO hostLog = execHostLogDAO.selectById(id);
|
||||||
|
Valid.notNull(hostLog, ErrorMessage.LOG_ABSENT);
|
||||||
|
String logPath = hostLog.getLogPath();
|
||||||
|
Valid.notNull(logPath, ErrorMessage.LOG_ABSENT);
|
||||||
|
// 设置日志参数
|
||||||
|
OperatorLogs.add(OperatorLogs.LOG_ID, hostLog.getLogId());
|
||||||
|
OperatorLogs.add(OperatorLogs.HOST_ID, hostLog.getHostId());
|
||||||
|
OperatorLogs.add(OperatorLogs.HOST_NAME, hostLog.getHostName());
|
||||||
|
// 获取日志
|
||||||
|
InputStream in = logsFileClient.getContentInputStream(logPath);
|
||||||
|
// 返回
|
||||||
|
Servlets.transfer(response, in, Files1.getFileName(logPath));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("ExecService.downloadLogFile error id: {}", id, e);
|
||||||
|
String errorMessage = ErrorMessage.FILE_READ_ERROR;
|
||||||
|
if (e instanceof InvalidArgumentException) {
|
||||||
|
errorMessage = e.getMessage();
|
||||||
|
}
|
||||||
|
// 响应错误信息
|
||||||
|
try {
|
||||||
|
Servlets.transfer(response, Strings.bytes(errorMessage), Const.ERROR_LOG);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("ExecService.downloadLogFile transfer-error id: {}", id, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始执行命令
|
* 开始执行命令
|
||||||
*
|
*
|
||||||
@@ -306,7 +402,7 @@ public class ExecServiceImpl implements ExecService {
|
|||||||
* @return logPath
|
* @return logPath
|
||||||
*/
|
*/
|
||||||
private String buildLogPath(Long logId, Long hostId) {
|
private String buildLogPath(Long logId, Long hostId) {
|
||||||
String logFile = "/exec/" + logId + "/" + hostId + ".log";
|
String logFile = "/exec/" + logId + "/" + logId + "_" + hostId + ".log";
|
||||||
return logsFileClient.getReturnPath(logFile);
|
return logsFileClient.getReturnPath(logFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class HostSftpLogServiceImpl implements HostSftpLogService {
|
|||||||
vo.setExtra(extra);
|
vo.setExtra(extra);
|
||||||
return vo;
|
return vo;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
// 返回
|
// 返回 TODO KIT
|
||||||
DataGrid<HostSftpLogVO> result = new DataGrid<>(rows, dataGrid.getTotal());
|
DataGrid<HostSftpLogVO> result = new DataGrid<>(rows, dataGrid.getTotal());
|
||||||
result.setPage(dataGrid.getPage());
|
result.setPage(dataGrid.getPage());
|
||||||
result.setLimit(dataGrid.getLimit());
|
result.setLimit(dataGrid.getLimit());
|
||||||
|
|||||||
Reference in New Issue
Block a user