18.调试信息输出
18.调试信息输出
概述
在URule Pro提供的所有类型的规则文件中,在它们的属性里都有一个名为“允许调试信息输出”的属性,我们需要做的就是添加这个属性同时设置属性值为“是”,这样规则在运行时默认就会向控制台打印出包含条件匹配信息、动作执行情况等所有日志信息,通过这些信息我们可以跟踪规则执行情况,在规则出现错误或与预期不一致时通过调试信息的输出就可快速定位问题所在。
下图展示的就是添加了“允许调试信息输出”的属性并设置为“是”后的效果。
在URule Pro中还提供了一个名为urule.debug的系统组属性,该属性值默认为true,这时所有调试信息默认都会直接在控制台上打印,当将产品部署到生产环境中时,我们需要将urule.debug属性设置为false,这样所有调试信息都不会再输出,这其中也包括URule规则集里提供的名为“打印内容到控制台”的动作,这样就可以快速完成项目上线,而不用担心项目中因有大量调试信息输出而需要重新修改规则属性的问题。如下图所示:
调试信息输出目的地配置 {#id-18.调试信息输出-调试信息输出目的地配置}
在代码中调用规则时,如果也要在本地查看调试信息,那么首先需要将urule.debug属性设置为true,接下来为urule.defaultHtmlFileDebugPath属性设置一个具体的已存在的目录值即可。 设置好urule.defaultHtmlFileDebugPath属性后,默认会向这个属性对应的目录中输出以HTML格式的日志文件(默认情况下urule.defaultHtmlFileDebugPath属性值为空,不会输出任何日志文件), 输出的HTML日志文件采用的是时间戳命名方式,在生产环境下建议清空urule.defaultHtmlFileDebugPath属性,以免调试信息输出对性能产生影响。
在规则调用时需要在session.fireRules()或session.startProcess(...)方法后加上session.writeLogFile()方法,这样才会执行日志写入操作。
在某些情况下,为了方便查看,我们可能需要将这些调试信息输出到一个具体的文件,对于这一点,URule Pro也提供了相应的支持。 对于老版本URule Pro会尝试将调试信息提供给所有实现了com.bstek.urule.debug.DebugWriter接口的实现类,由这个实现类来决定具体该输出到何处。
以下为DebugWriter实现类源码(实现类需要配置到spring中成为一个标准bean,这样引擎才能发现并使用它)
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接口,如果要实现自己的LogWriter实现类,那么可以对这里的Log接口进行迭代,下面是系统内置的默的输出到控制台的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接口,实现后配置到Spring上下文环境里,在代码中调用要生效同样需要在session.fireRules()或session.startProcess(...)方法后加上session.writeLogFile()方法,
否则将不会触发执行。
上面介绍的通过配置urule.defaultHtmlFileDebugPath属性就会在指定目录生成日志文件的操作,实际上就是系统提供的一个默认的LogWriter接口实现类,该实现类在运行前会判断urule.defaultHtmlFileDebugPath属性值是否为空,
如果为空,则不做任何操作,不为空,那么就认为这个值是一个目录,并尝试在这个目录中生成HTML格式的日志文件。
最后,再次强调,如果要将项目部署到生产环境,一定要将urule.debug属性设置为false,否则因为有调试信息产生会影响系统性能,urule.debug属性设置为false后,所有的调试信息都将不再输出,包括“打印内容到控制台”的内置动作也不再执行。
更多建议: