You can generally do this type of logic directly in the stats through eval statements and in eval categorisation in the logic prior to the stats for clarity, so to expand on the 'type' logic I used in the earlier example, something like this | eval type=case(match(message,"created"),1,
match(message,"disconnected"),2,
match(message,"other_message"),3)
| stats count(eval(if(type<3,_time,null()))) as connection_count
count(eval(if(type=3,_time,null()))) as message_count
values(type) as types
min(eval(if(type<3,_time,null()))) as first_event_time
range(eval(if(type<3,_time,null()))) as duration
by userId, traceId
| addinfo
``` Handle created but no disconnect ```
| eval duration=if(duration=0 AND connection_count=1 AND types=1, info_max_time - first_event_time, duration)
``` Handle disconnect but no created ```
| eval duration=if(duration=0 AND connection_count=1 AND types=2, first_event_time - info_min_time, duration)
| stats values(message_count) as message_count sum(duration) as duration by userId so the type is 1-3 depending on text you want to match and then the count eval statements in the stats count the event types and the time calculations exclude the type=3 This is untested, but hopefully you get the picture. There are probably some optimisations there, but it should do what you need
... View more