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
- 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
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: