当前位置: 首页 > 知识库问答 >
问题:

口水-如何找出所有规则都匹配?

秦珂
2023-03-14

我有一个。DRL文件,其中包含10条规则。一旦我插入一个事实,一些规则可能会匹配-我如何找出哪些规则是以编程方式匹配的?

共有3个答案

商开济
2023-03-14

您可以使用静态记录器工厂,该工厂将使用您最喜欢的记录器记录DRL文件中的操作。

例如:

import org.drools.runtime.rule.RuleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class DRLLogger {

private DRLLogger() {
}

protected static Logger getLogger(final RuleContext drools) {
    final String category = drools.getRule().getPackageName() + "." + drools.getRule().getName();
    final Logger logger = LoggerFactory.getLogger(category);
    return logger;
}

public static void info(final RuleContext drools, final String message, final Object... parameters) {
    final Logger logger = getLogger(drools);
    logger.info(message, parameters);
}

public static void debug(final RuleContext drools, final String message, final Object... parameters) {
    final Logger logger = getLogger(drools);
    logger.debug(message, parameters);
}

public static void error(final RuleContext drools, final String message, final Object... parameters) {
    final Logger logger = getLogger(drools);
    logger.error(message, parameters);
}

}

然后从您的DRL文件中:

import function com.mycompany.DRLLogger.*

rule "myrule"
when
    $fact: Fact()
then
    info(drools, "Fact:{}", $fact);
end
平羽
2023-03-14

Steve的答案是可靠的,但是drools 6带来的主要变化使代码过时了。我在下面发布了史蒂夫代码的重写,其中考虑了新的api:

package your.preferred.package;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.drools.core.event.DefaultAgendaEventListener;
import org.kie.api.definition.rule.Rule;
import org.kie.api.event.rule.AfterMatchFiredEvent;
import org.kie.api.runtime.rule.Match;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A listener that will track all rule firings in a session.
 * 
 * @author Stephen Masters, Isaac Martin
 */
public class TrackingAgendaEventListener extends DefaultAgendaEventListener  {

    private static Logger log = LoggerFactory.getLogger(TrackingAgendaEventListener.class);

    private List<Match> matchList = new ArrayList<Match>();

    @Override
    public void afterMatchFired(AfterMatchFiredEvent event) {
        Rule rule = event.getMatch().getRule();

        String ruleName = rule.getName();
        Map<String, Object> ruleMetaDataMap = rule.getMetaData();

        matchList.add(event.getMatch());
        StringBuilder sb = new StringBuilder("Rule fired: " + ruleName);

        if (ruleMetaDataMap.size() > 0) {
            sb.append("\n  With [" + ruleMetaDataMap.size() + "] meta-data:");
            for (String key : ruleMetaDataMap.keySet()) {
                sb.append("\n    key=" + key + ", value="
                        + ruleMetaDataMap.get(key));
            }
        }

        log.debug(sb.toString());
    }

    public boolean isRuleFired(String ruleName) {
        for (Match a : matchList) {
            if (a.getRule().getName().equals(ruleName)) {
                return true;
            }
        }
        return false;
    }

    public void reset() {
        matchList.clear();
    }

    public final List<Match> getMatchList() {
        return matchList;
    }

    public String matchsToString() {
        if (matchList.size() == 0) {
            return "No matchs occurred.";
        } else {
            StringBuilder sb = new StringBuilder("Matchs: ");
            for (Match match : matchList) {
                sb.append("\n  rule: ").append(match.getRule().getName());
            }
            return sb.toString();
        }
    }

}
裴嘉许
2023-03-14

请注意,此答案适用于高达5. x的Drools版本。如果您已经转移到6或更高版本,请查看@melchoir55的修改答案。我自己还没有测试过,但我相信它是有效的。

要跟踪规则激活,您可以使用AgendaEventListener。下面是一个示例,如下所示:

https://github.com/gratiartis/sctrcd-payment-validation-web/blob/master/src/main/java/com/sctrcd/drools/util/TrackingAgendaEventListener.java

您只需要创建这样的侦听器并将其连接到会话,如下所示:

ksession = kbase.newStatefulKnowledgeSession();
AgendaEventListener agendaEventListener = new TrackingAgendaEventListener();
ksession.addEventListener(agendaEventListener);
//...
ksession.fireAllRules();
//...
List<Activation> activations = agendaEventListener.getActivationList();

