Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Customizable Event Log inside Camunda BPM process

Context  : Business Process Management (BPM) / Decision Management (DM)  
Framework: Camunda (

The problem

A BPM (Business Process Management) process exists of lots of flow objects (activities, events, gateways) and at some point of execution - for example when a user is prompted to perform a task - an information about "what happend so far" is helpful or even required.

Looking at the following process

Demo process

it might be helpful in Task 5 just to know that Task 1 and Task 3 happend. Task 5 could be a user task and of course the process should provide all information needed to complete this task. However, the complete process flow may not be known to the user and information about some things that happened might be useful.

Let's call the "what happend so far" information Event Log and let's consider how to get this information.

possible Solutions (not discussed here)

There are several options I can imagine to assemble the Event Log information.

query the history

Camunda BPM offers a (History and Audit Event Log). This offers access to all interesting data of a process execution and you'll probably find what you're looking for. But it may be too complex and the processing of the results for the required information can be cumbersome.

hold an own "Event Log" managed by Intermediate None Events

You can use Intermediate None Events at special points of interest in your process flow (see below).

Demo process with None Events

There you can hook in code that manages an own Event Log (probably added as process variable to the process instance). The Event Log can be easily made available to interesting clients (e.g. a User Interface that supports to handle a User Task). I somehow like that the "special events" are clearly visible in the process model, but strictly speaking they are not really important to the process. Moreover they are not very flexible and if a "point of interest" changes the process flow needs a change as well.

using Decision Management to manage an own "Event Log"

I finally found a way to use a decision table for my goal to manage a Custom Event Log for a running process. My DMN diagram looks like that:

DM process configuration

The rules in the diagram define Events that I would like to handle in a special case. An Event is specified by the activityId and the eventName as they occur in the process. The output of a rule is just a simple message that I can add to my Custom Event Log.

On the Java Code side I implemented a GlobalExecutionListener. This listener listens to each activity event that is executed by the process and if an activity/event matches a DM rule a custom treatment can be done. In my original use case I just add the rule output to a list of Strings. This list makes up my "Event Log" and I put it as a process variable to the process instance.

In the example code (see snippet below) here I just print the output message to the console.

    public void notify(final DelegateExecution execution) throws Exception {
        System.out.println("Entering activity (activitId=" + execution.getCurrentActivityId()
                + ", eventName=" + execution.getEventName() + ") ...");

     * Checks if the current execution matches the configuration. If {@code yes} performs desired
     * operation; here just prints a message that was specified in the DMN model.
     * @param execution the current execution
    private void handleEventLog(final DelegateExecution execution) {
        if (execution.getCurrentActivityId() != null && execution.getEventName() != null) {
            VariableMap variables =
                    Variables.putValue("activityId", execution.getCurrentActivityId())
                            .putValue("eventName", execution.getEventName());
            DmnDecisionTableResult result =
                    dmnEngine.evaluateDecisionTable(eventLogDecision, variables);
            if (!result.isEmpty()) {
                // the configuration matched the event
                System.out.println(">>> " + result.getSingleEntry().toString());

Oh, how did I manage to attach the Listener to all process activities? My project is a Spring Boot project using the camunda-bpm-spring-boot-starter. My Main class (wich is also the root of my Spring context configuration) extends the SpringBootProcessApplication and overrides the getExecutionListener method (therefore the Process Engine Plugin needs to be activated). How simple is that?

package de.frvabe.bpm.camunda;

import org.camunda.bpm.application.ProcessApplication;
import org.camunda.bpm.engine.delegate.ExecutionListener;
import org.camunda.bpm.spring.boot.starter.SpringBootProcessApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

 * The core Spring Application configuration.
public class Main extends SpringBootProcessApplication {

    public ExecutionListener getExecutionListener() {
        return new GlobalExecutionListener();

    public static void main(final String... args) {, args);



I think I found an interesting approach to implement something that I would call a "Custom EventLog" using BPM and DM. It offers great flexibility in choosing (and changing) Events that should be logged without changing the process.

But - to be honest - I am not really sure if this is the way to go. Some disadvanteges I see are

  • overhead of (useless) GlobalExecutionListener invocations and rule processing
  • the GlobalExecutionListener might be better used to do something else (and I only have one)
  • ...

So - if you could follow me - I would love to here your opinion about my approach. Feel free to contact me at Twitter (@FrVaBe) or open an issue here with your comment.

If you want to have a deeper look at the solution just clone the project. The camunda-customizable-event-log contains a complete Maven project where you can find a unit test that starts a process and observe the behavior.