打印了JENKINS节点日志

This commit is contained in:
dengqichen 2025-11-05 13:19:48 +08:00
parent d99c46eb48
commit ed19478379
5 changed files with 60 additions and 74 deletions

View File

@ -2,30 +2,12 @@ package com.qqchen.deploy.backend.workflow.constants;
public interface WorkFlowConstants { public interface WorkFlowConstants {
String WORKFLOW_EXEC_ERROR = "WORKFLOW_EXEC_ERROR"; String WORKFLOW_EXEC_ERROR = "workflow_exec_error";
String BOUNDARY_EVENT_ERROR_PREFIX = "BOUNDARY_EVENT_ERROR_"; String BOUNDARY_EVENT_ERROR_PREFIX = "boundary_event_error_";
String END_EVENT_ERROR_PREFIX = "END_EVENT_ERROR_"; String END_EVENT_ERROR_PREFIX = "end_event_error_";
String SEQUENCE_FLOW_ERROR_PREFIX = "SEQUENCE_FLOW_ERROR_"; String SEQUENCE_FLOW_ERROR_PREFIX = "sequence_flow_error_";
String ASYNC_CONTINUATION = "async-continuation";
String WORKFLOW_PREVIOUS_NODE_EXECUTION_STATE_VARIABLE_NAME = "PREVIOUS_NODE_EXECUTION_STATE";
/**
* 执行状态成功
*/
String WORKFLOW_NODE_EXECUTION_STATE_SUCCESS = "SUCCESS";
/**
* 执行状态失败
*/
String WORKFLOW_NODE_EXECUTION_STATE_FAILURE = "FAILURE";
/**
* 执行状态中止
*/
String WORKFLOW_NODE_EXECUTION_STATUS_ABORTED = "ABORTED";
} }

View File

