一.自定义 MDCCommandInvoker 拦截器类 继承 DebugCommandInvoker 重写方法:executeOperation
package interceptor;
import org.activiti.engine.debug.ExecutionTreeUtil;
import org.activiti.engine.impl.agenda.AbstractOperation;
import org.activiti.engine.impl.interceptor.DebugCommandInvoker;
import org.activiti.engine.logging.LogMDC;
/**
* 日志拦截器
*/
public class MDCCommandInvoker extends DebugCommandInvoker{
@Override
public void executeOperation(Runnable runnable) {
boolean mdcEnabled = LogMDC.isMDCEnabled();//取原来的值是否是生效的
LogMDC.setMDCEnabled(true);
if (runnable instanceof AbstractOperation) {
AbstractOperation operation = (AbstractOperation)runnable;
if (operation.getExecution() != null) {
/*logger.info("Execution tree while executing operation {} :", operation.getClass());
logger.info("{}", System.lineSeparator() + ExecutionTreeUtil.buildExecutionTree(operation.getExecution()));*/
LogMDC.putMDCExecution(operation.getExecution());//记录数据
}
}
super.executeOperation(runnable);
LogMDC.clear();//【清理MDC信息】为保证环境的清洁
if(!mdcEnabled){//如果原来的值是不生效的
//把他的值重新还原一下
LogMDC.setMDCEnabled(false);
}
}
}
二.配置 activiti_mdc.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<!--配置自定义的commandInvoker-->
<property name="commandInvoker" ref="commandInvoker"/>
</bean>
<bean id="commandInvoker" class="interceptor.MDCCommandInvoker"/>
</beans>
三.测试
import org.activiti.engine.logging.LogMDC;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class ConfigMDCTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigMDCTest.class);
@Rule
/* public ActivitiRule activitiRule = new ActivitiRule();*///整个流程引擎的启动和创建过程都固定好了
public ActivitiRule activitiRule = new ActivitiRule("activiti_mdc.cfg.xml");
@Test
@Deployment(resources = {"my-process.bpmn20.xml"})//加载流程引擎文件(测试)
public void test() {
//打开MDC记录日志
/*LogMDC.setMDCEnabled(true);*///正常执行是不打印日志
ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
assertNotNull(processInstance);
Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
assertEquals("Activiti is awesome!", task.getName());
activitiRule.getTaskService().complete(task.getId());
}
}
四。执行前提要配置 logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="false" scan="true" scanPeriod="30 seconds" >
<property name="log.dir" value="target/logs" />
<property name="encoding" value="UTF-8"/>
<property name="plain" value="%msg%n"/>
<property name="std" value="%d{HH:mm:ss.SSS}[%thread][%-5level]%msg %X{}"/>
<!--<property name="normal" value="%d{yyy-MM-dd:HH:mm:ss.SSS}[%thread][%-5level]"/>-->
<property name="mdc" value="%d{HH:mm:ss.SSS}[%thread][%-5level]%msg ProcessDefinitionId=%X{mdcProcessDefinitionID}
executionId=%X{mdcExecutionId} mdcProcessInstanceID=%X{mdcProcessInstanceID} mdcBusinessKey=%X{mdcBusinessKey} %logger{10}.%M:%L%n"/>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${catalina.base}/logs/" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<Encoding>UTF-8</Encoding>
<!--<layout class="ch.qos.logback.classic.PatternLayout"> -->
<!-- 格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>-->
<encoder>
<!--<pattern>${plain}</pattern>-->
<pattern>${mdc}</pattern>
<charset>${encoding}</charset>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<Encoding>UTF-8</Encoding>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/JKApp.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
<!--日志异步到数据库 -->
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
<!--日志异步到数据库 -->
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
<!--连接池 -->
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://localhost:3306/ceshi</url>
<user>root</user>
<password>root</password>
<sqlDialect class="ch.qos.logback.core.db.dialect.MySQLDialect" />
</dataSource>
</connectionSource>
</appender>
</configuration>
运行结果: