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:
afterWorkflowStarted
afterWorkflowFinish
beforeWorkflowCanceled
afterWorkflowTaskCreated
afterWorkflowTaskEnded
afterWorkflowTaskReassigned
afterWorkflowTaskDelegated
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:
modelName
is the name of the workflow modelmodelId
is the uuid of the workflow modelworkflowInitator
is the user who initiated the workflowtaskActor
is the user who completed a task associated to a workflow nodeworkflowVariables
lists the global variables of the workflownodeVariables
lists the local variables i.e. the ones defined on the node associated to a taskaction
is the action (i.e. button) that has been clicked to complete a task.timeSinceWfStarted
is the time in milliseconds elapsed since the workflow started.timeSinceTaskStarted
is 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
afterWorkflowStarted
event{ "_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
afterWorkflowTaskCreated
event because the workflow creates the task associated to thewf.travelExpenses.create
node 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.department
andextended.workflowVariables.expensenature
variables 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
afterWorkflowTaskCreated
event because the workflow creates a task associated to theAccept/Reject
node 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
afterWorkflowFinish
event 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
.