Перейти к содержанию

Логи

Интеграции пишут логи в stdout. Filebeat на каждом узле читает логи подов namespace платформы и отправляет их в Logstash. Logstash разбирает строки и пишет их в Elasticsearch.

Формат логов интеграции

Формат задаёт файл log4j2.properties в проекте: без ANSI-цветов, с trace id и span id в каждой строке. В новый проект файл из шаблона не переносится, скопируйте его из любого готового проекта.

Чтобы связать события одного бизнес-объекта между интеграциями, добавьте его идентификатор в MDC (подробнее в разделе Брокеры сообщений и сквозная трассировка):

camel.mdc.customHeaders=CAMEL_TRACE_ID,CAMEL_SPAN_ID,OrderId

Заголовок OrderId попадёт в строки лога, которые пишутся при обработке сообщения. Строки запуска приложения его не содержат. В log4j2.properties его печатает шаблон [order=%X{OrderId}], а Logstash кладёт значение в поле order.id. Вся цепочка обработки в Kibana находится одним запросом:

order.id: "<значение ключа>"

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

Filebeat из чарта

logging:
  filebeat:
    enabled: true
    logstashHost: "<хост Logstash>:5045"
    dataPath: ""            # пусто: /var/lib/<namespace>-neomsa-esb-filebeat-data
    tolerations: []

Filebeat из чарта:

  • работает только в namespace платформы и не создаёт ничего в kube-system;
  • обходится без ClusterRole и маршрутизирует события только по меткам пода;
  • использует имена neomsa-esb-filebeat, чтобы не конфликтовать с уже установленным в кластере Filebeat;
  • хранит реестр в отдельном каталоге на узле. Два Filebeat с общим реестром дают дубли и потери;
  • монтирует только каталоги с логами контейнеров.

DaemonSet читает логи с узла через hostPath, поэтому namespace должен иметь уровень Pod Security privileged. Этот уровень действует на все поды namespace, включая интеграции. Если это недопустимо, отключите Filebeat в чарте и собирайте логи внешним агентом. Если на узлах есть taints, добавьте tolerations, иначе с этих узлов логи не соберутся.

Ограничение по namespace логическое: Filebeat подписывается только на поды своего namespace, но физически видит каталоги логов всех подов узла. Если нужна изоляция на уровне файловой системы, отправляйте логи из приложений по сети (log4j2 → Logstash TCP) без DaemonSet.

Logstash

В комплект поставки входит пайплайн logstash/neomsa-esb.conf. Подключите его отдельным пайплайном в pipelines.yml Logstash:

  • пайплайн слушает отдельный порт 5045;
  • положите файл в отдельный каталог, например pipeline-neomsa/, чтобы его фильтры не применялись к событиям других пайплайнов;
  • если Logstash запускается с флагом -f, уберите этот флаг: с ним Logstash игнорирует pipelines.yml и запускает только один файл.

После перезапуска проверьте, что работают оба пайплайна:

grep "Pipelines running" <лог Logstash>
# ожидается: :running_pipelines=>[:main, :"neomsa-esb"]

Индексы

Пайплайн пишет в месячные индексы neomsa-esb-integrations-YYYY.MM и neomsa-esb-platform-YYYY.MM. Суточные индексы быстро упираются в лимит шардов кластера (cluster.max_shards_per_node, по умолчанию 1000 на узел). После этого Elasticsearch не может создать новый индекс и отклоняет документы с ошибкой 400. Такие документы Logstash не повторяет: он отправляет их в dead letter queue, если она включена (dead_letter_queue.enable: true в logstash.yml), а иначе отбрасывает с записью в лог.

Для узла без реплик задайте срок хранения и шаблон индекса. Нужен пользователь с правами на ILM и шаблоны индексов, curl запросит его пароль:

curl --cacert <CA Elasticsearch> -u <пользователь> -XPUT \
  -H 'Content-Type: application/json' \
  "https://<es>:9200/_ilm/policy/neomsa-esb-logs" \
  -d '{"policy":{"phases":{"hot":{"actions":{}},"delete":{"min_age":"90d","actions":{"delete":{}}}}}}'

curl --cacert <CA Elasticsearch> -u <пользователь> -XPUT \
  -H 'Content-Type: application/json' \
  "https://<es>:9200/_index_template/neomsa-esb" \
  -d '{"index_patterns":["neomsa-esb-*"],"priority":200,
       "template":{"settings":{"number_of_shards":1,"number_of_replicas":0,
                               "index.lifecycle.name":"neomsa-esb-logs"},
                   "mappings":{"properties":{"order":{"properties":{"id":{"type":"keyword"}}}}}}}'

Срок 90d отсчитывается от создания индекса. Индекс месячный, поэтому событие из конца месяца удалится примерно через 60 дней. Если каждое событие нужно хранить не меньше 90 дней, задайте min_age с запасом в месяц, например 120d.

Шаблон действует только на индексы, созданные после него. Состояние политики у индекса показывает запрос GET <индекс>/_ilm/explain.