1. Общие сведения о программе

1.1. Назначение программы

Национальная система управления данными (далее – НСУД) представляет собой систему, состоящую из взаимосвязанных элементов информационно-технологического, организационного, методологического, кадрового и нормативно-правового характера и обеспечивающую достижение целей и выполнение задач, обозначенных в Концепции Национальной системы управления данными, утвержденной распоряжением Правительства Российской Федерации от 3 июня 2019 года № 1189-р.

НСУД предназначена для управления информацией, содержащейся в информационных системах органов и организаций государственного сектора, а также в информационных ресурсах, созданных в целях реализации полномочий органов и организаций государственного сектора (далее – государственные данные) и для осуществления информационного обмена между Поставщиками и Получателями данных, присоединившимися к НСУД (далее – Участники НСУД).

Управление процессами информационного обмена между Участниками НСУД осуществляется средствами федеральной государственной информационной системы «Единая информационная платформа Национальной системы управления данными» (далее – ФГИС «ЕИП НСУД»).

Для передачи данных между Участниками НСУД используется среда взаимодействия НСУД, состоящая из Системы межведомственного электронного взаимодействия 3.0 (далее – СМЭВ) и (или) подсистемы обеспечения доступа к данным СМЭВ (далее – ПОДД СМЭВ) (СМЭВ 4.0), обеспечивающих транспорт и процессинг данных, а также агентов ПОДД СМЭВ, устанавливаемых на стороне Участников НСУД.

Для формирования и (или) для получения данных с использованием среды взаимодействия НСУД необходим комплекс программных и технических средств в составе информационно-телекоммуникационной инфраструктуры участника НСУД, описываемое в данном документе «Витрина данных НСУД», но возможно и применение «Витрина данных НСУД»). Данный документ описывает применение именно ПО среды взаимодействия НСУД.

Программа «Витрина данных НСУД» является частью НСУД и предназначена для загрузки публикуемых данных в отдельную БД на стороне Поставщика данных. Программа представляет собой типовое программное обеспечение, устанавливаемое на стороне поставщиков/потребителей данных.

1.2. Возможности программы

Программа обеспечивает выполнение следующих задач:

  • описание логической модели данных;

  • настройка программы и структуры таблиц в ее БД для хранения публикуемых данных;

  • загрузка и хранение публикуемых данных в БД программы;

  • извлечение данных из внешних систем (внешних ИС по отношению к Витрине данных НСУД);

  • выполнение запросов в соответствии с протоколом ПОДД через механизмы ПОДД СМЭВ:

    • поддержка протокола коммуникации агента ПОДД.

    • предоставление публикуемых данных (в т. ч. BLOB-объектов и/или с использованием табличных параметров);

    • генерацию формируемых документов на основании публикуемых данных;

    • репликацию публикуемых данных (в качестве витрины-источника);

    • получение реплицируемых данных (в качестве витрины-получателя).

  • обмен в соответствии с протоколом СМЭВ3:

    • подключение к СМЭВ3 как информационной системы участника взаимодействия;

    • обработку запросов на предоставление публикуемых данных (видов сведений), в т. ч. BLOB-объектов;

    • инициативная рассылка оповещений об обновлении публикуемых данных.

  • обработка запросов с использованием стандарта JDBC;

  • публикация конечных точек API для обработки запросов с использованием спецификации OpenAPI версии 3;

  • предоставление публикуемых данных информационным системам с использованием интерфейса JDBC и/или REST-запросов;

  • восстановление данных в непротиворечивое состояние после сбоев;

  • поддержка языка SQL;

  • журналирование событий функциональных блоков;

  • мониторинг информации о работоспособности экземпляра Программы.

1.3. Компоненты системы

Перечень состава компонентов программы версии 1.13.0 приведен в таблице ниже (см. Таблица 1.8)

Таблица 1.8 Состав компонентов в дистрибутиве программы

Наименование компонента

Версия

Техническое наименование

ПОДД Агент

3.11.0

ПОДД-Агент:3.11.0

СМЭВ3-адаптер

1.13.0

smev3-adapter:1.13.0

printable-form-service

1.13.0

printable-form-service:1.13.0

rest-adapter

1.13.0

rest-adapter:1.13.0

rest-uploader

1.13.0

rest-uploader:1.13.0

data-uploader

1.13.0

data-uploader:1.13.0

blob-adapter

1.13.0

blob-adapter:1.13.0

podd-adapter-query

1.13.0

podd-adapter-query:1.13.0

podd-adapter-replicator

1.13.0

podd-adapter-replicator:1.13.0

podd-adapter-group-repl

1.13.0

podd-adapter-group-repl:1.13.0

podd-adapter-mppr

1.13.0

podd-adapter-mppr:1.13.0

podd-adapter-mppw

1.13.0

podd-adapter-mppw:1.13.0

podd-adapter-group-tp

1.13.0

podd-adapter-group-tp:1.13.0

podd-adapter-import-tp

1.13.0

podd-adapter-import-tp:1.13.0

podd-avro-defragmentator

1.13.0

podd-avro-defragmentator:1.13.0

smevql-server

1.13.0

smevql-server:1.13.0

csv-uploader

1.13.0

csv-uploader:1.13.0

counter-provider

1.13.0

counter-provider:1.13.0

backup-manager

1.13.0

backup-manager:1.13.0

query-execution

6.7.0

query-execution:6.7.0

kafka

2.6.0

kafka:2.6.0

zookeeper

3.5.7

zookeeper:3.5.7

redis

7.0.11

redis:7.0.11

fdw

0.10.2

fdw:0.10.2

pxf

1.0

pxf:1.0

2. Подготовка к установке

2.1. Предварительные действия

Примечание

Установка Программы производится в закрытом контуре (без необходимости доступа к сети Интернет).

Перед установкой Программы необходимо выполнить следующие предварительные действия:

  1. Установить на серверы одну из поддерживаемых операционных систем (см. раздел Установка операционной системы).

  2. Проверить настройки Firewall и отключить при необходимости (см. раздел Настройка межсетевого экрана).

  3. Выключить SELinux (см. раздел Отключение SELinux (только для CentOS)).

  4. Указать соответствующий местоположению сервера часовой пояс (см. раздел Выбор часового пояса).

  5. Проверить, что на всех серверах установлен сервис синхронизации времени (см. раздел Установка сервиса синхронизации времени).

  6. Проверить, что имена хостов (FQDN) серверов могут получать IP по имени со всех машин (см. раздел Настройка имен хостов (FQDN) на серверах);

  7. Установить/обновить Java SE Development Kit 17.0.7 (см. раздел Установка Java SE Development Kit 17.0.7)

Дополнительно можно установить:

2.1.1. Установка операционной системы

Программа может работать на одной из операционных систем:

  • Centos 7.9;

  • Astra Linux Special Edition 1.7 (уровень защищенности «Воронеж»);

  • Alt 8 SP Server;

  • РЕД ОС, версии 7.2.

Подробная инструкция по установке операционной системы Centos 7.9 приведена на официальном сайте разработчика: https://docs.centos.org/en-US/centos/install-guide/.

Подробная инструкция по установке операционной системы Astra Linux Special Edition 1.7 приведена на официальном сайте разработчика: https://astralinux.ru/products/astra-linux-special-edition/documents-astra-se/

Подробная инструкция по установке операционной системы Alt 8 SP Server приведена на официальном сайте разработчика: https://www.basealt.ru/alt-8-sp-sertifikat-fstehk/docs

Подробная инструкция по установке операционной системы РЕД ОС, версии 7.2 приведена в документе «Руководство администратора по РЕД ОС 7.2»

2.1.2. Настройка межсетевого экрана

Для корректной установки потребуется отключить службу FirewallD операционной системы CentOS.

Что просмотреть текущий статус работы приложения используйте команду firewall-cmd:

sudo firewall-cmd --state

В случае, если служба FirewallD запущена, команда выше выведет следующее сообщение:

running

Вы можете временно остановить службу FirewallD для этого выполните следующую команду:

sudo systemctl stop firewalld

Следует учитывать, что данная команда только временно отключит службу, при последующей перезагрузке служба FirewallD снова будет запущена. Чтобы полностью отключить службу выполните следующую команду:

Остановите службу:

sudo systemctl stop firewalld

Отключите автоматический запуск службы FirewallD при загрузке операционной системы:

sudo systemctl disable firewalld

После отключения проверьте, что статус службы изменился на not running, для этого выполните команду

sudo firewall-cmd --state
not running

2.1.3. Отключение SELinux (только для CentOS)

Для корректной установки CentOS необходимо отключить SELinux, для этого выполните следующие действия:

1. Проверьте параметры запуска SELinux при загрузке системы. Для этого выполните следующую команду:

cat /etc/selinux/config

2. Если параметр SELINUX имеет значение enforcing, отключите запуск SELinux при загрузке системы. Для этого следует в файле /etc/selinux/config указать значение SELINUX=disabled и перезагрузите сервер. SELinux будет отключен.

Открыть и отредактировать файл /etc/selinux/config можно с помощью редактора vi, для этого выполните команду:

sudo vi /etc/selinux/config
  1. Проверьте, что служба отключена. Для этого выполните команду:

    sestatus

В ответ вы должны получить:

SELinux status: disabled

2.1.4. Выбор часового пояса

Проверьте, что установлен нужный часовой пояс. В нашем случае, на команду timedatectl, должна выводиться строка Time zone: Europe/Moscow (MSK, +0300).

Пример команды:

timedatectl

Пример ответа:

Local time: Mon 2021-12-20 12:06:39 MSK
Universal time: Mon 2021-12-20 09:06:39 UTC
RTC time: Mon 2021-12-20 09:06:49
Time zone: Europe/Moscow (MSK, +0300)
NTP enabled: n/a
NTP synchronized: no
RTC in local TZ: no
DST active: n/a

Если результат отличается, укажите соответствующий местоположению сервера часовой пояс.

Пример команды для московского часового пояса:

sudo timedatectl set-timezone Europe/Moscow

2.1.5. Установка сервиса синхронизации времени

Для корректной установки программы необходимо убедиться, что на всех серверах установлен сервис синхронизации времени.

2.1.6. Настройка имен хостов (FQDN) на серверах

Для корректной установки программы необходимо проверить, что имена хостов (FQDN) серверов могут взаимно получать IP по имени со всех машин. Имена хостов меняются согласно документации установленной ОС.

2.1.7. Установка Java SE Development Kit 17.0.7

Установка Java SE Development Kit 17.0.7 осуществляется согласно официальной документации: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html

2.1.8. Установка компонента сбора данных запросов и ответов Витрины данных

Компонент сбора данных запросов и ответов Витрины данных реализован с целью проведения бизнес-мониторинга ИЭП процессов обработки запросов типовым ПО витрины данных, как в целом, так и в части функционирования отдельных витрин для последующей передачи данных в СЦЛ.

2.1.8.1. Процесс установки

Общий процесс установки состоит из следующих действий:

  1. Настройка логирования приложений

  2. Установка и настройка Vector.

  3. Установка и настройка HaProxy.

  4. Установка и настройка fluentbit.

  5. Установка ClickHouse.

2.1.8.1.1. Настройка логирования приложений

На стороне приложений ПОДД-адаптер, Модуль MPPR, BLOB-адаптер и сервиса формирования документов необходимо настроить формирование логов в формате JSON. Для этого необоходимо в файле logback.xml включить net.logstash.logback.encoder.LogstashEncoder.

Пример logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/application.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- keep 30 days' worth of history capped at 3GB total size -->
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

    <root level="INFO">
        <appender-ref ref="FILE" />
    </root>
</configuration>

Подробная информация об encoder

2.1.8.1.2. Установка и настройка Vector

Установка производится по официальной документации Vector

Настройка Vector

Пример настройки source:

json_source:
    type: fluent
    address: 0.0.0.0:24226

Пример фильтрации сообщений, имеющих флаг scl:

scl_tags_filter:
type: filter
inputs:
  - json_source
