18.調試信息輸出
概述
在URule Pro提供的所有(yǒu)類型的規則文件中,在它們的屬性裏都有(yǒu)一個(gè)名為(wèi)“允許調試信息輸出”的屬性,我們需要做(zuò)的就是添加這個(gè)屬性同時(shí)設置屬性值為(wèi)“是”,這樣規則在運行(xíng)時(shí)默認就會(huì)向控制(zhì)台打印出包含條件匹配信息、動作(zuò)執行(xíng)情況等所有(yǒu)日志(zhì)信息,通(tōng)過這些(xiē)信息我們可(kě)以跟蹤規則執行(xíng)情況,在規則出現錯誤或與預期不一緻時(shí)通(tōng)過調試信息的輸出就可(kě)快速定位問題所在。
下圖展示的就是添加了“允許調試信息輸出”的屬性并設置為(wèi)“是”後的效果。
在URule Pro中還(hái)提供了一個(gè)名為(wèi)urule.debug的系統屬性,該屬性值默認為(wèi)true,這時(shí)所有(yǒu)調試信息默認都會(huì)直接在控制(zhì)台上(shàng)打印,當将産品部署到生(shēng)産環境中時(shí),我們需要将urule.debug屬性設置為(wèi)false,這樣所有(yǒu)調試信息都不會(huì)再輸出,這其中也包括URule規則集裏提供的名為(wèi)“打印內(nèi)容到控制(zhì)台”的動作(zuò),這樣就可(kě)以快速完成項目上(shàng)線,而不用擔心項目中因有(yǒu)大(dà)量調試信息輸出而需要重新修改規則屬性的問題。如下圖所示:
在向導式規則集文件當中,為(wèi)了更好的統一控制(zhì)日志(zhì)開(kāi)關,在設計(jì)器(qì)上(shàng)方的配置按鈕菜單下提供了一個(gè)針對當前文件級的日志(zhì)開(kāi)關控制(zhì)的菜單項,如下圖所示:
一旦我們配置了這個(gè)菜單項裏的日志(zhì)開(kāi)關,那(nà)麽當前規則文件中沒有(yǒu)顯示配置是否允許日志(zhì)輸出的規則将采用這裏配置的日志(zhì)開(kāi)關屬性,如果單個(gè)規則中配置了日志(zhì)輸出屬性,那(nà)麽将覆蓋工具欄中統一配置的日志(zhì)開(kāi)關屬性。
調試信息輸出目的地配置
在代碼中調用規則時(shí),如果也要在本地查看調試信息,那(nà)麽首先需要将urule.debug屬性設置為(wèi)true,接下來(lái)為(wèi)urule.defaultHtmlFileDebugPath屬性設置一個(gè)具體(tǐ)的已存在的目錄值即可(kě)。 設置好urule.defaultHtmlFileDebugPath屬性後,默認會(huì)向這個(gè)屬性對應的目錄中輸出以HTML格式的日志(zhì)文件(默認情況下urule.defaultHtmlFileDebugPath屬性值為(wèi)空(kōng),不會(huì)輸出任何日志(zhì)文件), 輸出的HTML日志(zhì)文件采用的是時(shí)間(jiān)戳命名方式,在生(shēng)産環境下建議清空(kōng)urule.defaultHtmlFileDebugPath屬性,以免調試信息輸出對性能産生(shēng)影(yǐng)響。
在規則調用時(shí)需要在session.fireRules()或session.startProcess(...)方法後加上(shàng)session.writeLogFile()方法,這樣才會(huì)執行(xíng)日志(zhì)寫入操作(zuò)。
在某些(xiē)情況下,為(wèi)了方便查看,我們可(kě)能需要将這些(xiē)調試信息輸出到一個(gè)具體(tǐ)的文件,對于這一點,URule Pro也提供了相應的支持。 我們需要做(zuò)的就是實現一個(gè)com.bstek.urule.runtime.log.LogWriter接口的實現類,并将其配置在Spring當中,讓其成為(wèi)一個(gè)标準的Spring Bean,這個(gè)引擎就可(kě)以發現并在日志(zhì)輸出的時(shí)候調用, 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接口,如果要實現自己的LogWriter實現類,那(nà)麽可(kě)以對這裏的Log接口進行(xíng)叠代,下面是系統內(nèi)置的默的輸出到控制(zhì)台的ConsoleLogWriter類源碼,實際使用時(shí)可(kě)以依照此代碼來(lái)叠代日志(zhì)信息。
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;
}
}
LogWriter接口實現後配置到Spring上(shàng)下文環境裏,在代碼中調用要生(shēng)效同樣需要在session.fireRules()或session.startProcess(...)方法後加上(shàng)session.writeLogFile()方法, 否則将不會(huì)觸發執行(xíng)。
上(shàng)面介紹的通(tōng)過配置urule.defaultHtmlFileDebugPath屬性就會(huì)在指定目錄生(shēng)成日志(zhì)文件的操作(zuò),實際上(shàng)就是系統提供的一個(gè)默認的LogWriter接口實現類,該實現類在運行(xíng)前會(huì)判斷urule.defaultHtmlFileDebugPath屬性值是否為(wèi)空(kōng), 如果為(wèi)空(kōng),則不做(zuò)任何操作(zuò),不為(wèi)空(kōng),那(nà)麽就認為(wèi)這個(gè)值是一個(gè)目錄,并嘗試在這個(gè)目錄中生(shēng)成HTML格式的日志(zhì)文件。
最後,再次強調,如果要将項目部署到生(shēng)産環境,一定要将urule.debug屬性設置為(wèi)false,否則因為(wèi)有(yǒu)調試信息産生(shēng)會(huì)影(yǐng)響系統性能,urule.debug屬性設置為(wèi)false後,所有(yǒu)的調試信息都将不再輸出,包括“打印內(nèi)容到控制(zhì)台”的內(nèi)置動作(zuò)也不再執行(xíng)。