hi Eli,
you have asked a very interesting question indeed. I hope I have
understood your goal correctly, and below is a rule which tries to
address it. The rule relies on the following observation -- if the
event counting operation does not reach the threshold by the end of
its window, the window must slide forward. Because we want to release
the collected events at this particular moment, an action must be
executed when the window sliding occurs. Unfortunately, the
SingleWithThreshold rule does not have that functionality, but the
EventGroup rule (generalization of SingleWithThreshold) does. Here is
an example which utilizes EventGroup rule and uses the
'EVENTS_$+{host}' context for recording all events observed by the
EventGroup event counting operation for the given host $+{host}:
type=EventGroup
ptype=RegExp
pattern=^(?<host>\S+) (?<if>\S+) (?:up|down)$
context=!RELEASED_EVENT
init=create EVENTS_$+{host}
count=add EVENTS_$+{host} $0
end=delete EVENTS_$+{host}
slide=copy EVENTS_$+{host} %events; cevent RELEASED_EVENT 0 %events;
reset 0; delete EVENTS_$+{host}
desc=multiple interfaces up/down on host $+{host}
action=event 0 %s
window=60
thresh=3
type=Single
ptype=RegExp
pattern=^(?<host>\S+) (?<if>\S+) (?:up|down)$
desc=demo rule for printing released events
action=write - Released event: $0
Let me explain the EventGroup rule step by step. The 'init' field of
the rule will set up the event recording context EVENTS_$+{host}, and
the 'count' field of the rule makes sure that every matching event
gets recorded to this context. The 'end' field of the rule will make
sure that the EVENTS_$+{host} context gets dropped from memory when
the event counting operation terminates in a normal way (that is, it
is *not* terminated with the 'reset' action).
The 'slide' field of the rule is a bit more complicated and contains 4
actions. These actions get executed when the event counting operation
has reached the end of its 60 second window and does *not* have enough
events to execute its regular output action (given with the 'action'
field). The entire purpose of the 'slide' field is to "release" events
which the event counting operation has collected -- in other words,
the events which have been recorded to the EVENTS_$+{host} context.
To achieve that goal, the first action of the 'slide' field is 'copy
EVENTS_$+{host} %events', which saves all events from the context to
the action list variable %events. The next action is 'cevent
RELEASED_EVENT 0 %events', which creates synthetic events from the
potentially multiline variable %events, so that each line becomes a
separate synthetic event. In addition, the 'cevent' action makes sure
that RELEASED_EVENT internal context is set up during the processing
of each synthetic event, so that these events could be distinguished
from regular input events. That is important, because otherwise the
EventGroup rule would match these synthetic events, and to prevent
that, the EventGroup rule has the following field:
context=!RELEASED_EVENT
After the first two actions of the 'slide' field have been executed,
the 'reset 0' action will terminate the counting operation, because
releasing the collected events makes this operation pointless. And
because killing the operation with 'reset' action does not execute the
action on the 'end' field, we need the final 'delete EVENTS_$+{host}'
action on the 'slide' field, so that the context of the terminated
operation would be properly dropped from memory.
To test the above ruleset of two rules, you need the --intcontext
command line option, which enables internal contexts for input sources
(otherwise the context RELEASED_EVENT would not be set up). Here is an
example test:
sec --conf=eli.sec --input=- --intcontexts
SEC (Simple Event Correlator) 2.9.2
Reading configuration from eli.sec
2 rules loaded from eli.sec
No --bufsize command line option or --bufsize=0, setting --bufsize to 1
Opening input file -
Interactive process, SIGINT can't be used for changing the logging level
Host1 int1 up <--- input from keyboard
Creating context 'EVENTS_Host1'
Adding event(s) 'Host1 int1 up' to context 'EVENTS_Host1'
Host1 int2 up <--- input from keyboard
Adding event(s) 'Host1 int2 up' to context 'EVENTS_Host1'
Copying context 'EVENTS_Host1' to variable '%events' <--- here we
have reached the end of the 60-second window...
Variable '%events' set to 'Host1 int1 up
Host1 int2 up'
Creating event 'Host1 int1 up' with context 'RELEASED_EVENT'
Creating event 'Host1 int2 up' with context 'RELEASED_EVENT'
Terminating event correlation operation 'eli.sec | 0 | multiple
interfaces up/down on host Host1'
Deleting context 'EVENTS_Host1'
Context 'EVENTS_Host1' deleted
Writing event 'Released event: Host1 int1 up' to file '-' <--- and
here the 2nd demo rule starts to match released events
Released event: Host1 int1 up
Writing event 'Released event: Host1 int2 up' to file '-'
Released event: Host1 int2 up
I hope that the above example ruleset is useful.
kind regards,
risto
Kontakt Kagan, Eli via Simple-evcorr-users
(<[email protected]>) kirjutas kuupäeval E,
12. jaanuar 2026 kell 19:41:
>
> Hi all,
>
>
>
> I’m struggling with how `SingleWithThreshold` handles events that do not
> reach the threshold, and I’m hoping someone can point me in the right
> direction.
>
>
>
> My goal is to correlate multiple interface up/down events into a single
> aggregated event.
>
> I created a `SingleWithThreshold` rule that looks for three interface up/down
> events on the same host within one minute and generates a synthetic event
> such as: “multiple interfaces up/down on host H”
>
> That part works fine.
>
>
>
> The problem is what happens to individual interface events that do not
> trigger the threshold. These events are still consumed by the
> `SingleWithThreshold` rule and never reach any other rules.
>
> I tried using a context followed by a `Suppress` rule, but then I end up with
> two individual up/down events followed by the aggregated event, which is not
> what I want.
>
>
>
> What I would like is this behavior:
>
> Input:
>
> Host1 int1 up
>
> Host1 int2 up
>
> Host1 int3 up
>
> Host2 int1 up
>
>
>
> Output:
>
> Multiple interfaces up/down on Host1
>
> Host2 int1 up
>
>
>
> In other words:
>
> * If three up/down events occur on the same host within one minute, emit only
> the aggregated event and suppress the individual ones.
>
> * If fewer than three occur, allow the individual events to be processed by
> other rules normally.
>
>
>
> Conceptually, what I am trying to achieve is if a `SingleWithThreshold` rule
> does not reach its threshold, it should “release” the events it has ingested
> so far so they can be processed by other rules.
>
>
>
> Below is my (failed) attempt:
>
> type=SingleWithThreshold
>
> ptype=RegExp
>
> pattern=^(?<host>\S+) (?<if>\S+) (?:up|down)$
>
> desc=multiple interfaces up/down on host $+{host}
>
> action=event 0 %s; create SUPPRESS-IF-ON-HOST:$+{host} 60
>
> window=60
>
> thresh=2
>
> continue=TakeNext
>
>
>
> type=Suppress
>
> ptype=RegExp
>
> pattern=^(?<host>\S+) (?<if>\S+) (?:up|down)$
>
> desc=$0
>
> context=SUPPRESS-IF-ON-HOST:$+{host}
>
>
>
>
>
> Any guidance on how to implement this correctly would be greatly appreciated.
>
>
>
> Thanks,
>
> Eli
>
>
> _______________________________________________
> Simple-evcorr-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/simple-evcorr-users
_______________________________________________
Simple-evcorr-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/simple-evcorr-users