The page details the information logged in the audit during a workflow completion.
What Is Logged in the Audit
Since 7.4, a new audit category called Routing has been added for the following workflow events:
afterWorkflowStartedafterWorkflowFinishbeforeWorkflowCanceledafterWorkflowTaskCreatedafterWorkflowTaskEndedafterWorkflowTaskReassignedafterWorkflowTaskDelegated
For all these events, we log useful information regarding the workflow and/or node state in the extended info of the audit entry. The table below summarizes which extended info is logged depending on the event.
| modelName | modelId | workflowInitator | taskActor | workflowVariables | nodeVariables | action | timeSinceWfStarted | timeSinceTaskStarted | |
|---|---|---|---|---|---|---|---|---|---|
| afterWorkflow Finish | x | x | x | x | x | ||||
| afterWorkflow Started | x | x | x | x | x | ||||
| beforeWorkflow Canceled | x | x | x | x | x | ||||
| afterWorkflow TaskCreated | x | x | x | x | x | ||||
| afterWorkflow TaskEnded | x | x | x | x | x | x | x | x | |
| afterWorkflow TaskReassigned | x | x | x | x | x | x | x | ||
| afterWorkflow TaskDelegated | x | x | x | x | x | x | x |
Where:
modelNameis the name of the workflow modelmodelIdis the uuid of the workflow modelworkflowInitatoris the user who initiated the workflowtaskActoris the user who completed a task associated to a workflow nodeworkflowVariableslists the global variables of the workflownodeVariableslists the local variables i.e. the ones defined on the node associated to a taskactionis the action (i.e. button) that has been clicked to complete a task.timeSinceWfStartedis the time in milliseconds elapsed since the workflow started.timeSinceTaskStartedis the time in milliseconds elapsed since the task started.
Note that since Nuxeo 7.3, the audit is stored by default as an Elasticsearch index which offers the possibility to store the extended info as plain JSON objects. The workflowVariables and nodeVariables are indeed maps of primitive types and therefore are stored in their current forms except for blob variables which are omitted.
The Travel Expenses Example
Let's consider the travel expenses addon's workflow which allows a user to submit a travel expense to be validated by a manager or a supervisor.
In the first step of the workflow called wf.travelExpenses.create, a user completes a task with the nature of the expense, the amount and the department he works in. Then a manager can accept the request, which will be passed on to the accountancy department, or reject it.
In order to have an overview of what is logged in the audit, we can use the Elasticsearch Passthrough to query the new entries added to the audit index as we are completing the above workflow. For instance the following request
curl -XGET -u jdoe:jdoe 'http://localhost:8080/nuxeo/site/es/audit_wf/_search' -d '{ "query": { "match_all":{}}}'
will return all Routing audit entries associated to the workflow models on which the current user has the Data Visualization permission. This Data Visualization permission can be added from the Admin > Workflow menu.
Let's have a look to returned entries. First the workflow is started by a user, there are two new entries in the audit:
One for the
afterWorkflowStartedevent{ "_id": "10267", "_index": "audit", "_score": null, "_source": { "category": "Routing", "comment": null, "docLifeCycle": "running", "docPath": "/document-route-instances-root/2015/09/28/TravelExpenseValidation", "docType": "DocumentRoute", "docUUID": "e2777d7e-5fac-4264-94be-818a13ea13dd", "entity-type": "logEntry", "eventDate": "2015-09-28T15:01:21.786+02:00", "eventId": "afterWorkflowStarted", "extended": { "modelId": "5e7980bc-12f1-4b5f-a7df-149af96bc899", "modelName": "TravelExpenseValidation", "workflowInitiator": "jdoe", "workflowVariables": { "amount": null, "department": "it", "description": null, "destination": null, "expensenature": "transportation", "file": null, "label": null, "user": null } }, "id": 10267, "logDate": "2015-09-28T15:01:22.395+02:00", "principalName": "Administrator", "repositoryId": "default" }, "_type": "entry", "_version": 1, "sort": [ 1443445281786 ] }Another one for the
afterWorkflowTaskCreatedevent because the workflow creates the task associated to thewf.travelExpenses.createnode right after it started.{ "_id": "10266", "_index": "audit", "_score": null, "_source": { "category": "Routing", "comment": null, "docLifeCycle": "opened", "docPath": "/task-root/Task4fb", "docType": "RoutingTask", "docUUID": "587464f7-daba-4c07-9b43-9f04f201d421", "entity-type": "logEntry", "eventDate": "2015-09-28T15:01:21.771+02:00", "eventId": "afterWorkflowTaskCreated", "extended": { "actors": [ "jdoe" ], "modelId": "5e7980bc-12f1-4b5f-a7df-149af96bc899", "modelName": "TravelExpenseValidation", "nodeVariables": {}, "taskName": "wf.travelExpenses.create", "workflowInitiator": "Administrator", "workflowVariables": { "amount": null, "department": "it", "description": null, "destination": null, "expensenature": "transportation", "file": null, "label": null, "user": null } }, "id": 10266, "logDate": "2015-09-28T15:01:22.331+02:00", "principalName": "Administrator", "repositoryId": "default" }, "_type": "entry", "_version": 1, "sort": [ 1443445281771 ] }In the above snippet, you can see that the
extended.workflowVariables.departmentandextended.workflowVariables.expensenaturevariables have default values defined by the workflow model.
Then the user completes the task associated to the wf.travelExpenses.create node which creates two new entries:
One for
afterWorkflowTaskEnded{ "_id": "10271", "_index": "audit", "_score": null, "_source": { "category": "Routing", "comment": null, "docLifeCycle": "ended", "docPath": "/task-root/Task4fb", "docType": "RoutingTask", "docUUID": "587464f7-daba-4c07-9b43-9f04f201d421", "entity-type": "logEntry", "eventDate": "2015-09-28T15:02:04.830+02:00", "eventId": "afterWorkflowTaskEnded", "extended": { "action": "submit", "modelName": "TravelExpenseValidation", "nodeVariables": {}, "taskActor": "jdoe", "taskName": "wf.travelExpenses.create", "timeSinceTaskStarted": 43052, "timeSinceWfStarted": 43044, "workflowInitiator": "jdoe", "workflowVariables": { "amount": 12, "department": "marketing", "description": "Morning breakfast", "destination": null, "expensenature": "lunch", "file": null, "label": "Breakfast", "user": null } }, "id": 10271, "logDate": "2015-09-28T15:02:05.097+02:00", "principalName": "Administrator", "repositoryId": "default" }, "_type": "entry", "_version": 1, "sort": [ 1443445324830 ] }At this stage, the extended info contains interesting data such as
timeSinceWfStarted,timeSinceTaskStarted,action(i.e. the button the user clicked to complete the task), etc.Another one for the
afterWorkflowTaskCreatedevent because the workflow creates a task associated to theAccept/Rejectnode right after:{ "_id": "10275", "_index": "audit", "_score": null, "_source": { "category": "Routing", "comment": null, "docLifeCycle": "opened", "docPath": "/task-root/Task12ef", "docType": "RoutingTask", "docUUID": "0a06570a-5e74-45a4-8a06-66989b543555", "entity-type": "logEntry", "eventDate": "2015-09-28T15:02:04.906+02:00", "eventId": "afterWorkflowTaskCreated", "extended": { "actors": [ "group:managers" ], "modelId": "5e7980bc-12f1-4b5f-a7df-149af96bc899", "modelName": "TravelExpenseValidation", "nodeVariables": {}, "taskName": "Accept/ Reject", "timeSinceWfStarted": 43120, "workflowInitiator": "jdoe", "workflowVariables": { "amount": 12, "department": "marketing", "description": "Morning breakfast", "destination": null, "expensenature": "lunch", "file": null, "label": "Breakfast", "user": null } }, "id": 10275, "logDate": "2015-09-28T15:02:05.160+02:00", "principalName": "Administrator", "repositoryId": "default" }, "_type": "entry", "_version": 1, "sort": [ 1443445324906 ] }
Eventually a manager will validate the request (associated audit entries will be persisted):
A final audit entry for the
afterWorkflowFinishevent is added{ "_id": "10289", "_index": "audit", "_score": null, "_source": { "category": "Routing", "comment": null, "docLifeCycle": "done", "docPath": "/document-route-instances-root/2015/09/28/TravelExpenseValidation", "docType": "DocumentRoute", "docUUID": "e2777d7e-5fac-4264-94be-818a13ea13dd", "entity-type": "logEntry", "eventDate": "2015-09-28T15:02:14.958+02:00", "eventId": "afterWorkflowFinish", "extended": { "modelId": "5e7980bc-12f1-4b5f-a7df-149af96bc899", "modelName": "TravelExpenseValidation", "timeSinceWfStarted": 53171, "workflowInitiator": "jdoe", "workflowVariables": { "amount": 12, "department": "marketing", "description": "Morning breakfast", "destination": null, "expensenature": "lunch", "file": null, "label": "Breakfast", "user": null } }, "id": 10289, "logDate": "2015-09-28T15:02:15.089+02:00", "principalName": "jdoe", "repositoryId": "default" }, "_type": "entry", "_version": 1, "sort": [ 1443445334958 ] }Along with final values of the workflow variables we can see the workflow duration
timeSinceWorkflowStarted.