Show Table of Contents

13.2. Audit Log
Storing information about the execution of process instances can be useful when you need to, for example:
- Verify which actions have been executed in a particular process instance.
- Monitor and analyze the efficiency of a particular process.
However, storing history information in the runtime database can result in the database rapidly increasing in size. Additionally, monitoring and analysis queries might influence the performance of your runtime engine. This is why process execution history logs are stored separately.
The JBoss BPM Suite creates a history log of execution based on events generated by the process engine during execution. This is possible because the JBoss BPM Suite runtime engine provides a generic event listener. That's why you can easily retrieve and store any information from the events and store it in a database. You can also use filters to limit the scope of the logged information.
13.2.1. Audit Data Model
The
jbpm-audit module contains an event listener that stores process-related information in a database using Java Persistence API (JPA). The data model contains three entities: one for process instance information, one for node instance information, and one for (process) variable instance information:
- The ProcessInstanceLog table contains the basic log information about a process instance.
- The NodeInstanceLog table contains information about which nodes were actually executed inside each process instance. Whenever a node instance is entered from one of its incoming connections or is exited through one of its outgoing connections, that information is stored in this table.
- The VariableInstanceLog table contains information about changes in variable instances. The default is to only generate log entries when (after) a variable changes. It is also possible to log entries before the variable (value) changes.
13.2.2. Audit Data Model Description
Each of the entities in the audit data model contain following elements:

Figure 13.2. Audit Data Model
Table 13.8. ProcessInstanceLog
| Field | Description | Nullable |
|---|---|---|
| id | The primary key and id of the log entity. | NOT NULL |
| duration | Duration of a process instance since its start date. | |
| end_date | The end date of a process instance when applicable. | |
| externalId | Optional external identifier used to correlate various elements, for example deployment id. | |
| user_identity | Optional identifier of the user who started the process instance. | |
| outcome | Contains the outcome of a process instance, for example the error code. | |
| parentProcessInstanceId | The process instance id of the parent process instance. | |
| processid | Id of the executed process. | |
| processinstanceid | The process instance id. | NOT NULL |
| processname | The name of the process. | |
| processversion | The version of the process. | |
| start_date | The start date of the process instance. | |
| status | The status of process instance that maps to process instance state. |
Table 13.9. NodeInstanceLog
| Field | Description | Nullable |
|---|---|---|
| id | Primary key and id of the log entity. | NOT NULL |
| connection | Identifier of the sequence flow that led to this node instance. | |
| log_date | Date of the event. | |
| externalId | Optional external identifier used to correlate various elements, for example deployment id. | |
| nodeid | Node id of the corresponding node in the process definition. | |
| nodeinstanceid | Instance id of the node. | |
| nodename | Name of the node. | |
| nodetype | The type of the node. | |
| processid | Id of the executed process. | |
| processinstanceid | Id of the process instance. | NOT NULL |
| type | The type of the event (0 = enter, 1 = exit). | NOT NULL |
| workItemId | Optional identifier of work items available only for certain node types. |
Table 13.10. VariableInstanceLog
| Field | Description | Nullable |
|---|---|---|
| id | Primary key and id of the log entity. | NOT NULL |
| externalId | Optional external identifier used to correlate various elements, for example deployment id. | |
| log_date | Date of the event. | |
| processid | Id of the executed process. | |
| processinstanceid | Id of the process instance. | NOT NULL |
| oldvalue | Previous value of the variable at the time of recording of the log. | |
| value | The value of the variable at the time of recording of the log. | |
| variableid | Variable id in the process definition. | |
| variableinstanceid | The id of the variable instance. |
13.2.3. Storing Process Events in a Database
To log process history in a database, register a logger in your session:
EntityManagerFactory emf = ...; StatefulKnowledgeSession ksession = ...; AbstractAuditLogger auditLogger = AuditLoggerFactory.newJPAInstance(emf); ksession.addProcessEventListener(auditLogger); // invoke methods one your session here
Modify
persistence.xml to specify a database. You need to include audit log classes as well (ProcessInstanceLog, NodeInstanceLog, and VariableInstanceLog). See the example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence
version="2.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd
http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance>
<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/jbpm-ds</jta-data-source>
<mapping-file>META-INF/JBPMorm.xml</mapping-file>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<class>org.jbpm.persistence.correlation.CorrelationKeyInfo</class>
<class>org.jbpm.persistence.correlation.CorrelationPropertyInfo</class>
<class>org.jbpm.runtime.manager.impl.jpa.ContextMappingInfo</class>
<class>org.jbpm.process.audit.ProcessInstanceLog</class>
<class>org.jbpm.process.audit.NodeInstanceLog</class>
<class>org.jbpm.process.audit.VariableInstanceLog</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.BitronixJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
13.2.4. Storing Process Events in a JMS Queue
Synchronous storing of history logs and runtime data in one database may be undesirable due to performance reasons. In that case, you can use JMS logger to send data into a JMS queue instead of directly storing it into a database. You can also configure it to be transactional in order to avoid issues with inconsistent data (for example when the process engine transaction is reversed).
Example configuration of JMS queue:
ConnectionFactory factory = ...;
Queue queue = ...;
StatefulKnowledgeSession ksession = ...;
Map<String, Object> jmsProps = new HashMap<String, Object>();
jmsProps.put("jbpm.audit.jms.transacted", true);
jmsProps.put("jbpm.audit.jms.connection.factory", factory);
jmsProps.put("jbpm.audit.jms.queue", queue);
AbstractAuditLogger auditLogger = AuditLoggerFactory.newInstance(Type.JMS, session, jmsProps);
ksession.addProcessEventListener(auditLogger);
// invoke methods of your session here

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.