Audit

Note

Available only in the Enterprise version.

Audit (event log) is designed for maintaining log files where system events are recorded, namely:

  • Search records

  • Get record attributes by their ID

  • Modify attributes or create a new record

  • Delete records

An event record contains a set of information about the event specified in the settings.

The main audit logic is located in the ecos-audit-lib library: https://gitlab.citeck.ru/citeck-projects/ecos-audit-lib

Audit in Citeck is configured via Spring configuration.

Configuration prefix: ecos.webapp.audit

Available settings

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> // исключить обработку событий из этого списка

Note

Templates are supported in includes and excludes for types. The event type is split by “.” into words and then matched against includes and excludes. If the symbol ‘#’ is encountered in the settings, it means “any number of words including 0”, the symbol ‘*’ means - one any word.

AuthorityFilter

includes: List<String> // обрабатывать только события от пользователей, ролей и/или групп из этого списка
excludes: List<String> // исключать события от пользователей, ролей и/или групп из этого списка
includeSystem: Boolean // фиксировать действия системы. По умолчанию false

Configuration example

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

Configuration

Description

rabbitmq

Send events to RabbitMQ on exchange “ecos-audit” with RoutingKey == {event_type}

log

Output events to the microservice log

Event types:

type

Fields

Headers

Description

records.query-records


sourceId: String
query: RecordsQuery
records: List<EntityRef>
attributes: Map<String, String>

sourceId: String
appName: String
appInstanceId: String

Search records

records.get-records-atts


sourceId: String
record: EntityRef
attributes: Map<String, String>

sourceId: String
appName: String
appInstanceId: String

Get record attributes by their ID

records.mutate-record


sourceId: String,
record: EntityRef,
attributes: ObjectData,
attsToLoad: Map<String, String>

sourceId: String
appName: String
appInstanceId: String

Modify attributes or create a new record

records.delete-records


sourceId: String
records: List<EntityRef>

sourceId: String
appName: String
appInstanceId: String

Delete records

General event view

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 // класс ошибки

Audit description

Audit event model

  • id: UUID // unique event identifier. Automatically generated for each event.

  • type: String // event type

  • user: String // user

  • admin: Boolean // flag defining whether the user is an administrator

  • client: ClientInfo // client information. Currently one field inside - ip: String

  • time: String // ISO8601 event time

  • success: Boolean // whether the action completed successfully or not

  • actionTimeMs: Long // action execution time in milliseconds

  • error: ErrorInfo // error information. Present only if success == false. Description of this structure is below.

  • data: Map<String, Object> // event data. Each event type has its own data set. A list of data by event type will be provided below.

  • appName: String // name of the application where the event occurred

  • appInstanceId: String // application instance where the event occurred

ErrorInfo model

  • message: String // error text. Can be formed arbitrarily and directly depends on the code section where this error occurred. If it is necessary to process and catch certain types of errors, a list of such errors should be formed and a refinement should be made.

  • javaClass: String // java error class. Like message, it can be anything, but tied to existing classes in the system.

Event types

records.query-records

Data in the data field:

  • sourceId: String // Data source identifier. It can be used to group or filter all operations (read, modify, create, delete) in a specific data source.

  • query: RecordsQuery // Search query for data (records) in the data source.

  • records: List<EntityRef> // List of records returned as a result of the query. EntityRef description

  • attributes: Map<String, String> // List of attributes that the client requested from the records in the records list.

records.get-records-atts

Data in the data field:

  • sourceId: String // Data source identifier. It can be used to group or filter all operations (read, modify, create, delete) in a specific data source. sourceId is always part of the record and if a separate field for filtering and grouping query/get-atts/mutate/delete actions is not required, then sourceId can be removed from the event.

  • record: EntityRef // Reference to a record in the data source. EntityRef description

  • attributes: Map<String, String> // Attributes that we request from the record

records.mutate-record

Data in the data field:

  • sourceId: String // Data source identifier. It can be used to group or filter all operations (read, modify, create, delete) in a specific data source. sourceId is always part of the record and if a separate field for filtering and grouping query/get-atts/mutate/delete actions is not required, then sourceId can be removed from the event.

  • record: EntityRef // Reference to a record in the data source. If the record looks like "{{appName}}/{{sourceId}}@" (i.e., there is nothing after the @ sign), then it means a request to create a new entity has been received. EntityRef description

  • attributes: Map<String, Object> // Attributes sent from the client for updating. I.e., if in attributes we see {“field0”: “field1”}, it means the client is trying to change the field “field0” by assigning it the value “field1”.

  • attsToLoad: Map<String, String> // Attributes to load after mutation. In some cases, the client sends in the request, in addition to the attributes to be changed, also attributes that should be loaded from the record after successful completion of the mutation.

records.delete-records

Data in the data field:

  • sourceId: String // Data source identifier. It can be used to group or filter all operations (read, modify, create, delete) in a specific data source. sourceId is always part of each element in records and if a separate field for filtering and grouping query/get-atts/mutate/delete actions is not required, then sourceId can be removed from the event.

  • records: List<EntityRef> // List of records to delete. EntityRef description

EntityRef description

  • EntityRef is a unique entity identifier in the Citeck system. It is formed according to the following template:

    {{appName}}/{{sourceId}}@{{localId}}

  • appName - the name of the application where the data source is located (see the appName field in the event model). Examples of applications: uiserv, emodel, integrations, etc.

  • sourceId - this is the data source identifier within the application (see the sourceId field)

  • localId - this is the local entity identifier within the data source. The absence of localId for mutation means creating a new record.

Description of attributes for loading

Attributes for loading can look like this:

{
  "name": "name?disp",
  "counterparty": "counterparty.fullOrgName?str"
}

This attribute format is part of the Records API (on which all communication in Citeck is built).

In RecordsAPI, the client can request attributes by specifying a complex nested structure, but for audit, mainly only the keys in this map are useful.

That is, from the example above, we can get information that the client requested two attributes - “name” and “counterparty”

More about Records API