1

With Drools fusion, I want to do some alarm for the cpu_idle of a computer. the condition is:

  1. I would receive a record from the machine I monitored per 10s;

  2. if the cpu_idle<10 , drools should open a time window maybe 10mim, and begin to count of how many times the condition cpu_idle<10 occur, the variable is occur_times .

  3. after 10min, drools check the occur_times.if occur_times>5 then do something alarm else do nothing.

I have no idea how to do this. I use the drools 6.1。below is the main code:

public static void main(String[] args) {
    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add( ResourceFactory.newByteArrayResource(str.getBytes()),
                  ResourceType.DRL );
    InternalKnowledgeBase kbase = (InternalKnowledgeBase) KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
    StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();

    EntryPoint atmStream = ksession.getEntryPoint("ATM Stream" );

     ksession.fireAllRules();
}

I have a record bean like:

public class Record {

    private double cpu_idle;
    private Timestamp collecte_time;
    public double getCpu_idle() {
        return cpu_idle;
    }
    public void setCpu_idle(double cpu_idle) {
        this.cpu_idle = cpu_idle;
    }
    public Timestamp getCollecte_time() {
        return collecte_time;
    }
    public void setCollecte_time(Timestamp collecte_time) {
        this.collecte_time = collecte_time;
    }
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
mrcui
  • 11
  • 1
  • The requirements aren't very elaborate. (a) Is this window reset again if there is an event with cpu_idle >= 10 after a few with < 10? (b) If we have 5 events with cpu_idle < 10: do we really have to wait for the end of 10 minutes before the alarm is raised? (Sounds silly, as in "let it burn a few minutes more before we call the fire brigade".) – laune Feb 17 '15 at 06:30
  • (b) In more detail: since 10 minutes produce 60 events: if there are 5 events with cpu_time < 10, we must have seen 55 with cpu_time >= 10. According to what you write, the alarm must be raised, but why wait? – laune Feb 17 '15 at 06:43
  • hi laune,thank you for your anwser.(a):the window does not reset when there is an event with cpu_idle>=10 after a few with <10 (b):if we have 5 events with cpu_idle<10.we do not need to wait for the end of 10 minutes.we just raise the alarm immediately. and then drools should back to the init state. – mrcui Mar 02 '15 at 02:30
  • simple flow :drools have a ksession(org.kie.api.runtime.KieSession) watch each record received. if cpu_idle >= 10 && drools does not open a window,nothing happend. if cpu_idle < 10,drools opens a window. if cpu_idle >= 10 && drools has opened a window && the length of window is in 10mims,drools should keep this window. if the length of window is out10mims,drools should drop this window. If we have 5 events with cpu_idle < 10,drools should raise alarm immediately,and then close the window, and open window again until next cpu_idle < 10 event occourd. – mrcui Mar 02 '15 at 02:54

1 Answers1

0

You need a

class Window {
    int count = 1;
    long time;
    Window( long time ){...}
    // getters and setters
}

and the following rules (all untested):

rule "nothing to do"
when
    $r: Record( cpu_idle >= 10 )
    not Window()
then
    retract( $r );
end

rule "open new window"
when
    $r: Record( cpu_idle < 10, $ts: collecte_time )
    not Window()
then
    insert( new Window( $ts.getTime() ) );
    retract( $r );
end

rule "keep window"
when
    $r: Record( cpu_idle >= 10, $ts: collecte_time )
    $w: Window( $ns: time )
    eval( ($ts.getTime() - $ns)/1000 <= 10*60)
then
    retract( $r );
    modify( $w ){ setCount( $w.getCount() + 1 ) }
end

rule "drop window"
when
    $r: Record( cpu_idle >= 10, $ts: collecte_time )
    $w: Window( $ns: time )
    eval( ($ts.getTime() - $ns)/1000 > 10*60)
then
    retract( $r );
    retract( $w );
end

rule "alarm"
when
    $w: Window( count >= 5 )
then
    // raise alarm
    retract( $w );
end

I'd use Date rather than lava.sql.Timestamp in Record.

laune
  • 31,114
  • 3
  • 29
  • 42