Примечание. Чтобы получить общее представление о Fluentd, ознакомьтесь со следующей статьей.



Плагин парсера Fluentd json, один из многих плагинов Fluentd, отвечает за анализ журналов JSON. В сочетании с динамическим сопоставлением очень легко отправлять журналы в формате JSON в кластер Elasticsearch. Это может быть очень полезно, но создает две проблемы: неправильные типы полей и расширение сопоставления, поскольку иногда вы не имеете достаточного контроля над получаемыми данными.

Чтобы узнать больше об управлении индексом Elasticsearch и его производительности, ознакомьтесь со следующей статьей.



Неверные типы полей возникают, когда Elasticsearch присваивает полю неправильный тип. Например, Elasticsearch может отображать продолжительность в текст или целое число, если вы хотите, чтобы она была с плавающей запятой, чтобы вы могли выполнять с ней операции. Это можно исправить, создав шаблон индекса и задав определенное поле определенного типа:

“index_patterns” : [“logstash-*”],
“mappings” : {
  “properties”: {
    “code”: {
      “type”: “text”
    },
    “duration”: {
      “type”: “float”
    },
    “exception”: {
      “type”: “text”
    },
    ....
  }
}

В этой статье мы обсудим несколько приемов, позволяющих избежать второй проблемы, сопоставления взрывов.

Отображение взрывов

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

Рассмотрим сценарий, в котором журналы приложений содержат заголовки запроса/ответа. Приложение использует CDN или WAF, которые используют обратные прокси-серверы для обработки входящего и исходящего трафика. Заголовки могут содержать идентификатор прокси, обрабатывающего запрос:

“req”: {
 “url”: “/home”,
 “headers”: {
 “x-request-id”: “xxxxxxxxxxxxxxxxxxxx”,
 “x-real-ip”: “xx.xx.xx.xx”,
 “x-forwarded-for”: “xx.xx.xx.xx”,
 “x-forwarded-host”: “www.mysite.com”,
 “x-forwarded-port”: “443”,
 “x-forwarded-proto”: “https”,
 “x-scheme”: “https”,
 “context.cdn-proxy-1”: “OK”,
 ...
 }

Если CDN имеет тысячи прокси, ваш индекс будет генерировать новое поле для каждого прокси, то есть прокси-1, прокси-2… прокси-N.

Если значение полей для вас важно, вы можете переименовать ключевую часть кортежа, оставив значение нетронутым, воспользовавшись плагином rename-key. . (Добавьте его в свой образ Docker, как описано здесь).

<filter kubernetes.var.log.containers.**.log>
  @type rename_key
  enable_ruby true
  rename_rule1 cdn-proxy-(.+) cdn-proxy
  rename_rule2 (\s.+) input
</filter>

Таким образом, ключи cdn-proxy-[N] будут переименованы в cdn-proxy, сохраняя значение кортежа доступным и нетронутым.

Второй вариант — полное удаление кортежа, если он вас не интересует. В этом случае мы будем использовать плагин record_modifier внутри фильтра:

<filter kubernetes.var.log.containers.**.log>
  @type record_modifier
  <record>
  _remove_ ${if record.has_key?(‘req’); record[‘req’].delete(‘cdn-proxy’) ; end; nil}
  </record>
  remove_keys _remove_
</filter>

Примечание. Невозможно применить подстановочный знак для одновременного удаления всех ключей, например, cdn-proxy-1, cdn-proxy-2 и т. д. Поэтому вам придется сначала переименовать их, а затем удалить один ключ. Вы можете применить этот фильтр к любому уникальному ключу, который вас не интересует.

И это все для этого поста. Надеюсь, вы нашли эти два приема полезными, чтобы избежать неконтролируемого роста индексов Elasticsearch и в то же время добиться лучшей производительности вашего кластера.

Спасибо за чтение!