規(guī)則監(jiān)控針對(duì)的是對(duì)知識(shí)包調(diào)用的監(jiān)控。在URule Pro當(dāng)中,規(guī)則是放在知識(shí)包是調(diào)用的,所以規(guī)則監(jiān)控也就是對(duì)知識(shí)包的監(jiān)控。
點(diǎn)開每個(gè)項(xiàng)目的知識(shí)包節(jié)點(diǎn),可以看到已定義的知識(shí)包的操作列里都有一個(gè)用于配置監(jiān)控信息的按鈕,如下圖所示:
點(diǎn)擊該按鈕,即可打開針對(duì)當(dāng)前知識(shí)包的監(jiān)控配置窗口,如下圖所示:
勾選“啟用對(duì)當(dāng)前知識(shí)包的調(diào)用監(jiān)控”選項(xiàng),即可開始配置具體的要監(jiān)控的信息。
勾選“啟用對(duì)當(dāng)前知識(shí)包的調(diào)用監(jiān)控”選項(xiàng)后,就可以看到具體可配置的監(jiān)控選項(xiàng),如下圖所示:
整個(gè)監(jiān)控的選項(xiàng)分為三個(gè)部分,分別是監(jiān)控內(nèi)容、輸入數(shù)據(jù)以及輸出數(shù)據(jù)。
監(jiān)控內(nèi)容部分主要是對(duì)系統(tǒng)日志部分內(nèi)容進(jìn)行的監(jiān)控,這部分內(nèi)容依賴于當(dāng)前知識(shí)包中規(guī)則是否開啟“允許調(diào)試信息輸出”屬性以及運(yùn)行項(xiàng)目中有沒有將urule.debug屬性配置為true, 只有這兩個(gè)都開啟了,那么監(jiān)控內(nèi)容部分配置才有意義,否則監(jiān)控到的內(nèi)容皆為空。
之前我們對(duì)規(guī)則中“允許調(diào)試信息輸出”屬性以及運(yùn)行項(xiàng)目中urule.debug屬性有過介紹,要求在生產(chǎn)環(huán)境中一定要把urule.debug屬性設(shè)置為false,這樣所有的調(diào)試信息都將不再產(chǎn)生,就不會(huì)對(duì)性能產(chǎn)生影響。
第二部分和第三部分中會(huì)把當(dāng)前知識(shí)包中用到的所有變量及參數(shù)都羅列出來,我們需要做的就是根據(jù)需要進(jìn)行勾選,這樣在監(jiān)控運(yùn)行時(shí)會(huì)所勾選的輸入以及輸出信息都記錄下來,給我們自定義的監(jiān)控實(shí)現(xiàn)類使用。
配置好監(jiān)控內(nèi)容后,接下來還需要編寫具體的監(jiān)控?cái)?shù)據(jù)處理實(shí)現(xiàn)類,該類編寫完成后需要配置到Spring上下文中,使其成為一個(gè)標(biāo)準(zhǔn)的Spring Bean,這樣引擎才能發(fā)現(xiàn)并使用它,該類接口源碼如下:
package com.bstek.urule.runtime.monitor;
/**
* @author Jacky.gao
* @since 2018年12月17日
*/
public interface InvokeMonitor {
void doMonitor(MonitorData data);
}
這里可能有人會(huì)有疑問,知識(shí)包監(jiān)控為什么還要編寫接口實(shí)現(xiàn)類呢?這是因?yàn)閷?duì)于URule Pro來說,他要做的工作就是把要監(jiān)控的數(shù)據(jù)準(zhǔn)備好,然后交給用戶去處理,因?yàn)閁Rule Pro本身并不知道該如何處理這些要監(jiān)控的數(shù)據(jù),所以需要用戶編寫實(shí)現(xiàn)類來決定如何處理這些監(jiān)控?cái)?shù)據(jù)。
對(duì)于接口實(shí)現(xiàn)類來說,可以把這些監(jiān)控?cái)?shù)據(jù)存儲(chǔ)到傳統(tǒng)的數(shù)據(jù)庫(kù)中,也可以存儲(chǔ)到key-value數(shù)據(jù)庫(kù)中,可以直接存,也可以開啟獨(dú)立線程異步去存。
在這個(gè)接口中,需要實(shí)現(xiàn)的方法只有一個(gè),參數(shù)也只有一個(gè),在這個(gè)MonitorData參數(shù)里,已經(jīng)把上述知識(shí)包監(jiān)控配置里要求監(jiān)控的內(nèi)容都準(zhǔn)備好了,我們直接調(diào)用即可,MonitorData源碼如下:
package com.bstek.urule.runtime.monitor;
import java.util.Date;
import java.util.List;
import com.bstek.urule.model.rete.RuleData;
import com.bstek.urule.runtime.log.FlowNodeLog;
import com.bstek.urule.runtime.log.Log;
import com.bstek.urule.runtime.log.MatchedRuleLog;
/**
* @author Jacky.gao
* @since 2018年12月18日
*/
public interface MonitorData {
/**
* @return 返回當(dāng)前監(jiān)控的知識(shí)包名稱信息:項(xiàng)目名稱/知識(shí)包ID
*/
String getPackageInfo();
/**
* @return 返回規(guī)則運(yùn)行總的耗時(shí),單位為毫秒
*/
long getTotalDuration();
/**
* @return 返回當(dāng)前知識(shí)包版本,如果當(dāng)前知識(shí)包沒有發(fā)布版本,則該值為空
*/
String getVersion();
/**
* @return 返回當(dāng)前知識(shí)包版本備注信息,如果當(dāng)前知識(shí)包沒有發(fā)布版本,則該值為空
*/
String getVersionComment();
/**
* @return 返回當(dāng)前知識(shí)包版本創(chuàng)建日期,如果當(dāng)前知識(shí)包沒有發(fā)布版本,則該值為空
*/
Date getVersionCreateDate();
/**
* @return 返回當(dāng)前知識(shí)包版本創(chuàng)建人,如果當(dāng)前知識(shí)包沒有發(fā)布版本,則該值為空
*/
String getVersionCreateUser();
/**
* @return 返回所有匹配的規(guī)則對(duì)象信息
*/
List<MatchedRuleLog> getMatchedRuleList();
/**
* @return 返回所有不匹配的規(guī)則對(duì)象信息
*/
List<RuleData> getNotMatchRuleList();
/**
* @return 返回所有觸發(fā)了的規(guī)則流節(jié)點(diǎn)信息(如果當(dāng)前有規(guī)則流的話)
*/
List<FlowNodeLog> getFiredFlowNodeList();
/**
* @return 返回當(dāng)前執(zhí)行的知識(shí)包中監(jiān)控是否允許顯示日志信息
*/
boolean isShowLog();
/**
* @return 返回當(dāng)前執(zhí)行的知識(shí)包中是否允許顯示所有匹配的規(guī)則信息
*/
boolean isShowMatchedRuleList();
/**
* @return 返回當(dāng)前執(zhí)行的知識(shí)包中是否要顯示不匹配的規(guī)則信息
*/
boolean isShowNotMatchRuleList();
/**
* @return 返回當(dāng)前執(zhí)行的知識(shí)包中是否顯示觸發(fā)的規(guī)則節(jié)點(diǎn)信息(如果當(dāng)前有規(guī)則流的話)
*/
boolean isShowFiredFlowNodeList();
/**
* @return 返回所有輸入日志信息(如果當(dāng)前配置的日志信息輸出的話)
*/
List<Log> getLogs();
/**
* @return 返回指定的輸入信息
*/
List<IOData> getInputData();
/**
* @return 返回規(guī)則計(jì)算后指定的輸出信息
*/
List<IOData> getOutputData();
}
可以看到,在MonitorData接口中,可以獲取到當(dāng)前知識(shí)包監(jiān)控配置的所有信息,這樣在記錄這個(gè)信息時(shí)可以先判斷系統(tǒng)是否配置了要監(jiān)控這項(xiàng)信息,以防獲取到的信息為空情況發(fā)生。下面的這個(gè)實(shí)現(xiàn)類在輸出要監(jiān)控的信息時(shí)就加了判斷:
package test;
import com.bstek.urule.runtime.monitor.InvokeMonitor;
import com.bstek.urule.runtime.monitor.MonitorData;
/**
* @author Jacky.gao
* @since 2018年12月17日
*/
public class TestInvokeMonitor implements InvokeMonitor {
public void doMonitor(MonitorData data) {
if(data.isShowLog()) {
System.out.println("日志:"+data.getLogs());
}
if(data.isShowFiredFlowNodeList()) {
System.out.println("觸發(fā)的規(guī)則節(jié)點(diǎn)列表:"+data.getFiredFlowNodeList());
}
if(data.isShowMatchedRuleList()) {
System.out.println("匹配的規(guī)則列表:"+data.getMatchedRuleList());
}
if(data.isShowNotMatchRuleList()) {
System.out.println("不匹配的規(guī)則列表:"+data.getNotMatchRuleList());
}
System.out.println("耗時(shí):"+data.getTotalDuration());
System.out.println("packageInfo:"+data.getPackageInfo());
System.out.println("輸入數(shù)據(jù):"+data.getInputData());
System.out.println("輸出數(shù)據(jù):"+data.getOutputData());
}
}
需要注意的是,如果我們使用URule Pro的方式為客戶端服務(wù)器模式,同時(shí)又想對(duì)知識(shí)包調(diào)用進(jìn)行監(jiān)控,那么InvokeMonitor的實(shí)現(xiàn)類則必須配置在知識(shí)包實(shí)際運(yùn)行的客戶端,原因很簡(jiǎn)單,因?yàn)橹R(shí)包是在客戶端運(yùn)行,
要監(jiān)控知識(shí)包,必須要保證當(dāng)前知識(shí)包運(yùn)行環(huán)境里能檢測(cè)到InvokeMonitor的實(shí)現(xiàn)類,所以需要這么配置。
更多建議: