@kiwiglen As has been said by @PickleRick , there is no recursion here, so this example handles up to 5 levels of subtask. | makeresults format=csv data="USER,JOBNAME,TRAN,TRANNUM,PHAPPLID,PHTRAN,PHTRANNO,USRCPUT_MICROSEC
,APP3,CSMI,43856,APP7,QZ81,70322,72
,APP5,CSMI,20634,APP7,QZ81,70322,8860
,APP7,QZ81,70322,APP3,QZ81,43836,16043
GPDCFC26,APP3,QZ81,43836, , ,0,897
,APP3,CSMI,41839,APP5,QZ61,15551,51
,APP3,CSMI,41838,APP5,QZ61,15551,64
,APP3,CSMI,41837,APP5,QZ61,15551,79
,APP5,QZ61,15551,APP3,QZ61,41835,5232
GOTLIS12,APP3,QZ61,41835, , ,0,778
,APP5,QZ61,12,APP3,QZ61,1,5232
GOTLIS12,APP3,QZ61,1, , ,0,778
,APP5,CSMI,111,APP7,QZ81,110,8860
,APP7,QZ81,110,APP3,QZ81,100,16043
ABCDEF,APP3,QZ81,100, , ,0,897"
| fields USER,JOBNAME,TRAN,TRANNUM,PHAPPLID,PHTRAN,PHTRANNO,USRCPUT_MICROSEC
``` Now initialise level 0 numbers ```
| eval level=if(PHTRANNO=0, 0, null()), root_trannum=if(PHTRANNO=0, TRANNUM, null())
``` This logic handles 5 levels of "recursion" - as discussed earlier, it's not true recursion as you have to specify the operations for the max level count you need.
The logic works by cascading the USER and root TRANNUM down the events for the related subtasks. It performs the following actions
- Create a parent id field containing TRANNUM, root TRANNUM USER and level for the specific level wanted - in this case level 0 is PHTRANNO=0 in the IF test
- Collect all the values of those ids across all events
- Find the PHTRANNO value of the event in the list of parents
- Extract the user and root TRANNUM from the result if found
```
``` Get level 1 ids ```
| eval parent_id=if(PHTRANNO=0, TRANNUM.":".root_trannum.":".USER.":".1, null())
| eventstats values(parent_id) as parents
| eval data=split(mvindex(parents, mvfind(parents, "^".PHTRANNO.":")), ":")
| eval root_trannum=if(isnotnull(data), mvindex(data, 1), root_trannum), root_user=if(isnotnull(data), mvindex(data, 2), root_user), level=if(isnotnull(data), mvindex(data, 3), level), USER=coalesce(USER, root_user)
``` Get level 2 ids ```
| eval parent_id=if(level=1, TRANNUM.":".root_trannum.":".USER.":".2, null())
| eventstats values(parent_id) as parents
| eval data=split(mvindex(parents, mvfind(parents, "^".PHTRANNO.":")), ":")
| eval root_trannum=if(isnotnull(data), mvindex(data, 1), root_trannum), root_user=if(isnotnull(data), mvindex(data, 2), root_user), level=if(isnotnull(data), mvindex(data, 3), level), USER=coalesce(USER, root_user)
``` Get level 3 ids ```
| eval parent_id=if(level=2, TRANNUM.":".root_trannum.":".USER.":".3, null())
| eventstats values(parent_id) as parents
| eval data=split(mvindex(parents, mvfind(parents, "^".PHTRANNO.":")), ":")
| eval root_trannum=if(isnotnull(data), mvindex(data, 1), root_trannum), root_user=if(isnotnull(data), mvindex(data, 2), root_user), level=if(isnotnull(data), mvindex(data, 3), level), USER=coalesce(USER, root_user)
``` Get level 4 ids ```
| eval parent_id=if(level=3, TRANNUM.":".root_trannum.":".USER.":".4, null())
| eventstats values(parent_id) as parents
| eval data=split(mvindex(parents, mvfind(parents, "^".PHTRANNO.":")), ":")
| eval root_trannum=if(isnotnull(data), mvindex(data, 1), root_trannum), root_user=if(isnotnull(data), mvindex(data, 2), root_user), level=if(isnotnull(data), mvindex(data, 3), level), USER=coalesce(USER, root_user)
``` Get level 5 ids ```
| eval parent_id=if(level=4, TRANNUM.":".root_trannum.":".USER.":".5, null())
| eventstats values(parent_id) as parents
| eval data=split(mvindex(parents, mvfind(parents, "^".PHTRANNO.":")), ":")
| eval root_trannum=if(isnotnull(data), mvindex(data, 1), root_trannum), root_user=if(isnotnull(data), mvindex(data, 2), root_user), level=if(isnotnull(data), mvindex(data, 3), level), USER=coalesce(USER, root_user)
| fields - root_user parents parent_id data
``` This counts all occurrences of the PHTRAN and joins the USER field into the child events ```
| eventstats count(eval(PHTRANNO!=0)) as subTasks by USER root_trannum
``` Now count the executions of each USER and evaluate the timings ```
| stats count(eval(PHTRANNO=0)) as Executions sum(USRCPUT_MICROSEC) as tot_USRCPUT_MICROSEC avg(USRCPUT_MICROSEC) as avg_USRCPUT_MICROSEC sum(eval(if(PHTRANNO=0,subTasks, 0))) as subTasks by USER
``` And adjust the subtask count, as we treated the main task as a subtask and then calculate the average subtask count ```
| eval avg_subTasks=subTasks/Executions Hopefully the comments help explain what's going on - however, without knowing really what you want from averages and totals, you may need to tweak, however, this is an EXPENSIVE search - so if you're dealing with a large data set it may be slow. If you have questions about the implementation just ask. Note, as with Splunk things, there may be a way to improve this, but with no correlation information other than the TRANNUM, it's tricky.
... View more