67.2. 持久性审计日志
流程引擎可以存储关于进程实例执行的信息,包括实例的连续历史状态。
很多情况下,这些信息很有用。例如,您可能希望验证已为特定进程实例执行哪些操作,或监控和分析特定进程的效率。
但是,在运行时数据库中存储历史记录信息会导致数据库迅速增加的大小,并会影响到持久层的性能。因此,历史记录日志信息会单独存储。
进程引擎基于进程在执行过程中生成的事件创建日志。它使用事件监听程序机制接收事件并提取必要的信息,然后将此信息保留在数据库中。jbpm-audit 模块包含一个事件监听程序,它利用 JPA 在数据库中存储与进程相关的信息。
您可以使用过滤器来限制日志信息的范围。
67.2.1. 进程引擎审计日志数据模型 复制链接链接已复制到粘贴板!
您可以查询进程引擎审计日志的日志信息,以便在不同的情况下使用它,例如为一个特定的进程实例创建历史记录日志,或分析特定进程的所有实例的性能。
审计日志数据模型是默认的实现。根据您的用例,您还可以定义自己的数据模型来存储所需信息。您可以使用进程事件监听程序来提取信息。
数据模型包含三个实体:一个用于处理实例信息,一个用于节点实例信息,一个用于处理变量实例信息。
ProcessInstanceLog 表包含有关进程实例的基本日志信息。
| 字段 | 描述 | nullable |
|---|---|---|
|
| 日志实体的主密钥和 ID | 不是 NULL |
|
| 此进程实例的关联 | |
|
| 自从开始日期开始以来,此进程实例的实际持续时间 | |
|
| 适用时,进程实例的结束日期 | |
|
| 用于与一些元素关联的可选外部标识符,如部署 ID | |
|
| 启动进程实例的用户的可选标识符 | |
|
| 进程实例的结果。如果进程实例完成并带有错误事件,则此字段包含错误代码。 | |
|
| 父进程实例的进程实例 ID(如果适用) | |
|
| 进程的 ID | |
|
| 进程实例 ID | 不是 NULL |
|
| 进程的名称 | |
|
| 实例的类型(处理或问题单) | |
|
| 进程的版本 | |
|
| 根据服务级别协议(SLA)的到期日期 | |
|
| SLA 合规级别 | |
|
| 进程实例的开始日期 | |
|
| 映射到进程实例状态的进程实例的状态 |
NodeInstanceLog 表包含有关各个进程实例内执行哪些节点的更多信息。每当从其进入的连接中输入某个节点实例时,或通过其中一个传出连接退出,则有关该事件的信息都会存储在此表中。
| 字段 | 描述 | nullable |
|---|---|---|
|
| 日志实体的主密钥和 ID | 不是 NULL |
|
| 导致此节点实例的序列流的实际识别符 | |
|
| 事件的日期 | |
|
| 用于与一些元素关联的可选外部标识符,如部署 ID | |
|
| 进程定义中对应节点的节点 ID | |
|
| 节点实例 ID | |
|
| 节点的名称 | |
|
| 节点的类型 | |
|
| 进程实例正在执行的进程 ID | |
|
| 进程实例 ID | 不是 NULL |
|
| 根据服务级别协议(SLA)的到期日期。 | |
|
| SLA 合规级别 | |
|
| 事件的类型(0 = enter, 1 = exit) | 不是 NULL |
|
| (可选,仅适用于某些节点类型)工作项目的标识符 | |
|
| 容器的标识符,如果节点位于嵌入式子进程节点中 | |
|
| 引用标识符 | |
|
| 如果节点是调度的事件类型,则原始节点实例 ID 和作业 ID。您可以使用这些信息再次触发作业。 |
VariableInstanceLog 表包含有关变量实例中更改的信息。默认情况下,进程引擎在变量更改其值后生成日志条目。流程引擎也可以在更改之前记录条目。
| 字段 | 描述 | nullable |
|---|---|---|
|
| 日志实体的主密钥和 ID | 不是 NULL |
|
| 用于与一些元素关联的可选外部标识符,如部署 ID | |
|
| 事件的日期 | |
|
| 进程实例正在执行的进程 ID | |
|
| 进程实例 ID | 不是 NULL |
|
| 在日志进行时,之前变量的值 | |
|
| 在日志进行时,变量的值 | |
|
| 进程定义中的变量 ID | |
|
| 变量实例的 ID |
AuditTaskImpl 表包含有关用户任务的信息。
| 字段 | 描述 | nullable |
|---|---|---|
|
| 任务日志实体的主键和 ID | |
|
| 激活此任务的时间 | |
|
| 分配给此任务的实际所有者。仅当所有者声明任务时才会设置这个值。 | |
|
| 创建此任务的用户 | |
|
| 任务创建日期 | |
|
| 此任务所属的部署的 ID | |
|
| 任务的描述 | |
|
| 由于在此任务上设置的日期 | |
|
| 任务的名称 | |
|
| 父任务 ID | |
|
| 任务的优先级 | |
|
| 此任务所属的进程定义 ID | |
|
| 与这个任务关联的进程实例 ID | |
|
| 用于创建此任务的 KIE 会话 ID | |
|
| 任务的当前状态 | |
|
| 任务标识符 | |
|
| 在进程中分配给这个任务 ID 的工作项目的标识符 | |
|
| 进程实例状态最后在持久性数据库中记录的日期和时间 |
BAMTaskSummary 表收集有关 BAM 引擎用于构建 chart 和仪表板的任务的信息。
| 字段 | 描述 | nullable |
|---|---|---|
|
| 日志实体的主密钥和 ID | 不是 NULL |
|
| 任务创建日期 | |
|
| 任务创建的时间 | |
|
| 任务到达最终状态时的日期(完成、退出、失败、跳过) | |
|
| 进程实例 ID | |
|
| 任务启动时的日期 | |
|
| 任务的当前状态 | |
|
| 任务标识符 | |
|
| 任务的名称 | |
|
| 分配给任务的用户 ID | |
|
| 作为 optimistic 锁定值的 version 字段 |
TaskVariableImpl 表包含有关任务变量实例的信息。
| 字段 | 描述 | nullable |
|---|---|---|
|
| 日志实体的主密钥和 ID | 不是 NULL |
|
| 最近修改变量的日期 | |
|
| 任务的名称 | |
|
| 进程实例正在执行的进程 ID | |
|
| 进程实例 ID | |
|
| 任务标识符 | |
|
| 变量的类型:任务的输入或输出 | |
|
| 变量值 |
TaskEvent 表包含有关任务实例中更改的信息。声明、 等操作存储在此表中,以提供给定任务发生的事件的时间表视图。
启动和停止
| 字段 | 描述 | nullable |
|---|---|---|
|
| 日志实体的主密钥和 ID | 不是 NULL |
|
| 保存此事件的日期 | |
|
| 事件日志信息 | |
|
| 进程实例 ID | |
|
| 任务标识符 | |
|
| 事件类型。类型与任务的生命周期阶段对应 | |
|
| 分配给任务的用户 ID | |
|
| 为任务分配的工作项目的标识符 | |
|
| 作为 optimistic 锁定值的 version 字段 | |
|
| 进程实例的关联密钥 | |
|
| 进程实例的类型(进程或问题单) | |
|
| 任务的当前所有者 |
67.2.2. 用于将进程事件日志存储在数据库中的配置 复制链接链接已复制到粘贴板!
要使用默认数据模型在数据库中记录进程历史记录信息,您必须在您的会话中注册日志记录器。
在 KIE 会话中注册日志记录器
KieSession ksession = ...; ksession.addProcessEventListener(AuditLoggerFactory.newInstance(Type.JPA, ksession, null)); // invoke methods for your session here
KieSession ksession = ...;
ksession.addProcessEventListener(AuditLoggerFactory.newInstance(Type.JPA, ksession, null));
// invoke methods for your session here
要指定存储信息的数据库,您必须修改 persistence.xml 文件,使其包含审计日志类: ProcessInstanceLog、NodeInstanceLog 和 VariableInstanceLog。
修改后的 persistence.xml 文件,其中包括审计日志类
67.2.3. 将进程事件日志发送到 JMS 队列的配置 复制链接链接已复制到粘贴板!
当进程引擎以默认审计日志实施的形式将事件存储在数据库中时,数据库操作会异步完成(与进程实例的实际执行相同)。此操作需要时间,在高度加载的系统上可能会对数据库性能造成一些影响,特别是当历史记录日志和运行时数据都存储在同一数据库中时。
作为替代方案,您也可以使用流程引擎提供的基于 JMS 的日志记录器。您可以将此日志记录器配置为将进程日志条目作为消息提交到 JMS 队列,而不是直接将它们保留在数据库中。
您可以将 JMS 日志记录器配置为事务性,以避免在处理引擎事务回滚时数据不一致。
使用 JMS 审计日志记录器
这只是配置 JMS 审计日志记录器的可能方法之一。您可以使用 AuditLoggerFactory 类来设置额外的配置参数。
67.2.4. 审核变量 复制链接链接已复制到粘贴板!
默认情况下,进程和任务变量的值以字符串表示形式存储在审计表中。要创建非字符串变量类型的字符串,进程引擎调用 variable.toString() 方法。如果将自定义类用于变量,您可以为类实施此方法。在很多情况下,这代表已经足够。
但是,有时日志中的字符串表示可能不足,特别是在需要按进程或任务变量进行有效查询时。例如,Person 对象用作变量的值,其结构可能如下:
Person 对象示例,用作进程或任务变量值
toString() 方法提供人类可读的格式。但是,搜索可能不足。示例字符串值为 Person [name="john", age="34"]。通过大量搜索字符串来查找年龄 34 的人会使数据库查询效率低下。
要启用更有效的搜索,您可以使用 VariableIndexer 对象审核变量,这会提取审计日志中存储的变量的相关部分。
VariableIndexer 接口的定义
默认索引器使用 toString() 方法为单个变量生成单个审计条目。其他索引器可以从索引单个变量返回对象列表。
要启用对 Person 类型的有效查询,您可以构建将 Person 实例索引到单独的审计条目中的自定义索引程序,一个用于代表该年龄。
Person 类型的索引程序示例
进程引擎可在 Person 类型时使用此索引器索引值,而所有其他变量则以默认 到String() 方法进行索引。现在,要查询指向年龄 34 人的进程实例或任务,您可以使用以下查询:
-
变量名称:
person.age -
变量值:
34
因为没有使用 LIKE 类型查询,数据库服务器可以优化查询,并使其在大量数据上高效。
自定义索引器
进程引擎支持处理和任务变量的索引器。但是,它将不同的接口用于索引器,因为它们必须生成代表 变量审计视图的不同类型的对象。
您必须实施以下接口来构建自定义索引器:
-
对于进程变量:
org.kie.internal.process.ProcessVariableIndexer -
对于任务变量:
org.kie.internal.task.api.TaskVariableIndexer
您必须对以下任意接口实施两种方法:
-
accept:指示某个类型是否由此索引程序处理。进程引擎期望只有一个索引程序可以索引给定变量值,因此它会使用接受该类型的第一个索引器。 -
索引:索引值,生成对象或对象列表(通常是字符串)以包含在审计日志中。
在实施接口后,您必须将此实施打包为 JAR 文件,并在以下其中一个文件中列出实施:
-
对于进程变量,
META-INF/services/org.kie.internal.process.Process.ProcessVariableIndexer文件,列出进程变量索引器(每行单类名)的完全限定类名称。 -
对于任务变量,
META-INF/services/org.kie.internal.task.api.TaskVariableIndexer文件,它列出了任务变量索引器(每行单类名称)
ServiceLoader 机制使用这些文件发现索引器。当索引进程或任务变量时,进程引擎会检查注册的索引器以查找接受变量值的索引程序。如果没有其他索引程序接受值,则进程引擎将使用 toString() 方法应用默认的索引程序。