✨ 清空主机连接日志.
This commit is contained in:
@@ -20,7 +20,7 @@ import lombok.NoArgsConstructor;
|
||||
@Schema(name = "HostConnectLogExtraDTO", description = "主机连接日志推展信息对象")
|
||||
public class HostConnectLogExtraDTO {
|
||||
|
||||
@Schema(description = "主机 id")
|
||||
@Schema(description = "hostId")
|
||||
private Long hostId;
|
||||
|
||||
@Schema(description = "主机名称")
|
||||
@@ -29,15 +29,15 @@ public class HostConnectLogExtraDTO {
|
||||
@Schema(description = "连接类型")
|
||||
private String connectType;
|
||||
|
||||
@Schema(description = "traceId")
|
||||
private String traceId;
|
||||
|
||||
@Schema(description = "channelId")
|
||||
private String channelId;
|
||||
|
||||
@Schema(description = "sessionId")
|
||||
private String sessionId;
|
||||
|
||||
@Schema(description = "traceId")
|
||||
private String traceId;
|
||||
|
||||
@Schema(description = "请求地址")
|
||||
private String address;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.orion.ops.module.asset.entity.vo;
|
||||
|
||||
import com.orion.ops.module.asset.entity.dto.HostConnectLogExtraDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -8,7 +9,6 @@ import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 主机连接日志 视图响应对象
|
||||
@@ -57,6 +57,6 @@ public class HostConnectLogVO implements Serializable {
|
||||
private Date endTime;
|
||||
|
||||
@Schema(description = "额外信息")
|
||||
private Map<String, Object> extra;
|
||||
private HostConnectLogExtraDTO extra;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,9 +5,11 @@ import com.orion.lang.exception.ConnectionRuntimeException;
|
||||
import com.orion.lang.exception.TimeoutException;
|
||||
import com.orion.lang.exception.argument.InvalidArgumentException;
|
||||
import com.orion.lang.utils.Exceptions;
|
||||
import com.orion.lang.utils.collect.Maps;
|
||||
import com.orion.lang.utils.io.Streams;
|
||||
import com.orion.net.host.SessionStore;
|
||||
import com.orion.ops.framework.common.constant.ErrorMessage;
|
||||
import com.orion.ops.framework.common.constant.ExtraFieldConst;
|
||||
import com.orion.ops.framework.common.enums.BooleanBit;
|
||||
import com.orion.ops.framework.websocket.core.utils.WebSockets;
|
||||
import com.orion.ops.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||
@@ -28,6 +30,7 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 连接主机处理器
|
||||
@@ -74,7 +77,9 @@ public class TerminalConnectHandler extends AbstractTerminalHandler<TerminalConn
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
// 修改连接状态为失败
|
||||
hostConnectLogService.updateStatusByToken(sessionId, HostConnectStatusEnum.FAILED);
|
||||
Map<String, Object> extra = Maps.newMap(4);
|
||||
extra.put(ExtraFieldConst.ERROR_MESSAGE, this.getConnectErrorMessage(e));
|
||||
hostConnectLogService.updateStatusByToken(sessionId, HostConnectStatusEnum.FAILED, extra);
|
||||
}
|
||||
// 返回连接状态
|
||||
this.send(channel,
|
||||
|
||||
@@ -47,7 +47,8 @@ public abstract class TerminalSession implements ITerminalSession {
|
||||
// 检查并且关闭
|
||||
if (this.checkAndClose()) {
|
||||
// 修改状态
|
||||
SpringHolder.getBean(HostConnectLogService.class).updateStatusByToken(sessionId, HostConnectStatusEnum.COMPLETE);
|
||||
SpringHolder.getBean(HostConnectLogService.class)
|
||||
.updateStatusByToken(sessionId, HostConnectStatusEnum.COMPLETE, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.orion.ops.module.asset.enums.HostConnectStatusEnum;
|
||||
import com.orion.ops.module.asset.enums.HostConnectTypeEnum;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
@@ -40,9 +41,10 @@ public interface HostConnectLogService {
|
||||
*
|
||||
* @param token token
|
||||
* @param status status
|
||||
* @param extra extra
|
||||
* @return effect
|
||||
*/
|
||||
Integer updateStatusByToken(String token, HostConnectStatusEnum status);
|
||||
Integer updateStatusByToken(String token, HostConnectStatusEnum status, Map<String, Object> extra);
|
||||
|
||||
/**
|
||||
* 查询用户最近连接的主机
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.orion.lang.utils.Arrays1;
|
||||
import com.orion.lang.utils.Valid;
|
||||
import com.orion.ops.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.ops.framework.common.constant.ErrorMessage;
|
||||
import com.orion.ops.framework.mybatis.core.query.Conditions;
|
||||
import com.orion.ops.framework.security.core.utils.SecurityUtils;
|
||||
import com.orion.ops.module.asset.convert.HostConnectLogConvert;
|
||||
import com.orion.ops.module.asset.dao.HostConnectLogDAO;
|
||||
@@ -29,6 +28,7 @@ import org.springframework.stereotype.Service;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
@@ -73,18 +73,39 @@ public class HostConnectLogServiceImpl implements HostConnectLogService {
|
||||
.page(request)
|
||||
.dataGrid(s -> {
|
||||
HostConnectLogVO vo = HostConnectLogConvert.MAPPER.to(s);
|
||||
vo.setExtra(JSON.parseObject(s.getExtraInfo()));
|
||||
vo.setExtra(JSON.parseObject(s.getExtraInfo(), HostConnectLogExtraDTO.class));
|
||||
return vo;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer updateStatusByToken(String token, HostConnectStatusEnum status) {
|
||||
log.info("HostConnectLogService-updateStatusByToken token: {}, status: {}", token, status);
|
||||
public Integer updateStatusByToken(String token, HostConnectStatusEnum status, Map<String, Object> partial) {
|
||||
log.info("HostConnectLogService-updateStatusByToken start token: {}, status: {}", token, status);
|
||||
// 查询
|
||||
HostConnectLogDO record = hostConnectLogDAO.of()
|
||||
.createWrapper()
|
||||
.eq(HostConnectLogDO::getToken, token)
|
||||
.then()
|
||||
.getOne();
|
||||
if (record == null) {
|
||||
log.info("HostConnectLogService-updateStatusByToken no record token: {}", token);
|
||||
return Const.N_0;
|
||||
}
|
||||
// 更新
|
||||
HostConnectLogDO update = new HostConnectLogDO();
|
||||
update.setId(record.getId());
|
||||
update.setStatus(status.name());
|
||||
update.setEndTime(new Date());
|
||||
return hostConnectLogDAO.update(update, Conditions.eq(HostConnectLogDO::getToken, token));
|
||||
if (partial != null) {
|
||||
Map<String, Object> extra = JSON.parseObject(record.getExtraInfo());
|
||||
if (extra == null) {
|
||||
extra = partial;
|
||||
} else {
|
||||
extra.putAll(partial);
|
||||
}
|
||||
update.setExtraInfo(JSON.toJSONString(extra));
|
||||
}
|
||||
return hostConnectLogDAO.updateById(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,7 +137,6 @@ public class HostConnectLogServiceImpl implements HostConnectLogService {
|
||||
|
||||
@Override
|
||||
public Integer clearHostConnectLog(HostConnectLogQueryRequest request) {
|
||||
// TODO 测试一下参数
|
||||
log.info("HostConnectLogService.clearHostConnectLog start {}", JSON.toJSONString(request));
|
||||
// 删除
|
||||
LambdaQueryWrapper<HostConnectLogDO> wrapper = this.buildQueryWrapper(request);
|
||||
@@ -144,7 +164,7 @@ public class HostConnectLogServiceImpl implements HostConnectLogService {
|
||||
session.forceOffline();
|
||||
}
|
||||
// 更新状态
|
||||
return this.updateStatusByToken(connect.getToken(), HostConnectStatusEnum.FORCE_OFFLINE);
|
||||
return this.updateStatusByToken(connect.getToken(), HostConnectStatusEnum.FORCE_OFFLINE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,20 @@ export interface HostConnectLogQueryResponse extends TableData {
|
||||
status: string;
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
extra: Record<string, any>;
|
||||
extra: HostConnectLogExtra;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主机连接日志拓展对象
|
||||
*/
|
||||
export interface HostConnectLogExtra {
|
||||
traceId: string;
|
||||
channelId: string;
|
||||
sessionId: string;
|
||||
address: string;
|
||||
location: string;
|
||||
userAgent: string;
|
||||
errorMessage: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="visible"
|
||||
title="主机连接日志详情"
|
||||
:width="420"
|
||||
:width="428"
|
||||
:mask-closable="false"
|
||||
:unmount-on-close="true"
|
||||
ok-text="关闭"
|
||||
@@ -49,6 +49,10 @@
|
||||
<a-descriptions-item label="userAgent">
|
||||
{{ record.extra?.userAgent }}
|
||||
</a-descriptions-item>
|
||||
<!-- 错误信息 -->
|
||||
<a-descriptions-item v-if="record.extra?.errorMessage" label="错误信息">
|
||||
{{ record.extra?.errorMessage }}
|
||||
</a-descriptions-item>
|
||||
<!-- 开始时间 -->
|
||||
<a-descriptions-item label="开始时间">
|
||||
{{ dateFormat(new Date(record.startTime)) }}
|
||||
@@ -57,6 +61,18 @@
|
||||
<a-descriptions-item label="结束时间">
|
||||
{{ dateFormat(new Date(record.endTime)) }}
|
||||
</a-descriptions-item>
|
||||
<!-- traceId -->
|
||||
<a-descriptions-item label="traceId">
|
||||
{{ record.extra?.traceId }}
|
||||
</a-descriptions-item>
|
||||
<!-- channelId -->
|
||||
<a-descriptions-item label="channelId">
|
||||
{{ record.extra?.channelId }}
|
||||
</a-descriptions-item>
|
||||
<!-- sessionId -->
|
||||
<a-descriptions-item label="sessionId">
|
||||
{{ record.extra?.sessionId }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import type { OperatorLogQueryResponse } from '@/api/user/operator-log';
|
||||
import { pick } from 'lodash';
|
||||
import { dateFormat } from '@/utils';
|
||||
|
||||
// 结果状态
|
||||
export const ResultStatus = {
|
||||
// 失败
|
||||
@@ -6,6 +10,23 @@ export const ResultStatus = {
|
||||
SUCCESS: 1,
|
||||
};
|
||||
|
||||
// 获取日志详情
|
||||
export const getLogDetail = (record: OperatorLogQueryResponse): Record<string, any> => {
|
||||
try {
|
||||
const detail = Object.assign({} as Record<string, any>,
|
||||
pick(record, 'traceId', 'address', 'location',
|
||||
'userAgent', 'errorMessage'));
|
||||
detail.duration = `${record.duration} ms`;
|
||||
detail.startTime = dateFormat(new Date(record.startTime));
|
||||
detail.endTime = dateFormat(new Date(record.endTime));
|
||||
detail.extra = record?.extra;
|
||||
detail.returnValue = JSON.parse(record?.returnValue);
|
||||
return detail;
|
||||
} catch (e) {
|
||||
return record;
|
||||
}
|
||||
};
|
||||
|
||||
// 操作日志模块 字典项
|
||||
export const operatorLogModuleKey = 'operatorLogModule';
|
||||
|
||||
|
||||
@@ -3,13 +3,6 @@ import { dateFormat } from '@/utils';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'id',
|
||||
dataIndex: 'id',
|
||||
slotName: 'id',
|
||||
width: 70,
|
||||
align: 'left',
|
||||
fixed: 'left',
|
||||
}, {
|
||||
title: '操作用户',
|
||||
dataIndex: 'username',
|
||||
slotName: 'username',
|
||||
@@ -20,16 +13,7 @@ const columns = [
|
||||
title: '操作模块',
|
||||
dataIndex: 'module',
|
||||
slotName: 'module',
|
||||
width: 120,
|
||||
ellipsis: true,
|
||||
tooltip: true,
|
||||
}, {
|
||||
title: '操作类型',
|
||||
dataIndex: 'type',
|
||||
slotName: 'type',
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
tooltip: true,
|
||||
width: 214,
|
||||
}, {
|
||||
title: '风险等级',
|
||||
dataIndex: 'riskLevel',
|
||||
@@ -61,7 +45,7 @@ const columns = [
|
||||
title: '操作',
|
||||
dataIndex: 'handle',
|
||||
slotName: 'handle',
|
||||
width: 90,
|
||||
width: 138,
|
||||
align: 'center',
|
||||
fixed: 'right',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user