condition:
  type: "vrl"
  source: |-
    exists(.tags) && includes(array!(.tags), "TYPE_SCL")

Пример парсинга scl-сообщений:

scl_message_remap:
    type: remap
    inputs:
    - scl_tags_filter
    source: |-
    . = parse_json!(.message)

Пример отправки scl-сообщений в Kafka:

podd_agent_sink:
    type: kafka
    inputs:
      - scl_message_remap
    bootstrap_servers: kafka:9092
    topic: "<префикс>.scl.signal"
    acknowledgements: true
    compression: "gzip"
    encoding:
      codec: json
    healthcheck: true
2.1.8.1.3. Установка и настройка HaProxy

Установка производится по официальной документации HaProxy

Для настройки HaProxy в секции backend нужно перечислить список установленных инстансов Vector.

Пример файла haproxy.cfg:

global
    log 127.0.0.1 local2

    chroot /var/lib/haproxy
    pidfile /var/run/haproxy.pid
    maxconn 4000
    user haproxy
    group haproxy
    daemon

    stats socket /var/lib/haproxy/stats

defaults
    mode tcp
    log global
    retries 3

    maxconn 3000

listen stats
    bind                 0.0.0.0:1936
    mode                 http
    stats                enable
    stats                uri /

frontend services
    bind 0.0.0.0:24226
    default_backend services
    mode tcp

backend services
    balance roundrobin
    mode tcp
    server vector01 vector-01:24226
    server vector02 vector-02:24226
2.1.8.1.4. Установка и настройка FluentBit

Установка производится по официальной документации FluentBit.

Далее необходимо настроить fluentbit на чтение файлов с логами приложений.

Пример файла конфигурации fluent-bit.conf:

[SERVICE]
    flush        5
    daemon       off
    log_level    info
    parsers_file parsers.conf
[INPUT]
    name tail
    path <путь до лог файла приложения>
    tag *
    parser json
[OUTPUT]
    name forward
    match *
    host haproxy
    port 24226

Пример файла parsers.conf:

[PARSER]
    Name        json
    Format      json

На этом настройка fluentbit завершена.

2.1.8.1.5. Включение / выключение отправки сообщений в СЦЛ

Отправка логов в СЦЛ осуществляется автоматически после корректной настройки компонента.

Для выключения отправки логов можно закомментировать блок podd_agent_sink отправки сообщений в kafka в настройках Vector.

2.1.8.1.6. Установка и настройка ClickHouse

Установка производится по официальной документации ClickHouse

Пример задания конфигурационных настроек:

clickhouse_default_config:
clickhouse:
   logger:
      level: trace
      log: /var/log/clickhouse-server/clickhouse-server.log
      errorlog: /var/log/clickhouse-server/clickhouse-server.err.log
      size: 1000M
      count: 10
   http_port: 8123
   tcp_port: 9000
   listen_host: 0.0.0.0
   max_connections: 4096
   keep_alive_timeout: 3
   user_directories:
      users_xml:
      path: users.xml
      local_directory:
      path: "{{ clickhouse_root_data_folder }}/access/"
   path: "{{ clickhouse_root_data_folder | add_slash }}"

2.1.9. Настройка сервиса журналирования

Сервис журналирования позволяет работать с логами прикладных модулей запущенных в средах WildFly и Kubernetes/OpenShift.

Настройка сервиса журналирования должна быть применена к каждому модулю.

Ниже указаны шаги, позволяющие обеспечить интеграцию сервиса с системой журналирования Платформы ГосТех.

  1. Добавить зависимости в проект

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.3.4.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>logger-test</artifactId>

<properties>
   <java.version>11</java.version>
   <spring-cloud.version>Hoxton.SR5</spring-cloud.version>
</properties>

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
   </dependency>

   <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
   </dependency>

   <dependency>
      <groupId>ch.qos.logback.contrib</groupId>
      <artifactId>logback-json-classic</artifactId>
      <version>0.1.5</version>
   </dependency>

   <dependency>
      <groupId>ch.qos.logback.contrib</groupId>
      <artifactId>logback-jackson</artifactId>
      <version>0.1.5</version>
   </dependency>
   <dependency>
      <groupId>net.logstash.logback</groupId>
      <artifactId>logstash-logback-encoder</artifactId>
      <version>6.3</version>
   </dependency>
   <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
      <scope>provided</scope>
   </dependency>
   <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-boot-starter</artifactId>
      <version>3.0.0</version>
   </dependency>
   <dependency>
      <groupId>org.codehaus.janino</groupId>
      <artifactId>janino</artifactId>
      <version>3.0.6</version>
   </dependency>
   <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-sleuth</artifactId>
   </dependency>
   <dependency>
      <groupId>org.springframework.kafka</groupId>
      <artifactId>spring-kafka</artifactId>
      <version>2.5.9.RELEASE</version>
   </dependency>

</dependencies>
<dependencyManagement>
   <dependencies>
      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
      </dependency>
   </dependencies>
</dependencyManagement>
  1. Подключить Fluentbit к приложению как отдельный контейнер в OpenShift

containers:
 - name: fluent-bit
   image: fluent/fluent-bit:latest
   volumeMounts: #перенос конфигураций, и лог файла из проекта в контейнер
     - name: logger
       mountPath: /fluent-bit/logger/
     - name: fluent-bit-config
       mountPath: /fluent-bit/etc/
   terminationMessagePolicy: File
   envFrom:
     - configMapRef:
         name: logger-fluent-bit-config-env
  1. Создать файла logback.xml для логирования приложения ( подробнее см. документацию)

Внимание

Обязательно в appender FILE_FLUENT прописать путь до конфигураций fluent-bit, иначе в контейнер логи не подтянутся. Например, <file>name-project/docker/fluentbit/conf/log.log</file>.

<configuration debug="true">
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
               <Pattern>
                  %d{yyyy-MM-dd HH:mm:ss}%-5level %logger{36} - %msg%n
               </Pattern>
            </pattern>
      </layout>
   </appender>

   <appender name="FILE_FLUENT" class="ch.qos.logback.core.FileAppender">
      <file>docker/fluentbit/conf/log.log</file>
      <append>false</append>
      <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
               <Pattern>
                  x-b3-traceid=%X{X-B3-TraceId:-} x-b3-spanid=%X{X-B3-SpanId:-} x-b3-parentspanid=%X{X-B3-ParentSpanId:-} x-b3-sampled=%X{X-B3-Sampled:-} x-b3-flags=%X{X-B3-Flags:-} caller_file_name=%file serverEventDatetime="%d" logLevel=%level threadName=%thread  message="%replace(%replace(%m){'\n','\u2028'}){'\"','\''}" exception="%replace(%replace(%ex){'\"','\u2028'}){'\n','\u2028'}%nopex" callerLine=%L callerMethod="%replace(%caller){'\n','\u2028'}" loggerName="%10.10logger" callerClass=%logger{40} levelStr="%level" levelInt="%level" mdc= \n
               </Pattern>
            </pattern>
      </layout>
   </appender>

   <root level="debug" additivity="false">
      <appender-ref ref="STDOUT"/>
      <appender-ref ref="FILE_FLUENT"/>
   </root>
</configuration>
  1. Добавить описание конфигурации для Fluent-bit (подробнее см документацию )

[SERVICE]
      Flush         1
      Log_Level     info
      Daemon        off
      Parsers_File /fluent-bit/etc/parsers.conf
[INPUT]
      Name   tail
      Path        /fluent-bit/logger/log.log
      Tag    kafka-efs
      Buffer_Chunk_Size 400k
      Buffer_Max_Size 6MB
      Mem_Buf_Limit 6MB
      Parser logfmt
      Refresh_Interval 20

[FILTER]
      Name record_modifier
      Match       kafka-efs
      Record      subsystem ${SUBSYSTEM}
      Record      distribVersion ${DISTRIBVERSION}
      Record      deploymentUnit ${DEPLOYMENTUNIT}
      Record      hostName ${HOSTNAME}
      Record      ipAddress ${IPADDRESS}

[FILTER]
      Name        modify
      Match       kafka-efs
      Hard_copy callerClass className

