Аудит
Примечание
Доступно только в Enterprise версии.
Аудит (журнал событий) предназначен для ведения лог-файлов, в которые записываются события системы, а именно:
Поиск записей
Получение атрибутов записей по их ID
Изменение атрибутов или создание новой записи
Удаление записей
Запись о событии содержит заданный в настройках набор информации о событии.
Основная логика аудита располагается в библиотеке ecos-audit-lib: https://gitlab.citeck.ru/citeck-projects/ecos-audit-lib
Аудит в ECOS настраивается через Spring-конфигурацию.
Префикс конфигурации: ecos.webapp.audit
Доступные настройки
enabled: Boolean // включить или выключить аудит. По умолчанию false
pipelines: Map<String, PipelineProps> // конфигурация конвееров
outputs: Map<String, OutputProps> // конфигурация выходов
PipelineProps:
enabled: Boolean // включен или нет конвеер. По умолчанию true
filter: EcosAuditEventFilterProps // настройки фильтрации
processors: List<EcosAuditProcessorProps> // процессоры
outputs: List<String> // выходы
EcosAuditEventFilterProps:
type: TypeFilter // фильтр по типу
authority: AuthorityFilter // фильтр по текущему пользователю
headers: Predicate // фильтр по хидерам. Предикат задается в виде строки.
eventData: Predicate // фильтр по содержимому события. Предикат задается в виде строки.
TypeFilter
includes: List<String> // обрабатывать только события из этого списка
excludes: List<String> // исключить обработку событий из этого списка
Примечание
в includes и excludes для типов поддерживаются шаблоны. Тип события разбивается по символам “.“ на слова и дальше идет сопоставление с includes и excludes. Если в настройках встречается символ #, то он означает “любое количество слов включая 0”, символ * означает - одно любое слово.
AuthorityFilter
includes: List<String> // обрабатывать только события от пользователей, ролей и/или групп из этого списка
excludes: List<String> // исключать события от пользователей, ролей и/или групп из этого списка
includeSystem: Boolean // фиксировать действия системы. По умолчанию false
Пример настройки
ecos:
webapp:
audit:
enabled: true
pipelines:
main:
filter:
type:
includes: [
"records.query-records",
"records.get-records-atts",
"records.mutate-record",
"records.delete-records"
]
headers: |
{"t":"like","att":"sourceId","val":"%-cipher"}
outputs: ["rabbitmq", "log"]
outputs:
rabbitmq:
type: rabbitmq
log:
type: log
type |
Конфигурация |
Описание |
---|---|---|
rabbitmq |
Отправлять события в RabbitMQ на exchange “ecos-audit“ с RoutingKey == {тип_события} |
|
log |
Выводить события в лог микросервиса |
Типы событий:
type |
Поля |
Хидеры |
Описание |
---|---|---|---|
records.query-records |
sourceId: String
query: RecordsQuery
records: List<EntityRef>
attributes: Map<String, String>
|
sourceId: String
appName: String
appInstanceId: String
|
Поиск записей |
records.get-records-atts |
sourceId: String
record: EntityRef
attributes: Map<String, String>
|
sourceId: String
appName: String
appInstanceId: String
|
Получение атрибутов записей по их ID |
records.mutate-record |
sourceId: String,
record: EntityRef,
attributes: ObjectData,
attsToLoad: Map<String, String>
|
sourceId: String
appName: String
appInstanceId: String
|
Изменение атрибутов или создание новой записи |
records.delete-records |
sourceId: String
records: List<EntityRef>
|
sourceId: String
appName: String
appInstanceId: String
|
Удаление записей |
Общий вид события
id: UUID // уникальный идентификатор события
type: String // тип события
user: String // пользователь
admin: Boolean // флаг определяющий является ли пользователь администратором
client: ClientInfo // информация о клиенте. На данный момент одно поле внутри - ip: String
time: String // ISO8601 время события
success: Boolean // успешно или нет выполнилось действие
actionTimeMs: Long // время выполнения действия в миллисекундах
error: ErrorInfo // информация об ошибке. Присутствует только если success == false
data: ObjectData // данные по событию. Для каждого типа событий свой набор данных
appName: String // имя приложения, в котором произошло событие
appInstanceId: String // инстанс приложения, в котором произошло событие
ErrorInfo
message: String // текст ошибки
javaClass: String // класс ошибки
Описание аудита
Модель события аудита
id: UUID // уникальный идентификатор события. Автоматически генерируется для каждого события.
type: String // тип события
user: String // пользователь
admin: Boolean // флаг определяющий является ли пользователь администратором
client: ClientInfo // информация о клиенте. На данный момент одно поле внутри - ip: String
time: String // ISO8601 время события
success: Boolean // успешно или нет выполнилось действие
actionTimeMs: Long // время выполнения действия в миллисекундах
error: ErrorInfo // информация об ошибке. Присутствует только если success == false. Описание этой структуры ниже.
data: Map<String, Object> // данные по событию. Для каждого типа событий свой набор данных. Ниже будет список данных по типу события.
appName: String // имя приложения, в котором произошло событие
appInstanceId: String // инстанс приложения, в котором произошло событие
Модель ErrorInfo
message: String // текст ошибки. Может формироваться произвольным образом и напрямую зависит от участка кода где эта ошибка возникла. Если нужно обрабатывать и отлавливать определенные типы ошибок, то следует сформировать список таких ошибок и сделать доработку.
javaClass: String // java класс ошибки. Так же как и message может быть любым, но с привязкой к существующим классам в системе.
Типы событий
records.query-records
Данные в поле data:
sourceId: String // Идентификатор источника данных. По нему можно сгруппировать или отфильтровать все операции (чтение, изменение, создание, удаление) в определенном источнике данных.
query: RecordsQuery // Поисковый запрос за данными (записями) в источнике данных.
records: List<EntityRef> // Список записей, который вернулись в результате запроса. Описание EntityRef
attributes: Map<String, String> // Список атрибутов, которые клиент запросил у записей из списка records.
records.get-records-atts
Данные в поле data:
sourceId: String // Идентификатор источника данных. По нему можно сгруппировать или отфильтровать все операции (чтение, изменение, создание, удаление) в определенном источнике данных. sourceId всегда является частью record и если отдельное поле для фильтрации и группировки query/get-atts/mutate/delete
действий не требуется, то можно sourceId убрать из события.
record: EntityRef // Ссылка на запись в источнике данных. Описание EntityRef
attributes: Map<String, String> // Атрибуты, которые мы запрашиваем у записи
records.mutate-record
Данные в поле data:
sourceId: String // Идентификатор источника данных. По нему можно сгруппировать или отфильтровать все операции (чтение, изменение, создание, удаление) в определенном источнике данных. sourceId всегда является частью record и если отдельное поле для фильтрации и группировки query/get-atts/mutate/delete
действий не требуется, то можно sourceId убрать из события.
record: EntityRef // Ссылка на запись в источнике данных. Если record имеет вид "{{appName}}/{{sourceId}}@"
(т.е. после знака @ ничего нет), то это означает, что пришел запрос на создание новой сущности. Описание EntityRef
attributes: Map<String, Object> // Атрибуты, которые отправлены от клиента для обновления. Т.е. если в attributes мы видим {«field0»: «field1»}, то это означает, что клиент пытается изменить поле «field0» присвоив ему значение «field1».
attsToLoad: Map<String, String> // Атрибуты для загрузки после мутации. В ряде случаев клиент отправляет в запросе помимо атрибутов, которые следует изменить так же и атрибуты, которые следует загрузить из записи после успешного окончания мутации.
records.delete-records
Данные в поле data:
sourceId: String // Идентификатор источника данных. По нему можно сгруппировать или отфильтровать все операции (чтение, изменение, создание, удаление) в определенном источнике данных. sourceId всегда является частью каждого элемента в records и если отдельное поле для фильтрации и группировки query/get-atts/mutate/delete действий не требуется, то можно sourceId убрать из события.
records: List<EntityRef> // Список записей для удаления. Описание EntityRef
Описание EntityRef
EntityRef - это уникальный идентификатор сущности в системе ECOS. Он формируется по следующему шаблону:
{{appName}}/{{sourceId}}@{{localId}}
appName - имя приложения где располагается источник данных (см. поле appName в модели события). Примеры приложений: uiserv, emodel, integrations и т.д.
sourceId - это идентификатор источника данных в пределах приложения (см. поле sourceId)
localId - это локальный идентификатор сущности в пределах источника данных. Отсутствие localId для мутации означает создание новой записи.
Описание атрибутов для загрузки
Атрибуты для загрузки могут иметь следующий вид:
{
"name": "name?disp",
"counterparty": "counterparty.fullOrgName?str"
}
Подобный формат атрибутов - это часть Records API (на базе которого строится все общение в ECOS).
В RecordsAPI клиент может запросить атрибуты, указав сложную вложенную струтуру, но для аудита в основном полезны только ключи в этой мапе.
То есть из примера выше мы можем получить информацию о том, что клиент запросил два атрибута - «name» и «counterparty»
Подробнее про Records API