Implementing custom history level engine plugin

Hello there,

I’m trying to implement a custom history level engine plugin. My goal is to use the history level “full” and additionally configure a plugin so that some variables are not written to history. I’m therefore following the example in the Camunda repository https://github.com/camunda/camunda-bpm-examples/tree/master/process-engine-plugin/custom-history-level#configure-custom-history-level.

I’m using the pre-packaged Camunda apache setup. The setup has already been running in “full” mode, i.e. the database has been created.

So I cloned the repository, built the plugin with maven and moved the .jar to the …\server\apache-tomcat-9.0.33\lib folder.

Then I modified the bpm-platform.xml by adding:

<bpm-platform>
  <process-engine>
    <plugins>
      <plugin>
        <class>org.camunda.bpm.example.CustomHistoryLevelProcessEnginePlugin</class>
      </plugin>
    </plugins>
  </process-engine>
</bpm-platform>

At startup, the catalina logs shows

org.camunda.commons.logging.BaseLogger.logInfo ENGINE-12003 Plugin 'CustomHistoryLevelProcessEnginePlugin' activated on process engine 'default'

So far so good. However, the plugin does not work yet. But then I’m a bit lost as to what to do. When adding my custom history level to the properties will throw an exception.

<bpm-platform>
  <process-engine>
    <properties>
      <property name="history">full</property>
	  <property name="history">custom-variable</property>
	</properties>  
  </process-engine>
</bpm-platform>

Exception:

org.camunda.commons.logging.BaseLogger.logError ENGINE-16004 Exception while closing command context: historyLevel mismatch: configuration says org.camunda.bpm.example.CustomVariableHistoryLevel@4f80cb and database says HistoryLevelFull(name=full, id=3)

The exception is also thrown when I remove the “full” property.

Now, I understand that if I wanted to change the history level in general for an existing database, I would neet to change the entry “historyLevel” in the table “act_ge_property”. However, I don’t know if I should do this in my use case and if I should, to what value.

In the documentation (History and Audit Event Log | docs.camunda.org) it is stated: “Keep in mind: If you are planning to use custom history levels, you have to register the custom levels for every configuration, otherwise an exception is thrown.” Unfortunately, I don’t unterstand what is meant by “register…for every configuration”, i.e. where is this registration done and how? I was under the impression that the registration is done in the CustomVariableHistoryLevel class of the example from the repository, i.e.:

public class CustomHistoryLevelProcessEnginePlugin extends AbstractProcessEnginePlugin {

  public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
	List<HistoryLevel> customHistoryLevels = processEngineConfiguration.getCustomHistoryLevels();
	if (customHistoryLevels == null) {
	  customHistoryLevels = new ArrayList<HistoryLevel>();
	  processEngineConfiguration.setCustomHistoryLevels(customHistoryLevels);
	}
	customHistoryLevels.add(CustomVariableHistoryLevel.getInstance());
	customHistoryLevels.add(PerProcessHistoryLevel.getInstance());
  }

  public void postInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
	PerProcessHistoryLevel.getInstance().addHistoryLevels(processEngineConfiguration.getCustomHistoryLevels());
  }
}

Now I could delete the database and remove the “full” property from the configuration and then Camunda will start. But that is neither my goal, not will it work for our production system. I’m looking for a solution to add the plugin to the existing “full” history level while keeping the data in the database.

Could someone point me in the right direction here as how to proceed?

As you correctly pointed out, this is the boat you find yourself in when you attempt to change the history level of an already running deployment (similar to what you’ll find in this post).

I think all you need to do is change the historyLevel entry in ACT_GE_PROPERTY to be the id of your custom history level implementation. Per the docs found here, your implementation should have an implementation for getId. Use this value. That way the single entry in the database (id) matches the single entry of <property name="history">custom-variable</property> in your config.

2 Likes

Thanks, that worked!