Конфигурация истории
|
Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine |
Выбор уровня истории
Уровень истории контролирует количество данных, предоставляемых движком управления процессами через поток событий истории. Следующие настройки доступны из коробки:
-
NONE: не выбрасываются никакие события истории. -
ACTIVITY: выбрасываются следующие события:-
START, UPDATE, END, MIGRATE для экземпляра процесса: выбрасываются, когда экземпляры процессов стартуют, обновляются, заканчиваются и мигрируют
-
CREATE, UPDATE, CLOSE для экземпляра сценария: выбрасываются, когда экземпляры сценариев создаются, обновляются и закрываются
-
START, UPDATE, END, MIGRATE для экземпляров активностей: выбрасываются, когда экземпляры активностей стартуют, обновляются, заканчиваются и мигрируют
-
CREATE, UPDATE, END для экземпляров активностей сценариев: выбрасываются, когда активности сценариев создаются, обновляются и заканчиваются
-
CREATE, UPDATE, COMPLETE, DELETE, MIGRATE для экземпляра задачи: выбрасывается, когда экземпляры задач создаются, обновляются (например, переназначаются, делегируются и т.д.), завершаются, удаляются или мигрируют
-
-
AUDIT: в дополнение к событиям, доступным на уровне историиACTIVITY, выбрасываются следующие события:-
CREATE, UPDATE, DELETE, MIGRATE для экземпляра переменной: выбрасываются, когда процессные переменные создаются, обновляются, удаляются или мигрируют. Бэкенд истории по умолчанию (
DbHistoryEventHandler) сохраняет события, относящиеся к экземпляру переменной, в таблицу базы данных, где хранятся экземпляры исторических переменных. Записи в этой таблице обновляются по мере того, как обновляются экземпляры переменных, что означает, что в конце концов будет доступно только последнее значение процессной переменной
-
-
FULL: в дополнение к событиям, доступном на уровне историиAUDIT, выбрасываются следующие события:-
UPDATE для свойства формы: выбрасывается]6 когда создаются или обновляются свойства форм
-
Бэкенд истории по умолчанию (
DbHistoryEventHandler) сохраняет обновления исторических переменных в базе данных. Это позволяет инспектировать промежуточные значения, используя сервис истории -
UPDATE для лога пользовательских операций: выбрасывается, когда пользователь выполняет операцию, например, запрос на пользовательскую задачу, делегирование пользовательской задачи и т.д.
-
CREATE, DELETE, RESOLVE, MIGRATE для инцидента: выбрасывается, когда инциденты создаются, удаляются, разрешаются или мигрируют
-
CREATE, FAILED, SUCCESSFUL, DELETED для лога исторических джоб: выбрасывается, когда джобы создаются, когда выполнение джобы заканчивается неудачей лбо успехом или когда джоба удаляется
-
Decision Instance EVALUATE: fired when a decision is evaluated by the DMN engine
-
START, END для Batch: выбрасываются, когда batch-и стартуют или заканчиваются
-
ADD, DELETE для связей между идентичностями: выбрасывается, когда связь между идентичностями (identity link) добавляется, удаляется или когда назначенный исполнитель пользовательской задачи устанавливается или меняется, а также когда владелец пользовательской задачи устанавливается или меняется
-
CREATED, DELETED, FAILED, SUCCESSFUL для лога исторических внешних задач: выбрасывается, когда историческая задача создается, удаляется, либо когда призодит отчет о выполнении внешней задачи, закончившемся неудачей или успехом
-
-
AUTO: уровеньautoполезен, если вы планируете запускать несколько движков на одной и той же базе данных. В этом случае все движки должны использовать один уровень истории. Вместо того, чтобы вручную поддерживать все конфишгурации в состоянии синхронизации, вы можете использовать уровеньauto, и движок автоматически определит уровень, уже сконфигурированный в базе данных. Если никакой уровень не найден, используется значение по умолчанию,audit. Помните: если вы планируете использовать кастомизированные уровни истории, вам придется регистрировать эти кастомизированные уровни во всех конфигурациях, иначе будет выбрасываться исключение.
Если вам необходимо кастомизироват количество логируемых уровней истории, вы можете предоставить кастомизированную реализацию {{< javadocref page="org/camunda/bpm/engine/impl/history/producer/HistoryEventProducer.html" text="HistoryEventProducer" >}} и подключить ее к конфигурации движка управления процессами.
В случае особых потребностей вы также можете создать кастомизированный уровень истории.
Установка уровня истории
Уровень истории может предоставляться как свойство в конфигурации движка управления процессами. В зависимости от того, как сконфигурирован движок, свойство можно устанавливать с использованием кода на Java:
ProcessEngine processEngine = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResourceDefault()
.setHistory(ProcessEngineConfiguration.HISTORY_FULL)
.buildProcessEngine();
Его также можно устанавливать с использованием Spring XML или дескриптора деплоймента (bpm-platform.xml, processes.xml). При использовании Camunda Wildfly Subsystem это свойство может быть установлено через конфигурацию Wildfly configuration (standalone.xml, domain.xml).
<property name="history">audit</property>
ОБратите внимание, что при использовании бэкенда истории по умолчанию уровень истории сохраняется в базе данных и не может быть изменен позднее.
УРОВНИ ИСТОРИИ И COCKPIT: веб приложение Camunda Cockpit лчше всего работает с уровнем истории, установленным в значение FULL. "Более низкие" уровни истории отключают некоторые возможности, относящиеся к истории.
Реализация истории по умолчанию
База данных, используемая для истории по умолчанию, записывает события истории в подходящие таблицы базы данных. Затем появляется возможность отправлять запросы, используя HistoryService или REST API.
Сущности истории
Существуют следующие сущности истории, которые, по контрасту с данными рантайма, останутся в базе данных после того, как экземпляры процесса или сценария закончат работу:
-
HistoricProcessInstancesсодержит информацию о текущем и прошлых экземплярах процесса. -
HistoricVariableInstancesсодержит информацию о последнем состоянии переменной, содержащейся в экземпляре процесса. -
HistoricCaseInstancesсодержит информацию о текущем и прошлых экземплярах сценария. -
HistoricActivityInstancesсодержит информацию об одном выполнении активности. -
HistoricCaseActivityInstancesсодержит информацию об одном выполнении активности в сценарии. -
HistoricTaskInstancesсодержит информацию о текущем и прошлых (завершенных и удаленных) экземплярах задачи. -
HistoricDetailsсодержит различные виды информации, относящиеся либо к экземплярам исторических процессов, либо к экземплярам активностей, либо к экземплярам задач. -
HistoricIncidentsсодержит информацию о текущем и прошлых (то есть, удаленных или разрешенных) инцидентах. -
UserOperationLogEntryвхождение лога, содержащее информацию об операции, выполненной пользователем. Используется для действий логирования, например, создания задачи, завершения задачи и т.д. -
HistoricJobLogсодержит информацию о выполнении джоб. Лог предоставляет подробную информацию о жизненном цикле джобы. -
HistoricDecisionInstanceсодержит информацию об одной оценке решения, включая входные и выходные значения. -
HistoricBatchсодержит информацию о текущем и прошлых batch-ах. -
HistoricIdentityLinkLogсодержит информацию о текущей и прошлых (добавленных, удаленных, установлен или изменен исполнитель, установлен или изменен владелец) связях идентичностей. -
HistoricExternalTaskLogсодержит информацию о внешнем логе. Лог предоставляет подробную информацию о жизненном цикле внешней задачи.
Состояние HistoricProcessInstances
Для каждого экземпляра процесса движок управления процессами создает одну запись в базе данных истории и продолжает обновлять эту запись во время выполнения процесса. Каждая запись HistoricProcessInstance может получить одно из перечисленных состояний:
-
ACTIVE — работающий экземпляр процесса
-
SUSPENDED — приостановленный экземпляр процесса
-
COMPLETED — завершен через нормальное событие
-
EXTERNALLY_TERMINATED — остановлен извне, например, через REST API
-
INTERNALLY_TERMINATED — остановлен изнутри, например, через останавливающее пограничное событие
Следующие из приведенных состояний могут быть установлены извне, например через REST API или Cockpit: ACTIVE, SUSPENDED, EXTERNALLY_TERMINATED.
Отправка запросов к истории
HistoryService выставляет наружу следующие методы: createHistoricProcessInstanceQuery(), createHistoricVariableInstanceQuery(), createHistoricCaseInstanceQuery(), createHistoricActivityInstanceQuery(), createHistoricCaseActivityInstanceQuery(),createHistoricDetailQuery(), createHistoricTaskInstanceQuery(), createHistoricIncidentQuery(), createUserOperationLogQuery(), createHistoricJobLogQuery(), createHistoricDecisionInstanceQuery(), createHistoricBatchQuery(), createHistoricExternalTaskLogQuery и createHistoricIdentityLinkLogQuery(). Эти методы могут использоваться для отправки запросов к истории.
Ниже приведено несколько примеров, которые показывают некоторые возможности по отправке API-запросов к истории. Полное описание таких возможностей можно найти в Javadocs, в пакете io.openbpm.bpm.engine.history.
HistoricProcessInstanceQuery
Получить десять HistoricProcessInstances, которые уже завершены и заняли максимальное время на выполнение (самая длинная продолжительность) среди всех завершенных процессов с определением 'XXX'.
historyService.createHistoricProcessInstanceQuery()
.finished()
.processDefinitionId("XXX")
.orderByProcessInstanceDuration().desc()
.listPage(0, 10);
HistoricCaseInstanceQuery
Получить десять HistoricCaseInstances, которые уже закрыты и потребовали больше всего времени для закрытия (самая длинная продолжительность) среди всех закрытых сценариев с определением 'XXX'.
historyService.createHistoricCaseInstanceQuery()
.closed()
.caseDefinitionId("XXX")
.orderByCaseInstanceDuration().desc()
.listPage(0, 10);
HistoricActivityInstanceQuery
Получить последний HistoricActivityInstance типа 'serviceTask', который была завершен в любом процессе, использующем processDefinition с id, равным 'XXX'.
historyService.createHistoricActivityInstanceQuery()
.activityType("serviceTask")
.processDefinitionId("XXX")
.finished()
.orderByHistoricActivityInstanceEndTime().desc()
.listPage(0, 1);
HistoricCaseActivityInstanceQuery
Получить последний HistoricCaseActivityInstance, который был завершен в любом сценарии, использующем caseDefinition с id, равным 'XXX'.
historyService.createHistoricCaseActivityInstanceQuery()
.caseDefinitionId("XXX")
.finished()
.orderByHistoricCaseActivityInstanceEndTime().desc()
.listPage(0, 1);
HistoricVariableInstanceQuery
Получить все HistoricVariableInstances из завершенного экземпляра процесса с id, равным 'XXX', упроядоченные по имени переменной.
historyService.createHistoricVariableInstanceQuery()
.processInstanceId("XXX")
.orderByVariableName().desc()
.list();
HistoricDetailQuery
В следующем примере мы получаем все обновления переменных, которые произошли в рамках процесса с id равным '123'. Этот запрос возвращает только HistoricVariableUpdates. Обратите внимание, что одно имя переменной может иметь несколько вхождений типа HistoricVariableUpdate, по одному на каждый раз, когда переменная обновлялась внутри процесса. Вы можете упорядочивать их по времени (orderByTime — время обновления переменной) или по ревизии (orderByVariableRevision — ревизия рантайм переменной во время обновления ), чтобы узнать, в каком порядке эти обновления произошли.
historyService.createHistoricDetailQuery()
.variableUpdates()
.processInstanceId("123")
.orderByVariableName().asc()
.list()
Следующим пример получает все обновления переменных, произошедние в задаче с id, равным '123'. Этот запрос возвращает все HistoricVariableUpdates для переменных, которые были кстановлены в задаче (локальные переменные задачи), а НЕ в экземпляре процесса.
historyService.createHistoricDetailQuery()
.variableUpdates()
.taskId("123")
.orderByVariableName().asc()
.list()
HistoricTaskInstanceQuery
Получить десять HistoricTaskInstances, которые уже завершены и потребовали максимальное количество времени (самая длинная продолжительность) из всех задач.
historyService.createHistoricTaskInstanceQuery()
.finished()
.orderByHistoricTaskInstanceDuration().desc()
.listPage(0, 10);
Получиьт HistoricTaskInstances, которые удалены и имеют причину удаления, содержащую слово 'invalid', а также были последними назначенными задачами на пользователя 'jonny'.
historyService.createHistoricTaskInstanceQuery()
.finished()
.taskDeleteReasonLike("%invalid%")
.taskAssignee("jonny")
.listPage(0, 10);
HistoricIncidentQuery
Запрос на получение всех разрешенных инцидентов:
historyService.createHistoricIncidentQuery()
.resolved()
.list();
UserOperationLogQuery
Запрос на получение всех операций, выполненных пользователем 'jonny':
historyService.createUserOperationLogQuery()
.userId("jonny")
.listPage(0, 10);
HistoricJobLogQuery
Запрос на логи успешно отработавших исторических джоб:
historyService.createHistoricJobLogQuery()
.successLog()
.list();
HistoricDecisionInstanceQuery
Получить все HistoricDecisionInstances из решения с ключом 'checkOrder', упорядоченные по времени, когда решение было оценено.
historyService.createHistoricDecisionInstanceQuery()
.decisionDefinitionKey("checkOrder")
.orderByEvaluationTime()
.asc()
.list();
Получить все HistoricDecisionInstances из решений, которые были оценены во время выполнения экземпляра процесса с id равным 'XXX'. HistoricDecisionInstances содержит входные значения, на которых оценивалось решение, и выходные значения выполненных правил.
historyService.createHistoricDecisionInstanceQuery()
.processInstanceId("XXX")
.includeInputs()
.includeOutputs()
.list();
HistoricBatchQuery
Получить все batch-и миграции исторических процессов, упорядоченные по id.
historyService.createHistoricBatchQuery()
.type(Batch.TYPE_PROCESS_INSTANCE_MIGRATION)
.orderById().desc()
.list();
HistoricIdentityLinkLogQuery
Запрос на все связи идентичностей, которые относятся к пользователю 'demo'.
historyService.createHistoricIdentityLinkLogQuery()
.userId("demo")
.list();
HistoricExternalTaskLogQuery
Запрос на логи исторических неудачно завершенных внешних задач:
historyService.createHistoricExternalTaskLogQuery()
.failureLog()
.list();
Отчет по истории
Вы можете использовать разделы в отчетах, чтобы извлечь кастомизированную статистику и отчеты. В настоящий момент мы поддерживаем следующие виды отчетов:
-
Отчет о продолжительности работы экземпляров link:{{< relref "#instance-duration-report" >}}[]
-
Отчет по задачам link:{{< relref "#task-report" >}}[]
-
Отчет по завершенным экземплярам link:{{< relref "#finished-instance-report" >}}[]
Отчет о продолжительности работы экземпляров (Instance duration report)
Извлекает отчет о продолжительности завершившихся экземпляров процессов, сгруппированных по заданному периоду. Эти отчеты включают максимальную, минимальную и среднюю продолжительность среди всех завершенных экземпляров процессов, которые стартовали в пределах заданного периода. Приведенный фрагмент кода извлекает отчет за каждый месяц с момента запуска движка:
historyService
.createHistoricProcessInstanceReport()
.duration(PeriodUnit.MONTH);
На данный момент поддерживемыми периодами являются MONTH и QUARTER из io.openbpm.bpm.engine.query.PeriodUnit.
Чтобы сделать запрос на отчет более точным, можно использовать следующие методы из HistoricProcessInstanceReport:
-
startedBefore: принимает во внимание только те исторические экземпляры процессов, которые стартовали до заданной даты. -
startedAfter: принимает во внимание только те исторические экземпляры процессов, которые стартовали после заданной даты. -
processDefinitionIdIn: Принимает во внимание только те исторические процессы, для которых id определений совпадают с заданными. -
processDefinitionKeyIn: Принимает во внимание только те исторические процессы, для которых ключи определений совпадают с заданными.
Здесь startedBefore и startedAfter используют объекты типоы java.util.Date (deprecated) или java.util.Calendar для входных данных.
Например, можно составить запрос на все экземпляры исторических процессов, которые стартовали до настоящего момента, и получить их продолжительность:
Calendar calendar = Calendar.getInstance();
historyService.createHistoricProcessInstanceReport()
.startedBefore(calendar.getTime())
.duration(PeriodUnit.MONTH);
Отчет о задачах (Task report)
Извлекает отчет по завершенным задачам. Для отчета по задачам существует два допустимых типа: count (количество) и duration (продолжительность).
Если вы используете метод countByProcessDefinitionKey или countByTaskName в конце вашего запроса на отчет, то отчет будет содержать список количеств завершенных задач, где каждое вхождение содержит имя задачи, ключ определения задачи, id определения процесса, ключ определения процесса, имя определения процесса и подсчитанное количество задач, выполненных для заданного ключа в пределах заданного периода. Методы countByProcessDefinitionKey и countByTaskName затем группируют отчеты о количествах в соответствии с критерием "ключ определения" или "имя задачи". Чтобы извлечь отчет о количествах задач, сгруппированный по имени задачи, можно выполнить следующий запрос:
historyService
.createHistoricTaskInstanceReport()
.countByTaskName();
Если тип отчета установлен в "duration", отчет содержит максимальное, минимальное и среднее значение продолжительности для всех завершенных экземпляров задач за заданный период.
historyService
.createHistoricTaskInstanceReport()
.duration(PeriodUnit.MONTH);
Поддерживаемые периоды времени и ограничения на запросы работают так же, как и для отчета по продолжительности экземпляров link:{{< relref "#instance-duration-report" >}}[].
Отчет о завершенных экземплярах (Finished instance report)
Извлекает отчет по завершенным экземплярам процессов, решений или сценариев. Отчет помогает пользователю производить тонкую настройку времени жизни для определений. Они могут видеть итоговый отчет по историческим данным, который может быть удален после очистки истории. Выходными полями являются id, ключ, имя версия определения, подсчитанное количество завершенных экземпляров и количество экземпляров, доступных для очистки.
historyService
.createHistoricFinishedProcessInstanceReport()
.list();
historyService
.createHistoricFinishedDecisionInstanceReport()
.list();
historyService
.createHistoricFinishedCaseInstanceReport()
.list();
Частичная сортировка событий истории по их появлению
Иногда вам может понадобиться отсортировать события в истории в том порядке, в котором они происходили. Обратите внимание, что временная метка для этой цели не подходит.
Большинство событий истории содержат временную метку (timestamp), которая отмечает точку на временной оси, в которой произошло действие, вызвавшее появление события. Однако, эта временная метка не может, в общем случае, использоваться для сортировки событий истории. Причина этого заключается в том, что двидок управления процессами может работать на нескольких узлах кластеров:
-
на одной машине показания часов могут меняться по причине синхронизации сети в рантайме,
-
в кластере события, происходящие в одном экземпляре процесса, могут генерироваться на разных узлах, между которыми часы могут не быть идеально синхронизированы с точностью до наносекунд.
Чтобы обойти эту проблему, движок Camunda генерирует последовательные номера, которые можно использовать, чтобы частично отсортировать события в истории по их появлению.
На уровне BPMN это означает, что эземпляры обдновременных активностей (пример: активности на различных параллельных ветвях после параллельного шлюза) не могут сравниваться друг с другом. Экземпляры активностей, являющихся частью отношения "происходит-до", на уровне BPMN будут упорядочиваться исходя из этого отношения.
Пример:
List<HistoricActivityInstance> result = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId("someProcessInstanceId")
.orderPartiallyByOccurrence()
.asc()
.list();
Обратите внимание, что возвращенный список экземпляров исторических активностей в примере отсортирован лишь частично, как объяснено выше. Он гарантирует, что связанные друг с другом экземпляры активностей отсортированы по их появлению. Упорядочивание не связанных друг с другом активностей является произвольным и не гарантируется.
Лицензия и атрибуция
Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .
Оригинал документации: https://docs.camunda.org