18.調(diào)試信息輸出

2019-09-19 12:15 更新

18.調(diào)試信息輸出

概述

在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)試信息輸出目的地配置 {#id-18.調(diào)試信息輸出-調(diào)試信息輸出目的地配置}

在代碼中調(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í)行。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)