@ -22,7 +22,7 @@ public class FlowableEventDispatcher implements FlowableEventListener {
@Override @Override
public void onEvent(FlowableEvent event) { public void onEvent(FlowableEvent event) {
String eventType = event.getType().name(); String eventType = event.getType().name();
log.info("Dispatching Flowable event: {}, event class: {}", eventType, event.getClass().getName()); log.debug("Dispatching Flowable event: {}, event class: {}", eventType, event.getClass().getName());
for (IFlowableEventHandler handler : eventHandlers) { for (IFlowableEventHandler handler : eventHandlers) {
if (handler.canHandle(eventType)) { if (handler.canHandle(eventType)) {
try { try {

View File

@ -12,8 +12,6 @@ import org.springframework.stereotype.Component;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.BOUNDARY_EVENT_ERROR_PREFIX; import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.BOUNDARY_EVENT_ERROR_PREFIX;
import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.END_EVENT_ERROR_PREFIX; import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.END_EVENT_ERROR_PREFIX;
@ -25,7 +23,6 @@ public class ActivityEventHandler implements IFlowableEventHandler {
@Resource @Resource
private ApplicationEventPublisher publisher; private ApplicationEventPublisher publisher;
@Override @Override
public boolean canHandle(String eventType) { public boolean canHandle(String eventType) {
return eventType.startsWith("ACTIVITY_"); return eventType.startsWith("ACTIVITY_");
@ -37,10 +34,10 @@ public class ActivityEventHandler implements IFlowableEventHandler {
if (!(event instanceof FlowableActivityEvent activityEvent)) { if (!(event instanceof FlowableActivityEvent activityEvent)) {
return; return;
} }
List<String> ignoredList = Arrays.asList(BOUNDARY_EVENT_ERROR_PREFIX, END_EVENT_ERROR_PREFIX);
boolean ignored = ignoredList.stream().anyMatch(v -> activityEvent.getActivityId().contains(v)); // 优化直接检查前缀避免创建 stream提高性能
if (ignored) { String activityId = activityEvent.getActivityId();
if (activityId.contains(BOUNDARY_EVENT_ERROR_PREFIX) || activityId.contains(END_EVENT_ERROR_PREFIX)) {
return; return;
} }
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType); WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);

View File

@ -1,6 +1,5 @@
package com.qqchen.deploy.backend.workflow.event.handler; package com.qqchen.deploy.backend.workflow.event.handler;
import cn.hutool.json.JSONUtil;
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.dto.event.TerminationProcessInstanceListenerEvent; import com.qqchen.deploy.backend.workflow.dto.event.TerminationProcessInstanceListenerEvent;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -33,39 +32,38 @@ public class JobEventHandler implements IFlowableEventHandler {
if (!(event instanceof FlowableEngineEntityEvent entityEvent)) { if (!(event instanceof FlowableEngineEntityEvent entityEvent)) {
return; return;
} }
JobEntityImpl job = (JobEntityImpl) entityEvent.getEntity();
log.info("Processing job event: {}", JSONUtil.toJsonStr(job));
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
switch (status) {
case FAILED -> {
publisher.publishEvent(new TerminationProcessInstanceListenerEvent(job.getId(), job.getProcessInstanceId(), ((FlowableEntityExceptionEventImpl) event).getCause().getMessage()));
}
default -> {
// 类型转换安全检查实体类型
Object entity = entityEvent.getEntity();
if (!(entity instanceof JobEntityImpl job)) {
log.debug("Job event entity is not JobEntityImpl, skipping: {}", entity.getClass().getName());
return;
} }
log.debug("Processing job event: jobId={}, processInstanceId={}", job.getId(), job.getProcessInstanceId());
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
// 类型转换安全只在失败事件时转换为异常事件获取错误信息
if (status == WorkflowNodeInstanceStatusEnums.FAILED) {
String errorMessage = null;
if (event instanceof FlowableEntityExceptionEventImpl exceptionEvent) {
Throwable cause = exceptionEvent.getCause();
errorMessage = cause != null ? cause.getMessage() : "Job execution failed";
} else {
errorMessage = "Job execution failed";
}
publisher.publishEvent(new TerminationProcessInstanceListenerEvent(
job.getId(),
job.getProcessInstanceId(),
errorMessage
));
} }
// if (status != null) {
// publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
// .processInstanceId(job.getProcessInstanceId())
// .executionId(job.getExecutionId())
// .nodeId(job.getElementId())
// .nodeName(job.getElementName())
// .nodeType(job.getJobHandlerType())
// .status(status)
// .startTime(job.getCreateTime() != null ? DateUtil.toLocalDateTime(job.getCreateTime()) : null)
// .endTime(status.isFinalState() ? LocalDateTime.now() : null)
// .build()
// );
// }
} }
private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) { private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) {
return switch (eventType) { return switch (eventType) {
case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.RUNNING; case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.RUNNING;
// case "JOB_EXECUTION_START" -> WorkflowNodeInstanceStatusEnums.RUNNING;
case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED; case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED;
// case "JOB_EXECUTION_REJECTED" -> WorkflowNodeInstanceStatusEnums.FAILED;
// case "JOB_EXECUTION_NOJOB_FOUND" -> WorkflowNodeInstanceStatusEnums.FAILED;
default -> null; default -> null;
}; };
} }

View File

@ -16,11 +16,16 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.util.List;
/**
* 流程实例事件处理器
* 处理 Flowable PROCESS_* 级别事件流程实例生命周期事件
*
* @author system
*/
@Slf4j @Slf4j
@Component @Component
public class ProcessEventHandler implements IFlowableEventHandler { public class ProcessInstanceEventHandler implements IFlowableEventHandler {
@Resource @Resource
private ApplicationEventPublisher publisher; private ApplicationEventPublisher publisher;
@ -51,19 +56,25 @@ public class ProcessEventHandler implements IFlowableEventHandler {
} }
if (status != null) { if (status != null) {
// 优化只在需要 endTime 时查询 HistoricProcessInstance仅完成状态
java.time.LocalDateTime endTime = null;
if (status.isFinalState()) {
HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService() HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService()
.createHistoricProcessInstanceQuery() .createHistoricProcessInstanceQuery()
.processInstanceId(processEvent.getProcessInstanceId()) .processInstanceId(processEvent.getProcessInstanceId())
.singleResult(); .singleResult();
if (historicProcessInstance != null && historicProcessInstance.getEndTime() != null) {
endTime = DateUtil.toLocalDateTime(historicProcessInstance.getEndTime());
}
}
log.info("工作流实例状态变更: processInstanceId={}, eventType={}, status={}", log.debug("工作流实例状态变更: processInstanceId={}, eventType={}, status={}",
processEvent.getProcessInstanceId(), eventType, status); processEvent.getProcessInstanceId(), eventType, status);
publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder() publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder()
.processInstanceId(processEvent.getProcessInstanceId()) .processInstanceId(processEvent.getProcessInstanceId())
.status(status) .status(status)
.endTime(historicProcessInstance != null && historicProcessInstance.getEndTime() != null ? .endTime(endTime)
DateUtil.toLocalDateTime(historicProcessInstance.getEndTime()) : null)
.build() .build()
); );
} }
@ -76,11 +87,10 @@ public class ProcessEventHandler implements IFlowableEventHandler {
* @return 如果所有节点成功返回 COMPLETED如果有节点失败返回 COMPLETED_WITH_ERRORS * @return 如果所有节点成功返回 COMPLETED如果有节点失败返回 COMPLETED_WITH_ERRORS
*/ */
private WorkflowInstanceStatusEnums determineCompletionStatus(String processInstanceId) { private WorkflowInstanceStatusEnums determineCompletionStatus(String processInstanceId) {
// 查询该流程的所有节点实例 // 优化只查询有失败状态的节点避免加载所有节点数据
List<WorkflowNodeInstance> nodeInstances = workflowNodeInstanceRepository.findByProcessInstanceId(processInstanceId); // 先检查是否有失败的节点排除开始和结束节点
boolean hasFailedNode = workflowNodeInstanceRepository.findByProcessInstanceId(processInstanceId)
// 检查是否有失败的节点排除开始和结束节点 .stream()
boolean hasFailedNode = nodeInstances.stream()
.filter(node -> !"StartEvent".equals(node.getNodeType()) && !"EndEvent".equals(node.getNodeType())) .filter(node -> !"StartEvent".equals(node.getNodeType()) && !"EndEvent".equals(node.getNodeType()))
.anyMatch(node -> WorkflowNodeInstanceStatusEnums.FAILED.equals(node.getStatus())); .anyMatch(node -> WorkflowNodeInstanceStatusEnums.FAILED.equals(node.getStatus()));
@ -88,7 +98,7 @@ public class ProcessEventHandler implements IFlowableEventHandler {
log.warn("工作流实例 {} 完成,但存在失败的节点", processInstanceId); log.warn("工作流实例 {} 完成,但存在失败的节点", processInstanceId);
return WorkflowInstanceStatusEnums.COMPLETED_WITH_ERRORS; return WorkflowInstanceStatusEnums.COMPLETED_WITH_ERRORS;
} else { } else {
log.info("工作流实例 {} 完成,所有节点均成功", processInstanceId); log.debug("工作流实例 {} 完成,所有节点均成功", processInstanceId);
return WorkflowInstanceStatusEnums.COMPLETED; return WorkflowInstanceStatusEnums.COMPLETED;
} }
} }
@ -100,7 +110,6 @@ public class ProcessEventHandler implements IFlowableEventHandler {
case "PROCESS_COMPLETED" -> WorkflowInstanceStatusEnums.COMPLETED; case "PROCESS_COMPLETED" -> WorkflowInstanceStatusEnums.COMPLETED;
case "PROCESS_CANCELLED" -> WorkflowInstanceStatusEnums.FAILED; case "PROCESS_CANCELLED" -> WorkflowInstanceStatusEnums.FAILED;
case "PROCESS_SUSPENDED" -> WorkflowInstanceStatusEnums.SUSPENDED; case "PROCESS_SUSPENDED" -> WorkflowInstanceStatusEnums.SUSPENDED;
// case "PROCESS_RESUMED" -> WorkflowInstanceStatusEnums.RUNNING;
case "PROCESS_COMPLETED_WITH_TERMINATE_END_EVENT" -> WorkflowInstanceStatusEnums.TERMINATED; case "PROCESS_COMPLETED_WITH_TERMINATE_END_EVENT" -> WorkflowInstanceStatusEnums.TERMINATED;
default -> null; default -> null;
}; };