Логи¶
Интеграции пишут логи в stdout. Filebeat на каждом узле читает логи подов namespace платформы и отправляет их в Logstash. Logstash разбирает строки и пишет их в Elasticsearch.
Формат логов интеграции¶
Формат задаёт файл log4j2.properties в проекте: без ANSI-цветов, с trace id и span id в каждой строке. В новый проект файл из шаблона не переносится, скопируйте его из любого готового проекта.
Чтобы связать события одного бизнес-объекта между интеграциями, добавьте его идентификатор в MDC (подробнее в разделе Брокеры сообщений и сквозная трассировка):
Заголовок OrderId попадёт в строки лога, которые пишутся при обработке сообщения. Строки запуска приложения его не содержат. В log4j2.properties его печатает шаблон [order=%X{OrderId}], а Logstash кладёт значение в поле order.id. Вся цепочка обработки в Kibana находится одним запросом:
Такая связка особенно нужна, когда интеграции обмениваются данными через брокер сообщений или промежуточную таблицу: трасса между ними может прерываться, и тогда у каждой интеграции свой 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и запускает только один файл.
После перезапуска проверьте, что работают оба пайплайна:
Индексы¶
Пайплайн пишет в месячные индексы 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.