<dependency> <groupId>com.broadleafcommerce.microservices</groupId> <artifactId>broadleaf-common-audit</artifactId> </dependency>
since 2.1.4|2.2.0
This feature is still in Beta. Functionality and documentation are subject to change. Audit events will be more deeply integrated into the framework in future releases, but the functionality is available for review now - allowing the creation of custom audit events.
Audit Services
manages and stores audit events from across the system. This includes key domain mutations, as well as key application lifecycle events that benefit from a forensic history store.
In general, there are three types of audit events created and stored in the system:
Audit event without detail. This is an event that only contains header information regarding time, description, user, etc… This type of event is useful for simple application lifecycle demarcation without requiring extensive informational details.
Audit event with raw detail. This is similar to the event without detail, but includes a collection of detailed information that is unstructured and may be represented in whatever format the caller desires.
Audit event with structured field detail. This is similar to the event with raw detail, but the detail objects adhere to a structured format of before/after field values for a specific entity mutation.
See Advanced Audit for details on using the audit features. |
The audit client library must be available on the classpath to initiate audit events. Whether or not if using a Broadleaf starter-based project, the framework component override module in your project should include a maven dependency on the client library. A version should not be required and should be auto-resolved via the inherited common dependencies BOM.
<dependency> <groupId>com.broadleafcommerce.microservices</groupId> <artifactId>broadleaf-common-audit</artifactId> </dependency>
A shared filesystem must be available and visible to all applicable microservices. When running locally, this is defaulted to a directory under the java temp directory. In higher environments (such as Kubernetes), this should be a persistent volume with a ReadWriteMany
access mode. If not using the default temp directory locations (local dev), these Spring environment properties are available for specifying the location of the shared filesystem:
broadleaf.audit.processing.storage.filesystem.working-directory
broadleaf.audit.processing.storage.filesystem.completion-directory
broadleaf.audit.processing.storage.filesystem.ingestion-directory
The audit feature must be enabled. This can be done with a single property: broadleaf.basic.audit.group
set to true
.
AuditServices must be running as part of the stack. This is generally achieved by updating the Broadleaf starter manifest to include.
components: - name: audit routed: true domain: cloud: audit docker: audit local: localhost enabled: false ports: - port: 8489 targetPort: 8489 - debug: true port: 8089 targetPort: 8089
flexPackages: - name: supporting domain: cloud: supporting docker: supporting local: localhost enabled: false flexUnits: adminnav,adminuser,metadata,notification,sandbox,search,tenant,audit
You may choose a different flexpackage than the example, or configure a new granular flexpackage to contain the audit service. |
The following components are used to support the audit services:
ChangeAuditHandler
- responsible for catching MutationNotifyEvent
instances for Trackable entity changes and converting to AuditEvent
instances via registered converters.
KeyEventAuditHandler
- responsible for catching AuditRequestEvent
instances (generally created via AuditEventUtility
) and converting to AuditEvent
instances.
AuditEventRecorder
- responsible for catching AuditEvent
instances as an async operation and storing as batches via a registered StorageProvider
(FileSystemStorageProvider
by default).
IngestionProcessor
- responsible for reading batches of AuditEvent
instances from the StorageProvider
(FileSystemIngestionProcessor
by default) and storing in the database via AuditHeaderRepository
.
DefaultAuditPruneService
- responsible for pruning the database of old audit events based on a configurable retention period.
Trackable JPA domain represents a basic concept in Broadleaf that covers admin maintenance and sandboxing. As part of this architecture, at a field-level, the system is aware of what changed, including before/after values. During Trackable maintenance, the system can be configured to audit these field-level changes.
To audit Trackable domain changes, the following steps are required:
A converter is needed to change a MutationNotifyEvent
coming from the Tracking architecture into an AuditEvent
.
class TestConverter extends DefaultAbstractMutationNotifyEventConverter { public TestConverter(TypeFactory factory) { super(factory); } @Override protected boolean isValid(MutationNotifyEvent source, Trackable changed) { // You should qualify the type of entity you want to audit return super.isValid(source, changed) && changed instanceof JpaTestItem; } @Override protected boolean isValid(MutationNotifyEvent source, ChangeDetail detail) { // You have the option to filter out specific fields from being audited (i.e. ChangeDetail) return super.isValid(source, detail); } }
The converter should be registered as a Spring bean.
@Bean public Converter<MutationNotifyEvent, AuditEvent> testConverter(TypeFactory factory) { return new TestConverter(factory); }
By default, DefaultAbstractMutationNotifyEventConverter qualifies validity based on the status of the change - specifically checking if the change is to the production level of the entity. This avoids tracking sandbox level changes. |
Audit events may also apply to key application lifecycle events. These need not be tied to entity mutation like the structured events described above. Support for this type of arbitrary event may be inserted programmatically at any spot having access to the audit client library API.
To audit lifecycle events, the following steps are required:
Use the AuditEventUtility
to construct an AuditEvent
and fire the event.
AuditEvent start = AuditEvent.builder().header(AuditEventHeader.builder() .eventType("TEST") .timestamp(Instant.now()) .tenantId("test") .detailType(DetailType.RAW.name()) .build()) .details(List.of(RawAuditEventDetail.builder() .author("admin") .rawDetail("A test") .timestamp(Instant.now()) .build())) .build(); AuditEventUtility.fire(start);
A usage variation can exclude the detail if not needed.
AuditEvent start = AuditEvent.builder().header(AuditEventHeader.builder() .eventType("TEST") .timestamp(Instant.now()) .tenantId("test") .detailType(DetailType.NONE.name()) .build()) .details(Collections.emptyList()) .build(); AuditEventUtility.fire(start);
Refer to the javadocs for AuditEventHeader and RawAuditEventDetail for more information on the fields available for use.
|
When using the default FileSystemStorageProvider
, a shared filesystem must be available and visible to all applicable microservices. When running locally, this is defaulted to a directory under the java temp directory. In higher environments (such as Kubernetes), this should be a persistent volume with a ReadWriteMany
access mode. If not using the default temp directory locations (local dev), these Spring environment properties are available for specifying the location of the shared filesystem:
broadleaf.audit.processing.storage.filesystem.working-directory
broadleaf.audit.processing.storage.filesystem.completion-directory
broadleaf.audit.processing.storage.filesystem.ingestion-directory
At the time of writing, there is only limited support for reviewing audit information in the admin tool. For example, there is currently no centralized view for viewing all audits. However, in the admin metadata for Trackable grids, the optional .auditable('ENTITY_TYPE')
may be included in the setup to cause audit information to be included in views for that entity type. The ENTITY_TYPE should be replaced with the actual entity type, which should match the AuditEventHeader#entityType
value.