[FILTER]
      Name        record_modifier
      Match       kafka-efs
      Whitelist_key serverEventDatetime
      Whitelist_key subsystem
      Whitelist_key distribVersion
      Whitelist_key deploymentUnit
      Whitelist_key hostName
      Whitelist_key ipAddress
      Whitelist_key logLevel
      Whitelist_key className
      Whitelist_key threadName
      Whitelist_key message
      Whitelist_key x-b3-traceid
      Whitelist_key x-b3-spanid
[FILTER]
      Name    lua
      Match   kafka-efs
      script  convert_date.lua
      call    convert_date_efs

[OUTPUT]
      Name  stdout
      Match kafka-efs
      Format json
      json_date_key time

[OUTPUT]
      Name  http
      Match kafka-efs
      Host logstash-service-gt-tatarstan-test-efs.apps.ocp-public.sbercloud.ru
      Port 80
      Format json
      json_date_key time

Для правильной работы необходимо подключить parsers.conf.

[PARSER]
      Name        logfmt
      Format      logfmt
  1. Добавить форматирование даты

function convert_date_efs(tag, timestamp, record)
  local pattern = "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+),(%d+)"
  dt_str = record["serverEventDatetime"]
  local year, month, day, hour, minute, seconds, milliseconds = dt_str:match(pattern)
  ts = os.time{year = year, month = month, day = day, hour = hour, min = minute, sec = seconds }
  ts = (ts * 1000) + milliseconds
  record["serverEventDatetime"] = ts
  return 2, timestamp, record
end

function convert_date_pprb(tag, timestamp, record)
  local pattern = "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+),(%d+)"
  dt_str = record["serverEventDatetime"]
  local year, month, day, hour, minute, seconds, milliseconds = dt_str:match(pattern)
  ts = os.time{year = year, month = month, day = day, hour = hour, min = minute, sec = seconds }
  ts = (ts * 1000) + milliseconds
  record["timestamp"] = ts
  return 2, timestamp, record
end

function convert_date_logstash(tag, timestamp, record)
  local pattern = "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+),(%d+)"
  dt_str = record["serverEventDatetime"]
  local year, month, day, hour, minute, seconds, milliseconds = dt_str:match(pattern)
  ts = os.time{year = year, month = month, day = day, hour = hour, min = minute, sec = seconds }
  ts = (ts * 1000) + milliseconds
  record["time"] = ts
  return 2, timestamp, record
end
  1. Добавить параметры модуля

kind: ConfigMap
apiVersion: v1
metadata:
  name: logger-fluent-bit-config-env
data:
  MODULEID: 1.0.0
  MODULEVERSION: 1.0.0
  NODEID: 12345
  HOSTADDRESS: 0.0.0.0
  SUBSYSTEM: LOGGER-TEST
  DISTRIBVERSION: 1.0.0
  DEPLOYMENTUNIT: TEST-UNIT
  IPADDRESS: 0.0.0.1

2.1.10. Настройка подсистемы мониторинга

Подсистема мониторинга предназначена для регистрации отладочной информации прикладных модулей в едином журнале.

Настройка подсистемы мониторинга должна быть применена к каждому модулю.

Ниже указана последовательность действий для выставления метрик в формате Prometheus из прикладного приложения, написанного на Spring Boot.

  1. Добавить зависимостей на Spring Boot Actuator и Micrometer в maven репозиторий.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
   <groupId>io.micrometer</groupId>
   <artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
   <groupId>io.micrometer</groupId>
   <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
  1. Указать порт Actuator, фильтр включенных конечных точек и системные теги, которые автоматически будут добавлены к прикладным метрикам (файл application.yml)

server:
port: 8080

management:
endpoint:
   health.show-details: always
endpoints:
web:
exposure:
   include: '*'
metrics:
tags:
application: ${spring.application.name}
namespace: ${POD_NAMESPACE:local}
pod: ${POD_NAME:local}
node_name: ${NODE_NAME:local}
  1. Создать прикладные метрики в проекте (с помощью micrometer)

@RestController
public class CounterController {

