Execution Log

The Execution Log extension provides an implementation of ExecutionSubscriber that persists Executions using either the JPA/EclipseLink or JDO/DataNucleus object store.

One use case is to combine with the Audit Trail extension. The Command Log module logs the action invocations or property edits that the end-user makes, while the audit trail logs the resultant changes in state to domain objects. The two logs are correlated using the interactionId of the owning interaction.

Sometimes the Command Log extension is also configured with or instead of this extension; see the notes below to compare and contrast.

Setup

Dependency Management

Add an entry for the Execution Log module’s own BOM:

pom.xml
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.causeway.extensions</groupId>
            <artifactId>causeway-extensions-executionlog</artifactId>
            <scope>import</scope>
            <type>pom</type>
            <version>2.0.0</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Dependencies / Imports

In the webapp module of your application, add the following dependency:

pom.xml
<dependencies>
    <dependency>
        <groupId>org.apache.causeway.extensions</groupId>
        <artifactId>causeway-extensions-executionlog-persistence-XXX</artifactId>    (1)
    </dependency>
</dependencies>
1 either:

In your application’s App Manifest, import the ExecutionLog modules. The exact modules to use will depend upon the persistence mechanism in use:

AppManifest.java
@Configuration
@Import({
        ...
        CausewayModuleExtExecutionLogPersistenceXxx.class,        (1)
        ...
})
public class AppManifest {
}
1 either:

If using SecMan, you will also need to import the Fixture module; SecMan uses fixture scripts to seed its entities.

Configuration Properties

Add the database schema used by the Execution Log entities to the configuration file:

application.yml
causeway:
  persistence:
    schema:
      auto-create-schemas: causewayExtExecutionLog

This extension currently does not though define any configuration properties of its own.

Once configured, the extension provides a number of menu actions. You can use menubars.layout.xml to arrange these as you see fit. To get you started, the following fragment adds all of the actions to an "Activity" secondary menu:

menubars.layout.xml
<mb:secondary>
    ...
    <mb:menu>
        <mb:named>Activity</mb:named>
        ...
        <mb:section>
            <mb:named>Execution Log</mb:named>
            <mb:serviceAction id="findMostRecent" objectType="causeway.ext.executionLog.ExecutionLogMenu"/>
            <mb:serviceAction id="findExecutions" objectType="causeway.ext.executionLog.ExecutionLogMenu"/>
            <mb:serviceAction id="findAll" objectType="causeway.ext.executionLog.ExecutionLogMenu"/>
        </mb:section>
        ...
    </mb:menu>
</mb:secondary>

SecMan Security Roles

If SecMan extension is configured, then permissions must be granted to access the menu actions.

This can be done by granting the role set up by the CausewayExtExecutionLogRoleAndPermissions seed fixture script (see its ROLE_NAME constant).

User Interface

The extension provides a number of menu actions and contributions.

The menu actions are as listed in menubar.layout.xml, above. They allow the administrator to query the persisted commands. Typically access to these actions would be restricted, see security roles above.

The extension also provides these mixins:

  • Object_recentExecutions

    This contributes a recentExecutions collection to each and every domain object.

    This can be explicit positioned through the domain class' own layout file, but this is generally not necessary: it will slot into the tab group in the layout file indicated for unreferenced collections using <tabGroup unreferencedCollections="true">.

  • HasUsername_recentExecutionsByUser

    This contributes the recentExecutionsByUser collection to any domain object that implements the HasUsername interface.

    Most notably, this is SecMan extension’s ApplicationUser entity that represents a logged-on user. It is also supported by xref:security:sessionlog:about.adoc

  • HasInteractionId_executionLogEntries

    This contributes the executionLogEntries property to any object implementing HasInteractionId interface. Typically these are the entities persisted by the Command Log or Audit Trail extensions, making it easy to traverse between these logs.

Notes

Conceptually a command represents the intention to execute an action or to edit a property ("before" the change), while an interaction execution represents the actual execution itself ("after" the change).

The CommandSubscriber SPI and ExecutionSubscriber SPI allow either to be subscribed to. From an auditing perspective, their behaviour is quite similar:

  • even though a command represents the intention to invoke an action, its CommandSubscriber SPI is only called once the action/property edit has been completed.

  • the ExecutionSubscriber is called as soon as the action has completed. In most interactions there will only be a single action called within the interaction, hence these two subscribers will be called at almost the same time with very similar payloads.

However, there can be some subtle differences:

  • the WrapperFactory service allows actions to be invoked "as if" through the user interface. Therefore one action can execute another can execute another, creating a nested call graph of executions.

    The ExecutionSubscriber is called after each and every execution as it completes, so will be called several times.

  • In contrast, the CommandSubscriber is called only once, for the top-level (outermost) action.