增加部署日志
This commit is contained in:
parent
649b14a739
commit
4b554a8a2a
@ -76,7 +76,7 @@ public class DeployRecord extends Entity<Long> {
|
|||||||
/**
|
/**
|
||||||
* 部署状态
|
* 部署状态
|
||||||
*/
|
*/
|
||||||
@Column(name = "status", nullable = false, length = 20)
|
@Column(name = "status", nullable = false, length = 50)
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private DeployRecordStatusEnums status;
|
private DeployRecordStatusEnums status;
|
||||||
|
|
||||||
|
|||||||
@ -42,19 +42,20 @@ public enum DeployRecordStatusEnums {
|
|||||||
PARTIAL_SUCCESS("PARTIAL_SUCCESS", "部分成功"),
|
PARTIAL_SUCCESS("PARTIAL_SUCCESS", "部分成功"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 已取消
|
* 审批被拒绝(终态)
|
||||||
|
*/
|
||||||
|
REJECTED("REJECTED", "审批被拒绝"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已取消(终态)
|
||||||
|
* 用于:手动取消部署、超时自动取消等场景
|
||||||
*/
|
*/
|
||||||
CANCELLED("CANCELLED", "已取消"),
|
CANCELLED("CANCELLED", "已取消"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 已终止
|
* 已终止(终态)
|
||||||
*/
|
*/
|
||||||
TERMINATED("TERMINATED", "已终止"),
|
TERMINATED("TERMINATED", "已终止");
|
||||||
|
|
||||||
/**
|
|
||||||
* 已暂停
|
|
||||||
*/
|
|
||||||
SUSPENDED("SUSPENDED", "已暂停");
|
|
||||||
|
|
||||||
private final String code;
|
private final String code;
|
||||||
private final String description;
|
private final String description;
|
||||||
@ -75,7 +76,7 @@ public enum DeployRecordStatusEnums {
|
|||||||
case "COMPLETED_WITH_ERRORS" -> PARTIAL_SUCCESS;
|
case "COMPLETED_WITH_ERRORS" -> PARTIAL_SUCCESS;
|
||||||
case "FAILED" -> FAILED;
|
case "FAILED" -> FAILED;
|
||||||
case "TERMINATED" -> TERMINATED;
|
case "TERMINATED" -> TERMINATED;
|
||||||
case "SUSPENDED" -> SUSPENDED;
|
case "SUSPENDED" -> RUNNING; // 工作流暂停时,部署记录仍视为运行中(可恢复)
|
||||||
default -> CREATED;
|
default -> CREATED;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,106 @@
|
|||||||
|
package com.qqchen.deploy.backend.deploy.listener;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.deploy.service.IDeployRecordService;
|
||||||
|
import com.qqchen.deploy.backend.workflow.dto.event.WorkflowInstanceStatusChangeEvent;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
|
||||||
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowCategoryRepository;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
|
||||||
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowCategory;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部署记录工作流状态同步监听器
|
||||||
|
* 监听工作流实例状态变化事件,同步更新部署记录状态
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-11-02
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class DeployRecordWorkflowStatusSyncListener {
|
||||||
|
|
||||||
|
private static final String DEPLOYMENT_CATEGORY_CODE = "DEPLOYMENT";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IDeployRecordService deployRecordService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IWorkflowInstanceRepository workflowInstanceRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IWorkflowDefinitionRepository workflowDefinitionRepository;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IWorkflowCategoryRepository workflowCategoryRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听工作流实例状态变化事件
|
||||||
|
* 同步更新部署记录状态
|
||||||
|
*/
|
||||||
|
@EventListener
|
||||||
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||||
|
public void handleWorkflowStatusChange(WorkflowInstanceStatusChangeEvent event) {
|
||||||
|
try {
|
||||||
|
// 1. 查询工作流实例
|
||||||
|
WorkflowInstance instance = workflowInstanceRepository
|
||||||
|
.findByProcessInstanceId(event.getProcessInstanceId())
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (instance == null) {
|
||||||
|
log.warn("工作流实例不存在: processInstanceId={}", event.getProcessInstanceId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 判断是否为部署类型的工作流(提前校验,避免不必要的操作)
|
||||||
|
if (!isDeploymentWorkflow(instance)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新工作流实例的结束时间(如果事件中有且实例中还没有)
|
||||||
|
if (event.getEndTime() != null && instance.getEndTime() == null) {
|
||||||
|
instance.setEndTime(event.getEndTime());
|
||||||
|
workflowInstanceRepository.save(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 同步状态(处理状态优先级)
|
||||||
|
// 注意:这里需要确保 instance 的 endTime 已更新,因为 syncStatusFromWorkflowInstance 会使用它
|
||||||
|
deployRecordService.syncStatusFromWorkflowInstance(instance, event.getStatus());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("同步部署记录状态失败(工作流状态变化): processInstanceId={}",
|
||||||
|
event.getProcessInstanceId(), e);
|
||||||
|
// 不影响主流程,只记录错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为部署类型的工作流
|
||||||
|
*/
|
||||||
|
private boolean isDeploymentWorkflow(WorkflowInstance instance) {
|
||||||
|
if (instance.getWorkflowDefinitionId() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkflowDefinition definition = workflowDefinitionRepository
|
||||||
|
.findById(instance.getWorkflowDefinitionId())
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (definition == null || definition.getCategoryId() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkflowCategory category = workflowCategoryRepository
|
||||||
|
.findById(definition.getCategoryId())
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
return category != null && DEPLOYMENT_CATEGORY_CODE.equals(category.getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -53,15 +53,15 @@ public interface IDeployRecordRepository extends IBaseRepository<DeployRecord, L
|
|||||||
*
|
*
|
||||||
* 统计规则:
|
* 统计规则:
|
||||||
* - 成功:SUCCESS状态
|
* - 成功:SUCCESS状态
|
||||||
* - 失败:FAILED/CANCELLED/TERMINATED/PARTIAL_SUCCESS状态,或CREATED状态超过30分钟仍未更新(视为启动失败)
|
* - 失败:FAILED/REJECTED/CANCELLED/TERMINATED/PARTIAL_SUCCESS状态,或CREATED状态超过30分钟仍未更新(视为启动失败)
|
||||||
* (PARTIAL_SUCCESS虽然工作流完成,但存在失败节点,视为部署不完整,计入失败)
|
* (REJECTED=审批被拒绝,PARTIAL_SUCCESS虽然工作流完成,但存在失败节点,视为部署不完整,计入失败)
|
||||||
* - 运行中:RUNNING状态,或CREATED状态在30分钟内(视为正在启动)
|
* - 运行中:RUNNING状态,或CREATED状态在30分钟内(视为正在启动)
|
||||||
*/
|
*/
|
||||||
@Query(value = "SELECT " +
|
@Query(value = "SELECT " +
|
||||||
" dr.team_application_id as teamApplicationId, " +
|
" dr.team_application_id as teamApplicationId, " +
|
||||||
" COUNT(dr.id) as totalCount, " +
|
" COUNT(dr.id) as totalCount, " +
|
||||||
" SUM(CASE WHEN dr.status = 'SUCCESS' THEN 1 ELSE 0 END) as successCount, " +
|
" SUM(CASE WHEN dr.status = 'SUCCESS' THEN 1 ELSE 0 END) as successCount, " +
|
||||||
" SUM(CASE WHEN dr.status IN ('FAILED', 'CANCELLED', 'TERMINATED', 'PARTIAL_SUCCESS') " +
|
" SUM(CASE WHEN dr.status IN ('FAILED', 'REJECTED', 'CANCELLED', 'TERMINATED', 'PARTIAL_SUCCESS') " +
|
||||||
" OR (dr.status = 'CREATED' AND TIMESTAMPDIFF(MINUTE, dr.create_time, NOW()) > 30) " +
|
" OR (dr.status = 'CREATED' AND TIMESTAMPDIFF(MINUTE, dr.create_time, NOW()) > 30) " +
|
||||||
" THEN 1 ELSE 0 END) as failedCount, " +
|
" THEN 1 ELSE 0 END) as failedCount, " +
|
||||||
" SUM(CASE WHEN dr.status = 'RUNNING' " +
|
" SUM(CASE WHEN dr.status = 'RUNNING' " +
|
||||||
|
|||||||
@ -85,7 +85,7 @@ public class DeployRecordServiceImpl extends BaseServiceImpl<DeployRecord, Deplo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果当前状态已经是终态(特别是审批被拒绝的CANCELLED),不应该被覆盖
|
// 如果当前状态已经是终态(特别是审批被拒绝的REJECTED),不应该被覆盖
|
||||||
if (isFinalState(record.getStatus())) {
|
if (isFinalState(record.getStatus())) {
|
||||||
log.debug("部署记录已处于终态,跳过同步: id={}, workflowInstanceId={}, currentStatus={}, workflowStatus={}",
|
log.debug("部署记录已处于终态,跳过同步: id={}, workflowInstanceId={}, currentStatus={}, workflowStatus={}",
|
||||||
record.getId(), instance.getId(), record.getStatus(), status);
|
record.getId(), instance.getId(), record.getStatus(), status);
|
||||||
@ -172,9 +172,9 @@ public class DeployRecordServiceImpl extends BaseServiceImpl<DeployRecord, Deplo
|
|||||||
log.info("部署记录状态已更新为运行中(审批通过): id={}, workflowInstanceId={}",
|
log.info("部署记录状态已更新为运行中(审批通过): id={}, workflowInstanceId={}",
|
||||||
record.getId(), workflowInstanceId);
|
record.getId(), workflowInstanceId);
|
||||||
} else {
|
} else {
|
||||||
// 审批被拒绝,更新为已取消
|
// 审批被拒绝,更新为审批被拒绝
|
||||||
record.setStatus(DeployRecordStatusEnums.CANCELLED);
|
record.setStatus(DeployRecordStatusEnums.REJECTED);
|
||||||
log.info("部署记录状态已更新为已取消(审批被拒): id={}, workflowInstanceId={}",
|
log.info("部署记录状态已更新为审批被拒绝: id={}, workflowInstanceId={}",
|
||||||
record.getId(), workflowInstanceId);
|
record.getId(), workflowInstanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +187,7 @@ public class DeployRecordServiceImpl extends BaseServiceImpl<DeployRecord, Deplo
|
|||||||
private boolean isFinalState(DeployRecordStatusEnums status) {
|
private boolean isFinalState(DeployRecordStatusEnums status) {
|
||||||
return status == DeployRecordStatusEnums.SUCCESS
|
return status == DeployRecordStatusEnums.SUCCESS
|
||||||
|| status == DeployRecordStatusEnums.FAILED
|
|| status == DeployRecordStatusEnums.FAILED
|
||||||
|
|| status == DeployRecordStatusEnums.REJECTED
|
||||||
|| status == DeployRecordStatusEnums.CANCELLED
|
|| status == DeployRecordStatusEnums.CANCELLED
|
||||||
|| status == DeployRecordStatusEnums.TERMINATED
|
|| status == DeployRecordStatusEnums.TERMINATED
|
||||||
|| status == DeployRecordStatusEnums.PARTIAL_SUCCESS;
|
|| status == DeployRecordStatusEnums.PARTIAL_SUCCESS;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user