Red Hat
Mar 5, 2012
by devdude

At the ‘hello world’ level we cant see much need to debug our rules, but with growing complexity we will be challenged quickly. We need to see which rules was fired, what parameter, what object, etc. Eclipse IDE users have the advantage of the plugin which even visualizes the RETE tree, for the rest-of-us, aka Netbeans user, we need to rely on the debugging output available. We have 4 options that give us access to almost all information of interest.

To try the below debugging options, use the previous HelloDrools Tutorial

1. Default Debug Listener

Out-of-the-box we can use 2 debug event listener :

        ...
        ksession = kbase.newStatefulKnowledgeSession();

        ksession.addEventListener( new DebugAgendaEventListener() );
        ksession.addEventListener( new DebugWorkingMemoryEventListener() );
        ...



This creates some output like this

 run:
 ==>[ActivationCreatedEvent: getActivation()=[Activation rule=Hello World 2, act#=0, salience=0, tuple=[fact 0:1:41000735:41000735:1:DEFAULT:hellodrools.Message@2719f1f]
 ], getKnowledgeRuntime()=org.drools.impl.StatefulKnowledgeSessionImpl@257b40fe]
 Test, Drools!
 RULES FIRED. ----------
 ==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:1:41000735:41000735:1:DEFAULT:hellodrools.Message@2719f1f], getObject()=hellodrools.Message@2719f1f, getKnowledgeRuntime()=org.drools.impl.StatefulKnowledgeSessionImpl@257b40fe, getPropagationContext()=PropagationContextImpl [activeActivations=0, dormantActivations=0, entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:1:41000735:41000735:1:DEFAULT:hellodrools.Message@2719f1f], leftTuple=null, originOffset=-1, propagationNumber=3, rule=null, type=0]]
 ==>[BeforeActivationFiredEvent: getActivation()=[Activation rule=Hello World 2, act#=0, salience=0, tuple=[fact 0:1:41000735:41000735:1:DEFAULT:hellodrools.Message@2719f1f]
 ], getKnowledgeRuntime()=org.drools.impl.StatefulKnowledgeSessionImpl@257b40fe]
 ==>[AfterActivationFiredEvent: getActivation()=[Activation rule=Hello World 2, act#=0, salience=0, tuple=[fact 0:1:41000735:41000735:1:DEFAULT:hellodrools.Message@2719f1f]
 ], getKnowledgeRuntime()=org.drools.impl.StatefulKnowledgeSessionImpl@257b40fe]
 BUILD SUCCESSFUL (total time: 4 seconds)

2. Custom Listener

or we can create custom listener by overriding AgendaEventListener and WorkingMemoryEventListener:

  • Add a new class CustomAgendaEventListener and override AgendaEventListener

    New Class

    Implement all abstract methods

    Complete class

  • Now you have full control what debugging information you want to log for any event.

    I suggest you explore the objects and its attributes. Look into the API .

        ...
        @Override
        public void beforeActivationFired(BeforeActivationFiredEvent bafe) {
            final Rule rule = bafe.getActivation().getRule();
            System.out.println(bafe.getClass().getSimpleName());
            System.out.println(rule.getPackageName() + "." + rule.getName());
        ...
        }
    
  • Add a new class CustomWorkingMemoryEventListener and override WorkingMemoryEventListener

    (as above)

3. Logger Factory KnowledgeRuntimeLoggerFactory

  • Output to console or file, similar info as the event listener
  • API Documentation (link , link )

    KnowledgeRuntimeLoggerFactory Output

4. Helper Class

  • Different approach, instead of listening to the rule engine, we embed logging information in the rule itself by the use of a helper class
  • Create helper class Helper.java

    package hellodrools;
    import org.drools.spi.KnowledgeHelper;
    
    public class Helper {
    
        public static void log(final KnowledgeHelper drools, final String message){
            System.out.println(message);
            System.out.println("\nrule triggered: " + drools.getRule().getName());
            System.out.println(drools.getActivation().getFactHandle());
        }
    
    }
    
  • Import the helper into the rule file and user helper method

    import hellodrools.Message
    import function hellodrools.Helper.log;
    rule "Hello World"
    when
        message:Message (type=="Hello")
    then
        System.out.println("Hello World, Drools!");
        log(drools,"extra info");
    end
    
    
  • Run the application

Reference: