Fluentd в Kubernetes DaemonSet выборочно анализирует различные журналы

Таким образом, базовая архитектура Fluentd DaemonSet очищает журналы Docker от настроек модулей, следуя этой статье в блоге, которая в конце концов использует эти ресурсы.

У меня есть несколько модулей и служб, работающих в кластере, и я не могу контролировать их формат журнала. Однако у меня есть контроль над службами, над которыми я работаю, и я хотел бы, чтобы они использовали выходной формат JSON, совместимый с Logstash (ключ-значение).

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

Пример журнала в формате JSON (развернуто приложение Rails): введите описание изображения здесь

Пример журнала не в формате JSON (служба CI/CD): введите описание изображения здесь

Конкретные конфиги Fluentd находятся в этом файле

Любая помощь / предложения с благодарностью

РЕДАКТИРОВАТЬ 1: Более подробная информация предоставляется

Таким образом, проблема заключается в том, что журнал JSON извлекается с помощью следующих шагов

# JSON Log Example
{"log":"2014/09/25 21:15:03 Got request with path wombat\n", "stream":"stderr", "time":"2014-09-25T21:15:03.499185026Z"}

Журналы читаются из журналов докера в каждом узле, используя tail тип:

<source>
  @id fluentd-containers.log
  @type tail
  path /var/log/containers/*.log
  pos_file /var/log/es-containers.log.pos
  tag raw.kubernetes.*
  read_from_head true
  <parse>
    @type multi_format
    <pattern>
      format json
      time_key time
      time_format %Y-%m-%dT%H:%M:%S.%NZ
    </pattern>
    <pattern>
      format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
      time_format %Y-%m-%dT%H:%M:%S.%N%:z
    </pattern>
  </parse>
</source>

Плагин метаданных Kubernetes добавляет дополнительные данные

{
  "log":"2014/09/25 21:15:03 Got request with path wombat\n",
  "stream":"stderr",
  "time":"2014-09-25T21:15:03.499185026Z",
  "kubernetes": {
    "namespace": "default",
    "pod_name": "synthetic-logger-0.25lps-pod",
    "container_name": "synth-lgr"
  },
  "docker": {
    "container_id": "997599971ee6366d4a5920d25b79286ad45ff37a74494f262e3bc98d909d0a7b"
  }
}

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

{"method":"GET","path":"/","format":"html","controller":"HomeController","action":"index","status":200,"duration":1922.45,"view":1912.5,"db":883.41,"request_ip":"127.0.0.1","@timestamp":"2018-09-20T16:43:17.322Z","@version":"1","message":"[200] GET / (HomeController#index)"}

И проблема в том, что весь журнал будет "зажат" внутри поля "log", как вы можете видеть на первом скриншоте, размещенном выше. Я думаю, что с метаданными kubernetes это будет что-то вроде:

{
  "log":"{"method":"GET","path":"/","format":"html","controller":"HomeController","action":"index","status":200,"duration":1922.45,"view":1912.5,"db":883.41,"request_ip":"127.0.0.1","@timestamp":"2018-09-20T16:43:17.322Z","@version":"1","message":"[200] GET / (HomeController#index)"}",
  "stream":"stdout",
  "time":"2014-09-25T21:15:03.499185026Z",
  "kubernetes": {
    "namespace": "default",
    "pod_name": "rails-pod",
    "container_name": "rails-app"
  },
  "docker": {
    "container_id": "801599971ee6366d4a5921f25b79286ad45ff37a74494f260c3bc98d909d0a7b"
  }
}

Я ищу способ фильтровать / анализировать / извлекать эти данные в нечто похожее на это:

{
  "rails-log": {
    "method": "GET",
    "path": "/",
    "format": "html",
    "controller": "HomeController",
    "action": "index",
    ...
    "message": "[200] GET / (HomeController#index)"
  },
  "stream":"stdout",
  "time":"2014-09-25T21:15:03.499185026Z",
  "kubernetes": {
    "namespace": "default",
    "pod_name": "rails-pod",
    "container_name": "rails-app"
  },
  "docker": {
    "container_id": "801599971ee6366d4a5921f25b79286ad45ff37a74494f260c3bc98d909d0a7b"
  }
}

У меня есть ощущение, что это может быть достигнуто путем разбора / фильтрации, я просто не уверен, как сделать это внутри плавных конфигов ( полные текущие конфиги можно найти здесь)

После запуска плагина Kubernetes (добавляет метаданные kubernetes к "полезной нагрузке") я могу выбрать (в Kibana) журналы из моей конкретной службы, выполнив запрос с фильтром: kubernetes.labels.app is '<service_name>', Поэтому это заставляет меня поверить, что есть способ сделать "условное извлечение / преобразование" поля "log" в нечто, с чем я могу работать.

1 ответ

Вы можете попробовать конфигурацию rails в свободном доступе здесь.

А для других типов журналов измените format соответственно. В зависимости от регулярного выражения Например:

 format /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/

Затем вы можете изменить ConfigMap для Kubernetes

kubectl -n kube-system edit configmap luentd-es-config-v0.1.5

Надеюсь, поможет!

Другие вопросы по тегам