   private static final String COUNTER_WITH_TAG_NAME = "simple.counterWithTags";
   private static final String COUNTER_WITH_TAG_DESCRIPTION = "Just a simple counter with tags";
   private static final String TAG_NAME_1 = "terbank";
   private static final String TAG_NAME_2 = "vsp";

   private final MeterRegistry meterRegistry;

   private Counter simpleCounter;
   private Counter simpleCounterWithTags;
   private Counter simpleCounterWithTags2;

   public CounterController(MeterRegistry meterRegistry) {
   this.meterRegistry = meterRegistry;
   }

   /**
   * Инициализация метрик типа Counter
   */
   @PostConstruct
   public void init() {
      simpleCounter = Counter.builder("simple.counter")
               .description("Just a simple counter")
               .register(meterRegistry);

      simpleCounterWithTags = Counter.builder(COUNTER_WITH_TAG_NAME)
               .description(COUNTER_WITH_TAG_DESCRIPTION)
               .tag(TAG_NAME_1, "sib")
               .tag(TAG_NAME_2, "111")
               .register(meterRegistry);

      simpleCounterWithTags2 = Counter.builder(COUNTER_WITH_TAG_NAME)
               .description(COUNTER_WITH_TAG_DESCRIPTION)
               .tag(TAG_NAME_1, "msk")
               .tag(TAG_NAME_2, "111")
               .register(meterRegistry);
   }

   @PutMapping("/counter")
   public String incrementCounter() {
      simpleCounter.increment();
      return String.format("Counter has been increases\nCurrent value: %s", simpleCounter.count());
   }

   @PutMapping("/counter-with-tags/terbank/sib")
   public String incrementCounterTags1() {
      simpleCounterWithTags.increment(1);
      return String.format("Counter has been increases\nCurrent value: %s", simpleCounterWithTags.count());
   }

   @PutMapping("/counter-with-tags/terbank/msk")
   public String incrementCounterTags2() {
      simpleCounterWithTags2.increment(2);
      return String.format("Counter has been increases\nCurrent value: %s", simpleCounterWithTags2.count());
   }
}

С помощью REST API сервиса возможна генерация собственных метрик типа Counter

curl -X PUT "MONITOR_URL/counter" -H "accept: */*"
curl -X PUT "MONITOR_URL/counter-with-tags/terbank/msk" -H "accept: */*"

В каждом из ответов можно увидеть, что общий счетчик метрик был увеличен на n-ное количество. Пример:

Counter has been increases
Current value: 1.0

2.1.10.1. Настройка конфигурации для OpenShift

Для того, чтобы Prometheus мог идентифицировать сервис и собирать с него информацию, необходимо создать Service и указать путь, на котором располагаются метрики приложения.

apiVersion: v1
kind: Service
metadata:
name: monitoring-rest
annotations:
   description: 'Exposes Prometheus App by CLuster Ip'
   prometheus.io.scrape: 'true'
   prometheus.io.path: '/monitoring-rest/actuator/prometheus'
   prometheus.io.port: '8081'
labels:
   app: monitoring-rest
spec:
type: LoadBalancer
ports:
   - name: http
      port: 8080
      targetPort: 8080
   - name: http-actuator
      port: 8081
      targetPort: 8081
selector:
   app: monitoring-rest

2.1.10.2. Grafana: графики мониторинга

Графики мониторинга метрик можно увидеть в Grafana.

Логин/пароль для входа в Grafana: viewer/viewer.

select TIME_FLOOR(__time,'PT1M') as "time",
avg("value") as "avg_value",
"labels.app" as "app",
name as name
from "unimon.gostech_task"
WHERE
name like '%counter%'
and "labels.namespace"='gt-sol-test-coreplatform-01'
and ("labels.application"='monitoring-rest'
OR "labels.app"='monitoring-rest'
OR "labels.SUBSYSTEM"='monitoring-rest')
group by TIME_FLOOR(__time,'PT1M'), "labels.app", name

Также существуют и другие типы метрик (DistributionSummary, Gauge, Timer), генерация которых реализована в demo-приложении.