Documentation Home

Admin Workflow Audit Logging

What Gets Logged

Broadleaf can provide detailed production logging for complex interactions during admin workflow processes. When enabled, data relating to the creation, modification, or deletion of entities will be recorded. These logs are useful for recreating complex user scenarios, replicating error conditions, and diagnosing otherwise inscrutable bugs.

How Broadleaf Configures the Logging by Default

Logging Workflow Process Details

Out-of-the-box, the ProcessDetailLogger is responsible for logging workflow audit data. This is generally outputted to a rolling log file. Since Broadleaf uses Logback out-of-the-box, a sample Logback configuration for a daily rolling log is provided in the Broadleaf demo project, which can be found in the core logback-spring.xml. This sample is provided below:

<!-- Enable this appender and logger for workflow log functionality. This is highly recommended for production. -->
<property name="WORKFLOW_LOG_FILE" value="${WORKFLOW_LOG_FILE:-${java.io.tmpdir:-/tmp}/blc-logs/workflow.log}"/>
<appender name="rollingDailyEnterpriseWorkflow" class="ch.qos.logback.core.rolling.RollingFileAppender">
   <file>${WORKFLOW_LOG_FILE}</file>
   <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <!-- daily rollover -->
       <fileNamePattern>${WORKFLOW_LOG_FILE}.%d{yyyy-MM-dd-HH-mm}.log</fileNamePattern>
       <maxHistory>30</maxHistory>
   </rollingPolicy>

   <encoder>
       <pattern>[%-5level] %d{MM-dd-yyyy HH:mm:ss} %logger{35} - %message%n</pattern>
   </encoder>
</appender>

<logger name="com.broadleafcommerce.enterprise.workflow.process.detail" level="DEBUG">
   <appender-ref ref="rollingDailyEnterpriseWorkflow"/>
</logger>

Note: See Logback's Pattern Documentation for information on what the encoder pattern [%-5level] %d{MM-dd-yyyy HH:mm:ss} %logger{35} - %message%n means and other ways to configure this pattern to suit your needs.

The Enterprise module augments this logging further in EnterpriseWorkflowLogger with details on whether the log is part of a production deployment and which admin user initiated the request that generated the log.

The default ProcessDetailLogger can be configured with the following properties:

  • ignore.no.process.detail.logger.configuration: Determines whether to display a support message when the ProcessDetailLogger is used but not configured by a backing logging system; default is false
  • disable.all.process.detail.logging: Determines whether ProcessDetailLogger will attempt to log anything. The ProcessDetailLogger functionality can be completely turned off with this; default is false

And the Enterprise version with these additional properties:

  • enterprise.workflow.logger.enabled: Determines whether enterprise workflow logging is enabled; default is true
  • enterprise.workflow.logger.non.production.enabled: Determines whether enterprise workflow logging is enabled for both production and non-production operations; default is true

Aggregating Workflow Logs for Reports

In addition to creating workflow logs, the AuditLogFileProvider can be implemented and given a list of dates to aggregate information from multiple log files into a single file. The data will be arranged in chronological order. The provider is also responsible for parsing individual lines from a log file in order to derive timestamp and text information.

Broadleaf provides a DefaultLogFileProvider that will look for files defined by the logback configuration provided above. However, this assumes that

  1. The current log file exists in the filesystem as workflow.log and
  2. The previous days' log files exist in the filesystem as workflow.log.yyyy-MM-dd
  3. A separate log is available on every node. Therefore, it sends out a global event for all admin nodes.

Several properties can be used to configure the DefaultLogFileProvider:

  • enterprise.audit.log.directory: The directory in the filesystem that contains the workflow logs; default is ${java.io.tmpdir:-/tmp}/blc-logs
  • enterprise.audit.log.line.detection.regex: The regex pattern used to match a line in the log file that contains the timestamp information; default is ^\[DEBUG\] (\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d).*}
  • enterprise.audit.log.line.date.format.pattern: The pattern used to parse the log line timestamp; default is MM-dd-yyyy HH:mm:ss
  • enterprise.audit.log.file.date.format.pattern: The pattern used to parse the date from the log file name; default is yyyy-MM-dd

