在URule Pro提供的所有類型的規(guī)則文件中,在它們的屬性里都有一個(gè)名為“允許調(diào)試信息輸出”的屬性,我們需要做的就是添加這個(gè)屬性同時(shí)設(shè)置屬性值為“是”,這樣規(guī)則在運(yùn)行時(shí)默認(rèn)就會(huì)向控制臺(tái)打印出包含條件匹配信息、動(dòng)作執(zhí)行情況等所有日志信息,通過(guò)這些信息我們可以跟蹤規(guī)則執(zhí)行情況,在規(guī)則出現(xiàn)錯(cuò)誤或與預(yù)期不一致時(shí)通過(guò)調(diào)試信息的輸出就可快速定位問(wèn)題所在。
下圖展示的就是添加了“允許調(diào)試信息輸出”的屬性并設(shè)置為“是”后的效果。
在URule Pro中還提供了一個(gè)名為urule.debug的系統(tǒng)組屬性,該屬性值默認(rèn)為true,這時(shí)所有調(diào)試信息默認(rèn)都會(huì)直接在控制臺(tái)上打印,當(dāng)將產(chǎn)品部署到生產(chǎn)環(huán)境中時(shí),我們需要將urule.debug屬性設(shè)置為false,這樣所有調(diào)試信息都不會(huì)再輸出,這其中也包括URule規(guī)則集里提供的名為“打印內(nèi)容到控制臺(tái)”的動(dòng)作,這樣就可以快速完成項(xiàng)目上線,而不用擔(dān)心項(xiàng)目中因有大量調(diào)試信息輸出而需要重新修改規(guī)則屬性的問(wèn)題。如下圖所示:
在代碼中調(diào)用規(guī)則時(shí),如果也要在本地查看調(diào)試信息,那么首先需要將urule.debug屬性設(shè)置為true,接下來(lái)為urule.defaultHtmlFileDebugPath屬性設(shè)置一個(gè)具體的已存在的目錄值即可。 設(shè)置好urule.defaultHtmlFileDebugPath屬性后,默認(rèn)會(huì)向這個(gè)屬性對(duì)應(yīng)的目錄中輸出以HTML格式的日志文件(默認(rèn)情況下urule.defaultHtmlFileDebugPath屬性值為空,不會(huì)輸出任何日志文件), 輸出的HTML日志文件采用的是時(shí)間戳命名方式,在生產(chǎn)環(huán)境下建議清空urule.defaultHtmlFileDebugPath屬性,以免調(diào)試信息輸出對(duì)性能產(chǎn)生影響。
在規(guī)則調(diào)用時(shí)需要在session.fireRules()或session.startProcess(...)方法后加上session.writeLogFile()方法,這樣才會(huì)執(zhí)行日志寫入操作。
在某些情況下,為了方便查看,我們可能需要將這些調(diào)試信息輸出到一個(gè)具體的文件,對(duì)于這一點(diǎn),URule Pro也提供了相應(yīng)的支持。 對(duì)于老版本URule Pro會(huì)嘗試將調(diào)試信息提供給所有實(shí)現(xiàn)了com.bstek.urule.debug.DebugWriter接口的實(shí)現(xiàn)類,由這個(gè)實(shí)現(xiàn)類來(lái)決定具體該輸出到何處。
以下為DebugWriter實(shí)現(xiàn)類源碼(實(shí)現(xiàn)類需要配置到spring中成為一個(gè)標(biāo)準(zhǔn)bean,這樣引擎才能發(fā)現(xiàn)并使用它)
package com.bstek.urule.debug;
import java.io.IOException;
import java.util.List;
/**
* @author Jacky.gao
* @since 2017年11月27日
*/
public interface DebugWriter {
void write(List<MessageItem> items) throws IOException;
}
在2.1.3版本后建議使用com.bstek.urule.runtime.log.LogWriter接口來(lái)代替DebugWriter接口,com.bstek.urule.runtime.log.LogWriter接口源碼如下:
package com.bstek.urule.runtime.log;
import java.io.IOException;
import java.util.List;
/**
* @author Jacky.gao
* @since 2018年12月11日
*/
public interface LogWriter {
void write(List<Log> logs) throws IOException;
}
在這個(gè)LogWriter接口中,要輸出的是一個(gè)Log接口,如果要實(shí)現(xiàn)自己的LogWriter實(shí)現(xiàn)類,那么可以對(duì)這里的Log接口進(jìn)行迭代,下面是系統(tǒng)內(nèi)置的默的輸出到控制臺(tái)的ConsoleLogWriter類源碼,實(shí)際使用時(shí)可以依照此代碼來(lái)迭代日志信息。
package com.bstek.urule.console.servlet.console;
import java.io.IOException;
import java.util.List;
import com.bstek.urule.runtime.log.DataLog;
import com.bstek.urule.runtime.log.Log;
import com.bstek.urule.runtime.log.LogWriter;
import com.bstek.urule.runtime.log.UnitLog;
/**
* @author Jacky.gao
* @since 2017年11月28日
*/
public class ConsoleLogWriter implements LogWriter {
private DebugMessageHolder debugMessageHolder;
@Override
public void write(List<Log> logs) throws IOException {
StringBuilder sb=new StringBuilder();
buildLogs(sb, logs);
String key=debugMessageHolder.generateKey();
System.out.println("Console key : "+key);
ConsoleKeyHolder.setKey(key);
debugMessageHolder.putDebugMessage(key, sb.toString());
}
private void buildLogs(StringBuilder msg,List<Log> logs) {
for(Log log:logs){
if(log instanceof UnitLog) {
msg.append("<div style=\"margin:8px;border:dashed 1px #cccccc\">");
UnitLog unit=(UnitLog)log;
List<Log> unitLogs=unit.getLogs();
buildLogs(msg, unitLogs);
msg.append("</div>");
}else if(log instanceof DataLog) {
DataLog dataLog=(DataLog)log;
String htmlMsg=dataLog.getHtmlMsg();
msg.append(htmlMsg);
}
}
}
public void setDebugMessageHolder(DebugMessageHolder debugMessageHolder) {
this.debugMessageHolder = debugMessageHolder;
}
}
無(wú)論是DebugWriter接口或是LogWriter接口,實(shí)現(xiàn)后配置到Spring上下文環(huán)境里,在代碼中調(diào)用要生效同樣需要在session.fireRules()或session.startProcess(...)方法后加上session.writeLogFile()方法,
否則將不會(huì)觸發(fā)執(zhí)行。
上面介紹的通過(guò)配置urule.defaultHtmlFileDebugPath屬性就會(huì)在指定目錄生成日志文件的操作,實(shí)際上就是系統(tǒng)提供的一個(gè)默認(rèn)的LogWriter接口實(shí)現(xiàn)類,該實(shí)現(xiàn)類在運(yùn)行前會(huì)判斷urule.defaultHtmlFileDebugPath屬性值是否為空,
如果為空,則不做任何操作,不為空,那么就認(rèn)為這個(gè)值是一個(gè)目錄,并嘗試在這個(gè)目錄中生成HTML格式的日志文件。
最后,再次強(qiáng)調(diào),如果要將項(xiàng)目部署到生產(chǎn)環(huán)境,一定要將urule.debug屬性設(shè)置為false,否則因?yàn)橛姓{(diào)試信息產(chǎn)生會(huì)影響系統(tǒng)性能,urule.debug屬性設(shè)置為false后,所有的調(diào)試信息都將不再輸出,包括“打印內(nèi)容到控制臺(tái)”的內(nèi)置動(dòng)作也不再執(zhí)行。
更多建議: