Sequence flow path history?

Is there a way to get sequence flow execution data?
Looking to see which paths were followed. I think you can infer the flow, but is there an actual log that shows the path taken?

thanks!

Hi Stephen,

This data is currently not written to history. Your best bet is to infer that from historic activity instances, which is not always clear though.

Cheers,
Thorben

Hi,

this data is still not written to history i suppose?
Can you give me an example when i cant infere the sequence flow history or when it is not clear? Currently i cant think of such a situation.

thanks in advance!

@tim_kraeuter

and

1 Like

Looks great @StephenOTT . This covers my use case.
Im still curious about a situation when you cant derive the sequence flow from the executed activitys.
Could you show a minimal example @thorben or @StephenOTT ?

Can you explain further

I want to know an example when it is not clear which sequence flows got executed even if you have information about the historic activity instances and the process definition

If you have executions of sequence flows as history then it should be always be clear to the path your bpmn took

Edit: @tim_kraeuter to clarify a bit: When you dont use the sequence Flow listener there are scenarios where you do not know which path was taken, seems to occur often with scenarios such as parallel activity, gateways that may have multiple pathways that point to the same activity. I saw this issue with using Link activities for large bpmns.

1 Like

Thanks for your explanation @StephenOTT . Great answer !

For people who needs same thing in SpringBoot, I wanted to share my solution.

Create an execution listener to run everytime a process goes through a sequence flow.

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.ExecutionListener;
import org.camunda.bpm.engine.delegate.Expression;
import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity;

public class SequenceFlowHistoryListener implements ExecutionListener {

    @Override
    public void notify(DelegateExecution delegateExecution) throws Exception {
        try {
			// this method is called everytime a sequence flow is triggered
			
			log.info("Properties " + delegateExecution.getId() + "," + delegateExecution.getCurrentTransitionId() + "," + delegateExecution.getProcessInstanceId());
			
			// fire an historic event or do whatever you want
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

Then create a bpmn parser listener to set execution listener on each and every sequence flow in all process definitions.

import org.camunda.bpm.engine.impl.bpmn.listener.ClassDelegateExecutionListener;
import org.camunda.bpm.engine.impl.bpmn.parser.AbstractBpmnParseListener;
import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParseListener;
import org.camunda.bpm.engine.impl.pvm.process.ScopeImpl;
import org.camunda.bpm.engine.impl.pvm.process.TransitionImpl;
import org.camunda.bpm.engine.impl.util.xml.Element;

public class CustomParseListener extends AbstractBpmnParseListener implements BpmnParseListener {

	@Override
	public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
		super.parseSequenceFlow(sequenceFlowElement, scopeElement, transition);
		try {
			ClassDelegateExecutionListener classDelegateExecutionListener = new ClassDelegateExecutionListener(SequenceFlowHistoryListener.class, null);
			transition.addListener("take", classDelegateExecutionListener);
		} catch (Exception e){
			e.printStackTrace();
		}
	}
}

Then wire parser listener to process engine configuration.

import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.impl.bpmn.parser.BpmnParseListener;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
import org.camunda.bpm.spring.boot.starter.configuration.Ordering;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(Ordering.DEFAULT_ORDER -1)
public class MyCamundaProcessEnginePlugin implements ProcessEnginePlugin {

    @Override
    public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
        List<BpmnParseListener> postParseListeners = processEngineConfiguration.getCustomPostBPMNParseListeners();
        if (postParseListeners == null) {
            postParseListeners = new ArrayList<>();
            processEngineConfiguration.setCustomPostBPMNParseListeners(postParseListeners);
        }
        postParseListeners.add(new CustomParseListener());
    }

    @Override
    public void postInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
        
    }

    @Override
    public void postProcessEngineBuild(ProcessEngine processEngine) {
        
    }
}
2 Likes

If this could also be visualized in the cockpit – that would be cool!

@fml2 vote for this issue: https://jira.camunda.com/browse/CAM-12959 (History events should be written for sequence flows)

(not sure if camunda product mgmt actually looks at votes; so make a comment or something :slight_smile: )

1 Like

The issue is related to my wish but not the same. I’d just wanted to have them visualized in the instance view so that I can quickly see the executed path(s).

They are not visualized because there is no history of their execution. If there was history then adding the visualization is trivial.

@fml2 With visualization, would you happen to mean something similar to what @nikku implemented in GitHub - nikku/camunda-playground: Try out and explore Camunda in minutes, not hours. (Although, it simply highlights sequence flow paths between completed activities, so there must be corner cases where it renders false positives.)

Just in case (and because I was supposed to try that out later anyway) I spent a few hours to include camunda-playground approach into my “instance history” cockpit plugin:

Cockpit plugin instance-historic-activities.js (for >= 7.14.0) shown in the screenshot above is available at https://github.com/datakurre/camunda-cockpit-plugins/tree/sequence-flow (Obviously, because I just added it, I have not tried it with real data yet. Just blindly trusting camunda-playground approach :slight_smile: .)

Can see code in: https://github.com/StephenOTT/camunda-coverage-generation

Where it generates sequence flow historic events and then renders then in BPMN.io. The native Historic Activity Event query api works / returns the desired events. You just need to covert the similar code into a cockpit styled view.

@datakurre Yes, this is exactly what I’ve been thinking about (the information source does not matter to me). Just highlighting the arrows that were executed. I’d probably choose other style (color and thickness), but it’s a matter of taste.

I see that for the bent connection, the highlighted path is not the same as the one from the designer. Is it possible to fix that?

I’ll definitely look into the plugin!

@StephenOTT Very cool! I didn’t know bpmn.io can be patched that simply. Is it possible to integrate this patch into the cockpit as weill?

Not with the approach from camunda-playground renders path on top of the original diagram in using naive curves only aware of start and end points. Stephen’s code looks like it highlights the actual paths rendered, so it might be closer to your needs :thinking: