Системный журнал EVPT#

Настройка системного журнала#

Отправляемые сообщения имеют формат JSON или XML согласно шаблону, описываемому в файле ./conf/logback.xml на сервере установки.

Перед установкой (переустановкой) новой версии EVPT необходимо в конфигурационном файле vars.yml заполнить блок:

В случае установки на VM:

scheduler_vm:
  logback_kafka_appender:
    enable: false # включение механизма отправки логов в Kafka через logback
    topic: evpt_topic # топик для отправки логов
    never_block: false # блокировка работы приложения при недоступности Kafka (по умолчанию - блокируется, при true недоставленные сообщения в kafka отбрасываются)
    discarding_threshold: 20 # процент свободного места в очереди отправки сообщений при достижении которого будут удаляться сообщения уровня TRACE, DEBUG, INFO
    queue_size: 512 # размер очереди для отправки в Кафку
    retries: 3 # Количество переиницилизации продьюсера, если параметр не задан, по умолчанию значение 3
    interval: 1000 # Интервал между переиницилизациями, по умолчанию 1000 мс. Задается в мс.
    multiplier: 1 # Множитель интервала переинициализации, по умолчанию значение 1.
    producer_configs: # настройка Kafka продюсера
      bootstrap.servers: kafka-host-1:9093,kafka-host-2:9093 # bootstrap подключения к Apache Kafka вида host:port,host2:port2
      security.protocol: SSL # тип протокола подключения. Значение по умолчанию: SSL
      ssl.keystore.location: /opt/scheduler/ssl/scheduler.jks # путь до хранилища сертификатов, для подключения к Kafka
      ssl.keystore.password: _PLACEHOLDER_ # пароль от keystore
      ssl.truststore.location: /opt/scheduler/ssl/scheduler.jks # путь до truststore
      ssl.truststore.password: _PLACEHOLDER_ # пароль от truststore
      ssl.endpoint.identification.algorithm: "" # обязательный параметр. Значение не изменять. Отключение проверки хостнейма в сертификате, обязательно для стендов Kafka

В случае установки в OS:

scheduler:
  logback:
    level: info # Общий уровень логирования (error, debug, info, warn)
  #    loggers: # Настройка дополнительных loggers. В примере ниже указан пакет и уровень логирования
  #      - name: "org.apache.kafka"
  #        level: warn
  #      - name: "com.typesafe.akka"
  #        level: debug
       kafka:
         topic: <topic_name> # Наименование топика
         retries: 3 # Количество переиницилизаций продюсера
         interval: 1000 # Интервал между переиницилизациями
         multiplier: 1 # Множитель интервала переинициализации
         properties:
           "bootstrap.servers": "hostname-1:9092,hostname-2:9092" # Bootstrap подключения к Apache Kafka вида host:port,host2:port2
           "client.id": "scheduler" # Client id для подключения
           "config.providers": decode # Объявление провайдера шифрования паролей. Значение не изменять
           "config.providers.decode.class": ru.sbt.ss.kafka.DecryptionConfigProvider # Класс провайдера шифрования паролей. Значение не изменять
           "config.providers.decode.param.security.encoding.key": ssl/secret.pass # Путь до файла, содержащего ключ шифрования паролей
           "config.providers.decode.param.security.encoding.class": ru.sbt.ss.password.BaseEncryptor # Класс шифрования паролей. Значение не изменять
           "security.protocol": SSL # Тип протокола подключения. Значение по умолчанию: SSL
          "ssl.endpoint.identification.algorithm": "" # Обязательный параметр. Значение "" не изменяемое. Отключение проверки хостнейма в сертификате, обязательно для стендов Kafka
          "ssl.keystore.location": "/path/to/*.jks" # Путь до хранилища сертификатов, для отправки логов в kafka
          "ssl.truststore.location": "/path/to/*.jks" # Путь до truststore
          "ssl.keystore.password": <password> Пароль от keystore
          "ssl.truststore.password": <password> # Пароль от truststore
          "ssl.key.password": <password> # Пароль для key.password

Для настройки отправки сообщений в централизованную систему журналирования Platform V Monitor необходимо заполнить блок appender GateLogger файла logback.xml (пример описан ниже).

При заполнении файла logback.xml стоит обратить внимание на заполнение следующих параметров:

Параметр

Описание

Значение по умолчанию

bodyType

Тип сообщения. Доступные значения: XML или JSON

JSON

rqUIDPath

Путь до RqUID (case sensitive) в логируемых сообщениях xpath (//rqUID) или jsonpath ($…rqUID)

$…rqUID

topic

Имя топика записи сообщений логов

client.id

Идентификатор Kafka producer, по которому можно однозначно идентифицировать Apache Kafka producer

пусто

config.providers

Объявление провайдера шифрования паролей. Значение не изменять

decode

config.providers.decode.class

Класс провайдера шифрования паролей. Значение не изменять

config.providers.decode.param.security.encoding.key

Путь до файла, содержащего ключ шифрования паролей

config.providers.decode.param.security.encoding.class

Класс шифрования паролей. Значение не изменять

security.protocol

Тип протокола подключения к системе журналирования

SSL

ssl.endpoint.identification.algorithm

Проверка сертификата на соответствия hostname

ssl.keystore.location

Расположение файла keystore

ssl.truststore.location

Расположение файла truststore

ssl.keystore.password

Пароль keystore в зашифрованном виде

ssl.truststore.password

Пароль truststore в зашифрованном виде

ssl.key.password

Ключ шифрования паролей в зашифрованном виде

bootstrap.servers

Hosts подключения к системе журналирования

host:port,host:port

Пример файла logback.xml с заполненными настройками:

<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{60} %X{sourceThread} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>./log/scheduler.log</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- rollover every daily -->
            <fileNamePattern>./log/scheduler-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 50MB -->
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>5</maxHistory>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
            <!-- <totalSizeCap>2GB</totalSizeCap> -->
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{60} %X{sourceThread} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="file"/>
    </root>

</configuration>

Логирование в централизованную систему журналирования Platform V Monitor#

Для EVPT может быть настроена отправка системных журналов в централизованную систему журналирования Platform V Monitor.

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

  • узнать адреса брокеров Apache Kafka централизованной системы журналирования Platform V Monitor;

  • узнать названия топиков централизованной системы журналирования Platform V Monitor, куда будут отправляться журналы EVPT;

  • выпустить сертификат подключения к Apache Kafka централизованной системы журналирования Platform V Monitor;

  • следует обратить внимание на значение параметра neverBlock:

    • false — в случае недоступности Platform V Monitor недоставленные сообщения будут отправляться заново, что может привести к блокировке работы EVPT;

    • true — в случае недоступности Platform V Monitor недоставленные сообщения отбрасываются, и блокировки работы EVPT не происходит.

Пример конфигурации логирования в системный вывод#

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

Доступные уровни логирования системного журнала#

Имя логирования

Описание

Примечание

TRACE

Отражает менее приоритетные события для отладки

Уровень TRACE не рекомендуется включать в Промышленной среде

DEBUG

Отражает полную отладочную информацию. На этом уровне в системный журнал пишутся передаваемые клиентские запросы, а так же отправляемые ответы в адрес клиентов

Уровень DEBUG не рекомендуется включать в Промышленной среде

INFO

Уровень логирования по умолчанию. События отражают информационные события системного журнала

WARN

Уровень отражает предупреждения и некритические ошибки обработки запросов/состояния сервиса

ERROR

Уровень отражает критические ошибки обработки запросов/состояния сервиса

Изменение уровня логирования#

Возможно изменение уровня логирования при обращении к endpoint, на котором запущен healthCheck.

Схема

openapi: 3.0.1
info:
  description: "Logger runtime update"
  version: "1.0.0"
  title: "Logging swagger"
servers:
  - url: "http://localhost:8080"
    description: "Logger runtime update"
paths:
  /loggers:
    get:
      summary: "Текущее состояние логеров"
      description: |
        **Текущее состояние логеров** \
        curl http://localhost:8080/loggers
      responses:
        "200":
          description: "Success"
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    name:
                      type: string
                      example: "ru.sbt.ss"
                    level:
                      type: string
                      example: "INFO"
        "405":
          description: "Incorrect method"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Incorrect method"
    put:
      summary: "Изменение уровня логирования логера с указанным именем"
      description: |
        **Изменение уровня логирования логера с указанным именем** \
        curl -X PUT http://localhost:8080/loggers -d '{"name":"ru.sbt.ss","level":"info"}'
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              type: object
              required:
                - name
                - level
              properties:
                name:
                  type: string
                  example: "ru.sbt.ss"
                level:
                  type: string
                  example: "INFO"
      responses:
        "200":
          description: "Success"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Change logger ru.sbt.ss to level info"
        "400":
          description: "Incorrect data"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Incorrect data"
        "403":
          description: "Изменение незаданных в logback логеров"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Changing level of org.apache.kafka logger is prohibited"
        "404":
          description: "Not found"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Logger with name ru.sbt.ss not found"
        "405":
          description: "Incorrect method"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Incorrect method"
  /loggers/{loggerName}:
    get:
      summary: "Текущий уровень логирования логера с указанным именем"
      description: |
        **Текущий уровень логирования логера с указанным именем** \
        curl -v http://localhost:8080/loggers/ru.sbt.ss
      parameters:
        - in: path
          name: loggerName
          schema:
            type: string
          required: true
          description: "Имя логгера, информация о котором требуется"
      responses:
        "200":
          description: "Success"
          content:
            application/json:
              schema:
                type: object
                properties:
                  name:
                    type: string
                    example: "ru.sbt.ss"
                  level:
                    type: string
                    example: "INFO"
        "400":
          description: "Incorrect data"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Incorrect data"
        "404":
          description: "Not found"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Logger with name ru.sbt.ss not found"
        "405":
          description: "Incorrect method"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "Incorrect method"

Часто встречающиеся события в файлах логов#

Часто встречающиеся события в файлах логов типа WARN#

  1. Нет подключения к Pangolin SE:

16:49:56.797 [C3P0PooledConnectionPoolManager[identityToken->example|example]-HelperThread-#2] WARN  c.m.v.resourcepool.BasicResourcePool - com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@1fe499a6 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
org.postgresql.util.PSQLException: Подсоединение по адресу localhost:5432 отклонено. Проверьте что хост и порт указаны правильно и что postmaster принимает TCP/IP-подсоединения.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:342)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:263)
    at org.postgresql.Driver.makeConnection(Driver.java:443)
    at org.postgresql.Driver.connect(Driver.java:297)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1176)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1163)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1908)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)
  1. Не смогли найти схему БД с именем, указанным в параметрах (например, batch) в Pangolin SE:

16:34:43.670 [C3P0PooledConnectionPoolManager[identityToken->example|example]-HelperThread-#1] WARN  c.m.v.resourcepool.BasicResourcePool - com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@56eb4e91 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception:
org.postgresql.util.PSQLException: FATAL: database "batch" does not exist
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2713)
    at org.postgresql.core.v3.QueryExecutorImpl.readStartupMessages(QueryExecutorImpl.java:2825)
    at org.postgresql.core.v3.QueryExecutorImpl.<init>(QueryExecutorImpl.java:175)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:313)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:54)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:263)
    at org.postgresql.Driver.makeConnection(Driver.java:443)
    at org.postgresql.Driver.connect(Driver.java:297)
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:175)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:220)
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:206)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:203)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1176)
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1163)
    at com.mchange.v2.resourcepool.BasicResourcePool.access$700(BasicResourcePool.java:44)
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1908)
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:696)

Часто встречающиеся события в файлах логов типа ERROR#

  1. Не найден сертификат, используемый для вызова целевого узла:

16:32:32.369 [DatabaseScheduler_Worker-1] ERROR r.sbt.ss.batch.quartz.QuartzFuncJob - Cannot execute quartz task:
ru.sbt.ss.ssl.context.builder.SSLContextBuilderException: Error build SSLContext: /Example/abc/Documents/certs/grpc-adapter.jks
at ru.sbt.ss.ssl.context.builder.SSLContextBuilder.buildStores(SSLContextBuilder.java:215)
at ru.sbt.ss.ssl.context.builder.SSLContextBuilder.build(SSLContextBuilder.java:221)
at ru.sbt.ss.batch.utils.SslContextHelper$.getContextFromProperties(SslContextHelper.scala:58)
at ru.sbt.ss.batch.tasks.RestTask.run(RestTask.scala:30)
at ru.sbt.ss.batch.quartz.QuartzFuncJob.$anonfun$execute$1(QuartzFuncJob.scala:17)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
at scala.util.Try$.apply(Try.scala:210)
at ru.sbt.ss.batch.quartz.QuartzFuncJob.execute(QuartzFuncJob.scala:17)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.nio.file.NoSuchFileException: /Example/abc/Documents/certs/grpc-adapter.jks
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219)
at java.base/java.nio.file.Files.newByteChannel(Files.java:370)
at java.base/java.nio.file.Files.newByteChannel(Files.java:421)
at java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420)
at java.base/java.nio.file.Files.newInputStream(Files.java:155)
at ru.sbt.ss.ssl.context.builder.util.SSLContextUtil.loadKeystore(SSLContextUtil.java:43)
at ru.sbt.ss.ssl.context.builder.SSLContextBuilder.buildStores(SSLContextBuilder.java:203)
... 9 common frames omitted
  1. Не подошел пароль от ключа в хранилище сертификата, используемого для вызова целевого узла:

16:56:57.468 [DatabaseScheduler_Worker-1] ERROR r.sbt.ss.batch.quartz.QuartzFuncJob - Cannot execute quartz task:
ru.sbt.ss.ssl.context.builder.SSLContextBuilderException: Error build SSLContext: Cannot recover key
    at ru.sbt.ss.ssl.context.builder.SSLContextBuilder.build(SSLContextBuilder.java:226)
    at ru.sbt.ss.batch.utils.SslContextHelper$.getContextFromProperties(SslContextHelper.scala:58)
    at ru.sbt.ss.batch.tasks.RestTask.run(RestTask.scala:30)
    at ru.sbt.ss.batch.quartz.QuartzFuncJob.$anonfun$execute$1(QuartzFuncJob.scala:17)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
    at scala.util.Try$.apply(Try.scala:210)
    at ru.sbt.ss.batch.quartz.QuartzFuncJob.execute(QuartzFuncJob.scala:17)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.security.UnrecoverableKeyException: Cannot recover key
    at java.base/sun.security.provider.KeyProtector.recover(KeyProtector.java:304)
    at java.base/sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:144)
    at java.base/sun.security.util.KeyStoreDelegator.engineGetKey(KeyStoreDelegator.java:90)
    at java.base/java.security.KeyStore.getKey(KeyStore.java:1057)
    at java.base/sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:145)
    at java.base/sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70)
Caused by: java.security.UnrecoverableKeyException: Cannot recover key

    at java.base/javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:271)
    at ru.sbt.ss.ssl.context.builder.util.SSLContextUtil.createKeyManagerFactory(SSLContextUtil.java:122)
    at ru.sbt.ss.ssl.context.builder.SSLContextBuilder.buildContext(SSLContextBuilder.java:265)
    at ru.sbt.ss.ssl.context.builder.SSLContextBuilder.build(SSLContextBuilder.java:222)
    ... 8 common frames omitted