20 — Advanced
Rule Tracing & Debugging
The Tracer provides event-driven debugging for rule execution. It lets you observe every stage of a rule or ruleset lifecycle through listener callbacks, making it easy to debug, audit, and monitor your rule engine in action.
Listener Types
Tracer supports three listener types, each targeting a different scope of events:
RuliiListener
Receives all events (rules and rulesets)
RuleListener
Receives rule-level events only
RuleSetListener
Receives ruleset-level events only
Creating a Tracer
Tracer tracer = Tracer.builder().build();
Rule-Level Events
A RuleListener can respond to the following events during rule execution:
| Event | Description |
|---|---|
| onRuleStart | Fired when a rule begins execution |
| onPreConditionCheck | Fired before the pre-condition is evaluated |
| onConditionCheck | Fired after the main condition is evaluated |
| onThen | Fired when the then-action executes |
| onOtherwise | Fired when the otherwise-action executes |
| onRuleError | Fired when a rule throws an error |
| onRuleEnd | Fired when a rule finishes execution |
RuleSet-Level Events
A RuleSetListener can respond to the following events during ruleset execution:
| Event | Description |
|---|---|
| onRuleSetStart | Fired when a ruleset begins execution |
| onPreConditionCheck | Fired before the ruleset pre-condition |
| onInitializer | Fired when the initializer runs |
| onRuleRun | Fired each time a rule within the set runs |
| onStop | Fired when execution stops early |
| onFinalizer | Fired when the finalizer runs |
| onResult | Fired when the result is produced |
| onRuleSetEnd | Fired when the ruleset finishes |
| onError | Fired when the ruleset encounters an error |
Example: Adding a Rule Listener
Tracer tracer = Tracer.builder().build();
// Add a rule listener
tracer.addListener(new RuleListener() {
@Override
public void onRuleStart(Rule rule) {
System.out.println("Starting: " + rule.getName());
}
@Override
public void onConditionCheck(Rule rule, Condition condition, boolean result) {
System.out.println(rule.getName() + " condition: " + result);
}
@Override
public void onRuleEnd(Rule rule, RuleResult result) {
System.out.println("Finished: " + rule.getName() + " → " + result.status());
}
});
// Use tracer in RuleContext
RuleContext ctx = RuleContext.builder()
.tracer(tracer)
.build(name -> "Alice", age -> 30);
rule.run(ctx);
// Output:
// Starting: AgeCheck
// AgeCheck condition: true
// Finished: AgeCheck → PASS
Listener Management
The Tracer provides methods to manage listeners at runtime:
// Add a listener
tracer.addListener(myListener);
// Remove a specific listener
tracer.removeListener(myListener);
// Clear all listeners
tracer.clear();
Use Cases
Debugging
Step through rule execution to identify logic issues
Audit Logging
Record which rules fired and their outcomes
Monitoring
Track rule execution performance and patterns