If a project diverges from this basic setup, a custom implementation of AuditLogFileProvider can be introduced via Spring using the blAuditLogFileProvider bean id. The custom implementation will handle log file retrieval and can be coded to your custom specifications.

Note: The Workflow Audit section of the admin uses whatever log provider matches the bean id blAuditLogFileProvider when compiling requested logs.

Things to Consider when Configuring Logging without an External Output File

The ProcessDetailLogger does not require a rolling log file persisted on the filesystem. It only expects a logger named com.broadleafcommerce.enterprise.workflow.process.detail. You can associate any appender appropriate for your project instead of the RollingFileAppender. However, keep in mind that you will have to implement your own AuditLogFileProvider in order to view workflow logs in the Workflow Audit section of the Admin. Otherwise, the requested logs will show "No log files found".

AuditLogFileProvider requires 2 methods to be implemented:

  1. AuditLogContainer[] getLogFileInputStream(List<Date> dates): for retrieving log information for the relevant log container based on the dates provided
  2. void buildLine(BufferedReader file, AuditLogLine logLine) throws LineParseException: for aggregating multiple logs into one; builds data around a line from a log

After implementing the custom log file provider, the bean should be registered with an ID of blAuditLogFileProvider. getLogFileInputStream() does not necessitate that log files exist on the filesystem. You can implement this to read logs from a whatever log-store you use. However, keep in mind that the expected output is an array of AuditLogContainers, which has the following fields:

  • dates:Date[]
  • logInputStream:InputStream
  • fileLength:long
  • fileName:String

While the last 2 fields have "file" in their names, they don't have to be related to files, just the input stream.

Viewing Workflow Audit Reports and Logs in the Admin

Workflow Audit Admin Section

In the admin UI provided by Broadleaf, you can access workflow audit reports and, if configured, aggregated workflow logs by going to the Workflow module (a.k.a. Site Updates) -> Workflow Audit section:

Navigating to the Workflow Audit Section

Workflow Actions Table

At the top of this section is a table including every workflow change processed: Creating, updating, and archiving of entities. It relates the change type, name of the affected entity, the operation originating the change, author, and timestamp of when the change was made.

From the first table you can select a change and view the WorkflowSandBoxItem details for it. This includes:

  • More details like those shown in the table relating to the change type, author, timestamp, and such data as is useful for recreating complex user scenarios, replicating error conditions, and diagnosing otherwise inscrutable bugs
  • Related events, deployments, attributes, and errors
  • Which fields were changed with the original and new values

Workflow Action Lineage Tab

Moreover, after you select a single change, another tab becomes available on the table that shows the workflow action lineage of that change. For example, if you change the name of a Product, save, promote, and approve the change, the "workflow action lineage" tab will contain a record for each of those changes. This enables you to, for instance, see who made the original change and who reviewed and approved it later.

Button and Tab Enabled after Selecting a Workflow Change

Requesting Reports and Logs

Now, you can select all the related changes and produce an aggregated report based on either the workflow logs (using the "Request Log" button) or, if workflow logging is not enabled, WorkflowSandBoxItem data from the DB (using the "Request Report" button). The "Request Log" button produces a file with the raw data from the logs and the "Request Report" button produces an easier-to-read report.

Sample Log snippet:

[DEBUG] 08-21-2017 17:59:17 c.b.e.w.p.detail - -1600 SandBox(Default[2]):User(Administrator[-1]) Cloning bean for sandbox edit (org.broadleafcommerce.core.catalog.domain.ProductImpl)
[DEBUG] 08-21-2017 17:59:17 c.b.e.w.p.detail - -1600 SandBox(Default[2]):User(Administrator[-1]) Cloning bean for sandbox edit (org.broadleafcommerce.core.catalog.domain.SkuImpl)
[DEBUG] 08-21-2017 17:59:17 c.b.e.w.p.detail - -1000 SandBox(Default[2]):User(Administrator[-1]) Adding clone library member (10150,1,2,org.broadleafcommerce.core.catalog.domain.ProductImpl,null)
[DEBUG] 08-21-2017 17:59:17 c.b.e.w.p.detail - -1000 SandBox(Default[2]):User(Administrator[-1]) Adding clone library member (10150,1,2,org.broadleafcommerce.core.catalog.domain.SkuImpl,null)
[DEBUG] 08-21-2017 17:59:17 c.b.e.w.p.detail - -1000 SandBox(Default[2]):User(Administrator[-1]) Change requested on object, cloned the object (org.broadleafcommerce.core.catalog.domain.ProductImpl:10150)
...

Sample Report:

REPORT 

---- 
---- Container Item ID:1 || Name:Home
---- 
Details 
     Name: Home
     Id: 1
     Description : org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Group Description: Category (Category:2001)
     Sandbox Id : 2
     Original Item Id : null
     Version : 1
     Container Id : null
     Sandbox Operation Type : Update
     Original Workflow Sandbox Item Id : null
     Operation Origin : User
     Has Error(s): false
     Scheduled Deployment Date : null
     Promotion Message: null
     Rejection Message: null
     Process Marker : null
     Original Sandbox Id: null
     Creation Sandbox Id : 2
     Deny Propigation Flag: false
     Inherited Version : null
     Date Created : 2017-08-21 17:00:08.0
     Date Updated : 2017-08-21 17:00:11.0
Events 
     No Events
Deployments 
     No Deployments
Child Items 
     Sandbox Item Id: 2
     Sandbox Item Name: Home
     Sandbox Item Description : org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Sandbox Item Group Description: Category (Category:2001)
     Sandbox Id : 2
     Sandbox Original Item Id : 2001
     Version : 1
     Sandbox Item Container Id : 1
     Sandbox Operation Type : Update
     Sandbox Item Original Workflow Sandbox Item Id : null
     Sandbox Item Process Marker : null
     Original Sandbox Id: null
     Creation Sandbox Id : 2
     Deny Propigation Flag: false
     Inherited Version : null
     Fully Qualified Entity Ceiling Name: org.broadleafcommerce.core.catalog.domain.Category
     Entity LinkedItem Id: NA
     Entity Target Item Id : 2001
     Requesting Entity Name: Home
     Entity Change Type: UPDATE
     Entity Type: org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Entity Field Name : id
         Original Value : null
         Original Display Value : null
         New Concise Value : 2001
         Is Dirty : false
         Disabled By Property : null
         Is Override : false
         Secondary Type : null
     Entity Field Name : longDescription
         Original Value : null
         Original Display Value : null
         New Concise Value : asdf
         Is Dirty : true
         Disabled By Property : null
         Is Override : false
         Secondary Type : null
     Domain Change Lineage
         Primary Entity : org.broadleafcommerce.core.catalog.domain.CategoryImpl
         CATEGORY_ID,ACTIVE_END_DATE,ACTIVE_START_DATE,ADMIN_ADDITION_STATUS,ARCHIVED,CREATED_BY,DATE_CREATED,DATE_UPDATED,DEFAULT_PARENT_CATEGORY_ID,DESCRIPTION,DISPLAY_TEMPLATE,EXTERNAL_ID,FULFILLMENT_TYPE,INVENTORY_TYPE,LONG_DESCRIPTION,META_DESC,META_TITLE,NAME,OVERRIDE_GENERATED_URL,PRODUCT_DESC_PATTERN_OVERRIDE,PRODUCT_TITLE_PATTERN_OVERRIDE,ROOT_DISPLAY_ORDER,SNDBX_ARCHIVED_FLAG,SNDBX_CATALOG_FLAG,SNDBX_DELETED_FLAG,SNDBX_ID,SNDBX_ORIG_ITEM_ID,SNDBX_ORIG_RECORD_ID,SNDBX_TIER,SNDBX_TMPLT_RECORD_ID,TAX_CODE,THEME_FILE_ID,UPDATED_BY,URL,URL_KEY
         2001,,2017-08-21 16:55:00.0,CONFIRMED,N,,,2017-08-21 17:00:24.0,,Home,layout/homepage,,,,asdf,,,Home,false,,,-5.000000,,,,,,,,,,,-1,/,
---- 
---- Container Item ID:3 || Name:Home
---- 
Details 
     Name: Home
     Id: 3
     Description : org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Group Description: Category (Category:2001)
     Sandbox Id : 1
     Original Item Id : null
     Version : 2
     Container Id : null
     Sandbox Operation Type : Update
     Original Workflow Sandbox Item Id : null
     Operation Origin : Promote
     Has Error(s): false
     Scheduled Deployment Date : 2017-08-21 17:00:13.0
     Promotion Message: 
     Rejection Message: null
     Process Marker : null
     Original Sandbox Id: 2
     Creation Sandbox Id : 2
     Deny Propigation Flag: false
     Inherited Version : null
     Date Created : 2017-08-21 17:00:11.0
     Date Updated : 2017-08-21 17:00:24.0
Events 
     Event Id : 1
     Event Name : Category  Modified
     Event Archived : true
     Event Has Errors : false
     Event Sandbox Id : 1
     Event Action Type : Approve
     Event Scheduled Date : 2017-08-21 17:00:13.0
Deployments 
     Deployment Id : 1
     Deployment Job Id : null
     Deployment Status : Completed
     Deployment Date : 2017-08-21 17:00:13.0
Child Items 
     Sandbox Item Id: 4
     Sandbox Item Name: Home
     Sandbox Item Description : org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Sandbox Item Group Description: Category (Category:2001)
     Sandbox Id : 1
     Sandbox Original Item Id : 2001
     Version : 2
     Sandbox Item Container Id : 3
     Sandbox Operation Type : Update
     Sandbox Item Original Workflow Sandbox Item Id : 2
     Sandbox Item Process Marker : 1
     Original Sandbox Id: 2
     Creation Sandbox Id : 2
     Deny Propigation Flag: false
     Inherited Version : null
     Fully Qualified Entity Ceiling Name: org.broadleafcommerce.core.catalog.domain.Category
     Entity LinkedItem Id: NA
     Entity Target Item Id : 2001
     Requesting Entity Name: Home
     Entity Change Type: UPDATE
     Entity Type: org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Entity Field Name : id
         Original Value : null
         Original Display Value : null
         New Concise Value : 2001
         Is Dirty : true
         Disabled By Property : null
         Is Override : false
         Secondary Type : null
     Entity Field Name : longDescription
         Original Value : null
         Original Display Value : null
         New Concise Value : asdf
         Is Dirty : true
         Disabled By Property : null
         Is Override : false
         Secondary Type : null
     Domain Change Lineage
         Primary Entity : org.broadleafcommerce.core.catalog.domain.CategoryImpl
         CATEGORY_ID,ACTIVE_END_DATE,ACTIVE_START_DATE,ADMIN_ADDITION_STATUS,ARCHIVED,CREATED_BY,DATE_CREATED,DATE_UPDATED,DEFAULT_PARENT_CATEGORY_ID,DESCRIPTION,DISPLAY_TEMPLATE,EXTERNAL_ID,FULFILLMENT_TYPE,INVENTORY_TYPE,LONG_DESCRIPTION,META_DESC,META_TITLE,NAME,OVERRIDE_GENERATED_URL,PRODUCT_DESC_PATTERN_OVERRIDE,PRODUCT_TITLE_PATTERN_OVERRIDE,ROOT_DISPLAY_ORDER,SNDBX_ARCHIVED_FLAG,SNDBX_CATALOG_FLAG,SNDBX_DELETED_FLAG,SNDBX_ID,SNDBX_ORIG_ITEM_ID,SNDBX_ORIG_RECORD_ID,SNDBX_TIER,SNDBX_TMPLT_RECORD_ID,TAX_CODE,THEME_FILE_ID,UPDATED_BY,URL,URL_KEY
         2001,,2017-08-21 16:55:00.0,CONFIRMED,N,,,2017-08-21 17:00:24.0,,Home,layout/homepage,,,,asdf,,,Home,false,,,-5.000000,,,,,,,,,,,-1,/,
---- 
---- Container Item ID:5 || Name:Home
---- 
Details 
     Name: Home
     Id: 5
     Description : org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Group Description: Category (Category:2001)
     Sandbox Id : null
     Original Item Id : null
     Version : null
     Container Id : null
     Sandbox Operation Type : Update
     Original Workflow Sandbox Item Id : null
     Operation Origin : Promote
     Has Error(s): null
     Scheduled Deployment Date : null
     Promotion Message: 
     Rejection Message: null
     Process Marker : null
     Original Sandbox Id: 1
     Creation Sandbox Id : 2
     Deny Propigation Flag: false
     Inherited Version : null
     Date Created : 2017-08-21 17:00:24.0
     Date Updated : 2017-08-21 17:00:24.0
Events 
     No Events
Deployments 
     No Deployments
Child Items 
     Sandbox Item Id: 6
     Sandbox Item Name: Home
     Sandbox Item Description : org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Sandbox Item Group Description: Category (Category:2001)
     Sandbox Id : null
     Sandbox Original Item Id : 2001
     Version : null
     Sandbox Item Container Id : 5
     Sandbox Operation Type : Update
     Sandbox Item Original Workflow Sandbox Item Id : 4
     Sandbox Item Process Marker : null
     Original Sandbox Id: 1
     Creation Sandbox Id : 2
     Deny Propigation Flag: false
     Inherited Version : null
     Fully Qualified Entity Ceiling Name: org.broadleafcommerce.core.catalog.domain.Category
     Entity LinkedItem Id: NA
     Entity Target Item Id : 2001
     Requesting Entity Name: Home
     Entity Change Type: UPDATE
     Entity Type: org.broadleafcommerce.core.catalog.domain.CategoryImpl
     Entity Field Name : id
         Original Value : null
         Original Display Value : null
         New Concise Value : 2001
         Is Dirty : true
         Disabled By Property : null
         Is Override : false
         Secondary Type : null
     Entity Field Name : longDescription
         Original Value : null
         Original Display Value : null
         New Concise Value : asdf
         Is Dirty : true
         Disabled By Property : null
         Is Override : false
         Secondary Type : null
     Domain Change Lineage
         Primary Entity : org.broadleafcommerce.core.catalog.domain.CategoryImpl
         CATEGORY_ID,ACTIVE_END_DATE,ACTIVE_START_DATE,ADMIN_ADDITION_STATUS,ARCHIVED,CREATED_BY,DATE_CREATED,DATE_UPDATED,DEFAULT_PARENT_CATEGORY_ID,DESCRIPTION,DISPLAY_TEMPLATE,EXTERNAL_ID,FULFILLMENT_TYPE,INVENTORY_TYPE,LONG_DESCRIPTION,META_DESC,META_TITLE,NAME,OVERRIDE_GENERATED_URL,PRODUCT_DESC_PATTERN_OVERRIDE,PRODUCT_TITLE_PATTERN_OVERRIDE,ROOT_DISPLAY_ORDER,SNDBX_ARCHIVED_FLAG,SNDBX_CATALOG_FLAG,SNDBX_DELETED_FLAG,SNDBX_ID,SNDBX_ORIG_ITEM_ID,SNDBX_ORIG_RECORD_ID,SNDBX_TIER,SNDBX_TMPLT_RECORD_ID,TAX_CODE,THEME_FILE_ID,UPDATED_BY,URL,URL_KEY
         2001,,2017-08-21 16:55:00.0,CONFIRMED,N,,,2017-08-21 17:00:24.0,,Home,layout/homepage,,,,asdf,,,Home,false,,,-5.000000,,,,,,,,,,,-1,/,

Detected Classpath Libraries 
     Unable to determine the framework libraries

Requested logs can be viewed from the "Workflow Report Requests" table at the bottom of the Workflow Audit page using the "Download Report" button. They also be deleted from that table with the "Delete Report" button.

Workflow Report Requests table

Workflow Action Details Table

There is also a "Workflow Action Details" table that shows all the selected changes whereas the first table ("Workflow Actions") displays all changes. This table includes an additional button, "View Domain Details", that allows you to view the domain details of the entity changed rather than for its related WorkflowSandBoxItem as the "View Details" button does.

Workflow Action Details Table

The AdminWorkflowAuditController is the default handler for this page and the AuditReportService handles the generation and retrieval of reports and logs.

Note: The AuditReportService retrieves workflow logs across all the active admin nodes in the cluster.

Further Reading

Please refer to Workflow Sandbox Details for more information on the Enterprise workflow and approvals process.