请注意,还有WorkingMemoryEventListener,它使您能够跟踪事实的插入、更新和收回。

跟踪代码

package com.sctrcd.drools.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.drools.definition.rule.Rule;
import org.drools.event.rule.DefaultAgendaEventListener;
import org.drools.event.rule.AfterActivationFiredEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A listener that will track all rule firings in a session.
 * 
 * @author Stephen Masters
 */
public class TrackingAgendaEventListener extends DefaultAgendaEventListener {

    private static Logger log = LoggerFactory.getLogger(TrackingAgendaEventListener.class);

    private List<Activation> activationList = new ArrayList<Activation>();

    @Override
    public void afterActivationFired(AfterActivationFiredEvent event) {
        Rule rule = event.getActivation().getRule();

        String ruleName = rule.getName();
        Map<String, Object> ruleMetaDataMap = rule.getMetaData();

        activationList.add(new Activation(ruleName));
        StringBuilder sb = new StringBuilder("Rule fired: " + ruleName);

        if (ruleMetaDataMap.size() > 0) {
            sb.append("\n  With [" + ruleMetaDataMap.size() + "] meta-data:");
            for (String key : ruleMetaDataMap.keySet()) {
                sb.append("\n    key=" + key + ", value="
                        + ruleMetaDataMap.get(key));
            }
        }

        log.debug(sb.toString());
    }

    public boolean isRuleFired(String ruleName) {
        for (Activation a : activationList) {
            if (a.getRuleName().equals(ruleName)) {
                return true;
            }
        }
        return false;
    }

    public void reset() {
        activationList.clear();
    }

    public final List<Activation> getActivationList() {
        return activationList;
    }

    public String activationsToString() {
        if (activationList.size() == 0) {
            return "No activations occurred.";
        } else {
            StringBuilder sb = new StringBuilder("Activations: ");
            for (Activation activation : activationList) {
                sb.append("\n  rule: ").append(activation.getRuleName());
            }
            return sb.toString();
        }
    }

}
 类似资料:
  • 问题内容: 我有一个.DRL文件,其中有10条规则。插入事实后,可能会匹配一些规则-如何找出以编程方式匹配的规则? 问题答案: 请注意,此答案对不超过5.x的Drools版本有效。 如果您已升至6或更高,请查看@ melchoir55的修改后答案。我还没有亲自测试过,但是我相信它会起作用。 若要跟踪规则激活,可以使用AgendaEventListener。下面是一个示例,可在此处找到: https

  • 我有很长时间使用JBOSS Drools的经验。我正在处理的当前项目使用Drools 4。 这是我在项目中的一条规则 想法是从没有关联目标对象的工作内存中收回此类项目。我正在使用工作内存中的这些对象对其进行测试: 项目{itemId=7305,itemTYpeId=Item\u TYPE\u A,targetId=-1023}目标{targetId=-1023} 在这种情况下,规则不应该开火,但它

  • 我不太会流口水和咕噜。 我有一个关于规则流的基本问题。 我在guvnor插件上使用引导编辑器创建了3条规则。现在我想根据第一条规则的结果调用第二条或第三条规则。 e、 g.如果患者年龄小于18岁,则进行第二条规则的小检查,否则请调用第三条规则由高级医生进行检查。 那么,这可以通过使用规则流来实现吗?如果是,如何?是否有任何示例链接和文档来演示它?非常感谢您的帮助。 谢啦

  • Drools文档提到,规则可以使用诸如生效日期和过期日期之类的属性来指定绝对规则有效期。 例如 Drools还支持周期性重复的规则,间隔为,cron为,但这意味着规则是在这样的点触发的。 我很感兴趣,如果有任何选项如何指定定期可用(不解雇)的规则与时间限制。例如,让我们想象一些公司的营业时间-操作只能在正式工作期间执行,但不能在下班后执行。 我想要这样的东西,但这不是Drools的有效规则 是否可

  • 我刚开始流口水,遇到了一个问题。 我简化了规则以显示问题: 基本上,我想计算特定路段上发生的事件(路段是道路的一部分)。当同一链接上发生3个事件时,我希望触发规则。 上面的规则几乎起作用了,但是当它发射时,它发射了3次,每个事件发射一次。我只希望它发射一次。 我错过了什么? 非常感谢。