0

I am trying to trigger an alert when an event does not occur within a time window after an event came. I know there are a lot of similar questions out there, but nothing seems to match what I am looking for.

Let's say I have a time window of 20 seconds and I want to be alerted when any of these two conditions are satisfied:

  1. When the rule is enabled(not just created), start a time window of 20 seconds, send an alert if the event did not occur in the first 20 seconds.
  2. An event occurred at 15th second, wait for a time window of 20 sec and send an alert if an event did not occur.
  3. An event occurred at 15th second and at 16th second, start a time window from 16th second and wait for the new event to occur. (Basically, start a time window from the latest event that happened)

I have tried a couple of things like:

from not employees[eid == 'E1234'] for 20 sec select eid, 'MissingEvent' as alert insert
into employees_alerts; 

from f1=employees[eid == 'E1234'] -> not employees[f1.eid == eid] for 20 sec select eid,
'MissingEvent' as alert insert into employees_alerts;

There are a couple of problem with this query:

  1. "for" syntax requires a siddhiAppRuntime to restart to work. Hence, when the rule is disable and enabled, the query doesnt work.
  2. This works only for the first time. eg. when my events are generated at these time intervals:
    a. emp_event1 at 21st sec
    b. emp_event2 at 25th sec after emp_event1
    c. emp_event3 at 5th sec after emp_event2

I get an alert at the first 20th second(before emp_event1, which is right) and an alert at 20 seconds after emp_event1(before emp_event2, which is right).

However, I dont get an alert 20 seconds after emp_event3(since no new matching event is sent in a 20 second time window after emp_event3 happened).

How can I change my query to alert this way?

I also tried this by following https://docs.wso2.com/display/CEP400/Sample+0111+-+Detecting+non-occurrences+with+Patterns and Siddhi check if an event does not arrive within a specified time window?

from employees[eid == 'E1234']#window.time(20 sec) 
select * insert expired events into expiredEventsStream; 

from every f1 = employees[eid == 'E1234'] -> f2 = employees[f1.eid == eid] 
                                        or f3 = expiredEventsStream[f1.eid == eid] 
select f1.eid as eid, f2.eid as newEid insert into filter_stream; 

from filter_stream[(newEid is null)] select eid, 'Missing event' as alert 
insert into employees_alerts

This gives me the same output as above, with the difference that:

  1. It does not use "for" syntax and as a result works while enabling and disabling a query.
  2. The alerting time has now increased and the first alert comes at 40th second since it waits for the expiredEventsStream which worries me for larger time windows like 24 hours.

I have also tried to come up with queries that would involve count() and tried a few other things.

Is there a way to avoid "for" syntax and start a time window after the latest event satisfying an eid condition?

  • FWIW, this is easy to do with Flink without using any additional library, such as CEP or siddhi. Whenever an event arrives, delete any existing timer(s), and set a new timer. If a timer ever fires, send an alert. – David Anderson Oct 11 '21 at 23:53
  • Yeah, that makes sense. However, I need to leverage siddhi for this considering our overall usecase. – Madhuri Jain Oct 12 '21 at 23:53

1 Answers1

0

I was able to fix the multiple alert issue by adding the "every" keyword in the query.
So the new query look like:

from not employees[eid == 'E1234'] for 20 sec select eid, 'MissingEvent'
as alert insert into employees_alerts; 

from every f1=employees[eid == 'E1234'] -> not employees[f1.eid == eid] 
for 20 sec select eid, 'MissingEvent' as alert insert into 
employees_alerts;

The Disablement and Enablement of this query now works with a minor issue. With the example given in the question:

  • At "create", it alerts 3 times(20th sec before event1 arrives, 20th sec after first event/before event2 arrives, 20th sec after event3 arrives) - which is right
  • However, when the rule is disabled and enabled, I only get 2 alerts (20th sec after event1 arrives and 20th sec after event3). It misses out the alert at the first 20th sec before event1 arrives.

This can however be overcome by not disabling and enabling the query, but by just Creating, Deleting and Creating again (which is a hack).

Would be nice to have a better solution for this though.