在URule Pro提供的所有類型的規(guī)則文件中,在它們的屬性里都有一個名為“允許調(diào)試信息輸出”的屬性,我們需要做的就是添加這個屬性同時設(shè)置屬性值為“是”,這樣規(guī)則在運行時默認就會向控制臺打印出包含條件匹配信息、動作執(zhí)行情況等所有日志信息,通過這些信息我們可以跟蹤規(guī)則執(zhí)行情況,在規(guī)則出現(xiàn)錯誤或與預(yù)期不一致時通過調(diào)試信息的輸出就可快速定位問題所在。
下圖展示的就是添加了“允許調(diào)試信息輸出”的屬性并設(shè)置為“是”后的效果。
在URule Pro中還提供了一個名為urule.debug的系統(tǒng)組屬性,該屬性值默認為true,這時所有調(diào)試信息默認都會直接在控制臺上打印,當(dāng)將產(chǎn)品部署到生產(chǎn)環(huán)境中時,我們需要將urule.debug屬性設(shè)置為false,這樣所有調(diào)試信息都不會再輸出,這其中也包括URule規(guī)則集里提供的名為“打印內(nèi)容到控制臺”的動作,這樣就可以快速完成項目上線,而不用擔(dān)心項目中因有大量調(diào)試信息輸出而需要重新修改規(guī)則屬性的問題。如下圖所示:
在代碼中調(diào)用規(guī)則時,如果也要在本地查看調(diào)試信息,那么首先需要將urule.debug屬性設(shè)置為true,接下來為urule.defaultHtmlFileDebugPath屬性設(shè)置一個具體的已存在的目錄值即可。 設(shè)置好urule.defaultHtmlFileDebugPath屬性后,默認會向這個屬性對應(yīng)的目錄中輸出以HTML格式的日志文件(默認情況下urule.defaultHtmlFileDebugPath屬性值為空,不會輸出任何日志文件), 輸出的HTML日志文件采用的是時間戳命名方式,在生產(chǎn)環(huán)境下建議清空urule.defaultHtmlFileDebugPath屬性,以免調(diào)試信息輸出對性能產(chǎn)生影響。
在規(guī)則調(diào)用時需要在session.fireRules()或session.startProcess(...)方法后加上session.writeLogFile()方法,這樣才會執(zhí)行日志寫入操作。
在某些情況下,為了方便查看,我們可能需要將這些調(diào)試信息輸出到一個具體的文件,對于這一點,URule Pro也提供了相應(yīng)的支持。 對于老版本URule Pro會嘗試將調(diào)試信息提供給所有實現(xiàn)了com.bstek.urule.debug.DebugWriter接口的實現(xiàn)類,由這個實現(xiàn)類來決定具體該輸出到何處。
以下為DebugWriter實現(xiàn)類源碼(實現(xiàn)類需要配置到spring中成為一個標(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接口來代替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;
}
在這個LogWriter接口中,要輸出的是一個Log接口,如果要實現(xiàn)自己的LogWriter實現(xiàn)類,那么可以對這里的Log接口進行迭代,下面是系統(tǒng)內(nèi)置的默的輸出到控制臺的ConsoleLogWriter類源碼,實際使用時可以依照此代碼來迭代日志信息。
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;
}
}
無論是DebugWriter接口或是LogWriter接口,實現(xiàn)后配置到Spring上下文環(huán)境里,在代碼中調(diào)用要生效同樣需要在session.fireRules()或session.startProcess(...)方法后加上session.writeLogFile()方法,
否則將不會觸發(fā)執(zhí)行。
上面介紹的通過配置urule.defaultHtmlFileDebugPath屬性就會在指定目錄生成日志文件的操作,實際上就是系統(tǒng)提供的一個默認的LogWriter接口實現(xiàn)類,該實現(xiàn)類在運行前會判斷urule.defaultHtmlFileDebugPath屬性值是否為空,
如果為空,則不做任何操作,不為空,那么就認為這個值是一個目錄,并嘗試在這個目錄中生成HTML格式的日志文件。
最后,再次強調(diào),如果要將項目部署到生產(chǎn)環(huán)境,一定要將urule.debug屬性設(shè)置為false,否則因為有調(diào)試信息產(chǎn)生會影響系統(tǒng)性能,urule.debug屬性設(shè)置為false后,所有的調(diào)試信息都將不再輸出,包括“打印內(nèi)容到控制臺”的內(nèi)置動作也不再執(zhí)行。
更多建議: