Бит ввода в Logstash теряет поля

Имею следующую инфраструктуру:

ELK устанавливается как docker-контейнеры, каждый в своем контейнере. А на виртуальной машине под управлением CentOS я установил веб-сервер nginx и Filebeat для сбора логов. Я включил модуль nginx в filebeat.

> filebeat modules enable nginx

Перед тем, как запустить filebeat, я настроил его с помощью elasticsearch и установил его информационные панели на kibana.

config (я удалил ненужные комментарии из файла):

filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false

setup.kibana:
  host: "172.17.0.1:5601"

output.elasticsearch:
  hosts: ["172.17.0.1:9200"]

затем настроить его в elasticsearch и kibana

> filebeat setup -e --dashboards

Это нормально работает. На самом деле, если я оставлю так, все будет работать отлично. Я могу использовать собранные журналы в kibana и использовать панели мониторинга для NGinX, которые я установил с помощью указанной выше команды.

Я хочу передать журналы в Logstash. И вот моя конфигурация Logstash использует следующие конвейеры:

- pipeline.id: filebeat
  path.config: "config/filebeat.conf"

filebeat.conf:

input {
  beats {
    port => 5044
  }
}


#filter {
#  mutate {
#    add_tag => ["filebeat"]
#  }
#}


output {
  elasticsearch {
    hosts => ["elasticsearch0:9200"]
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }

  stdout { }
}

Заставляя журналы проходить через Logstash, в результате получается просто:

{
        "offset" => 6655,
      "@version" => "1",
    "@timestamp" => 2019-02-20T13:34:06.886Z,
       "message" => "10.0.2.2 - - [20/Feb/2019:08:33:58 -0500] \"GET / HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/71.0.3578.98 Chrome/71.0.3578.98 Safari/537.36\" \"-\"",
          "beat" => {
         "version" => "6.5.4",
            "name" => "localhost.localdomain",
        "hostname" => "localhost.localdomain"
    },
        "source" => "/var/log/nginx/access.log",
          "host" => {
                   "os" => {
             "version" => "7 (Core)",
            "codename" => "Core",
              "family" => "redhat",
            "platform" => "centos"
        },
                 "name" => "localhost.localdomain",
                   "id" => "18e7cb2506624fb6ae2dc3891d5d7172",
        "containerized" => true,
         "architecture" => "x86_64"
    },
       "fileset" => {
          "name" => "access",
        "module" => "nginx"
    },
          "tags" => [
        [0] "beats_input_codec_plain_applied"
    ],
         "input" => {
        "type" => "log"
    },
    "prospector" => {
        "type" => "log"
    }
}

В моем объекте отсутствует много полей. Должно было быть гораздо больше структурированной информации

ОБНОВЛЕНИЕ: это то, что я ожидаю вместо этого

{
  "_index": "filebeat-6.5.4-2019.02.20",
  "_type": "doc",
  "_id": "ssJPC2kBLsya0HU-3uwW",
  "_version": 1,
  "_score": null,
  "_source": {
    "offset": 9639,
    "nginx": {
      "access": {
        "referrer": "-",
        "response_code": "404",
        "remote_ip": "10.0.2.2",
        "method": "GET",
        "user_name": "-",
        "http_version": "1.1",
        "body_sent": {
          "bytes": "3650"
        },
        "remote_ip_list": [
          "10.0.2.2"
        ],
        "url": "/access",
        "user_agent": {
          "patch": "3578",
          "original": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/71.0.3578.98 Chrome/71.0.3578.98 Safari/537.36",
          "major": "71",
          "minor": "0",
          "os": "Ubuntu",
          "name": "Chromium",
          "os_name": "Ubuntu",
          "device": "Other"
        }
      }
    },
    "prospector": {
      "type": "log"
    },
    "read_timestamp": "2019-02-20T14:29:36.393Z",
    "source": "/var/log/nginx/access.log",
    "fileset": {
      "module": "nginx",
      "name": "access"
    },
    "input": {
      "type": "log"
    },
    "@timestamp": "2019-02-20T14:29:32.000Z",
    "host": {
      "os": {
        "codename": "Core",
        "family": "redhat",
        "version": "7 (Core)",
        "platform": "centos"
      },
      "containerized": true,
      "name": "localhost.localdomain",
      "id": "18e7cb2506624fb6ae2dc3891d5d7172",
      "architecture": "x86_64"
    },
    "beat": {
      "hostname": "localhost.localdomain",
      "name": "localhost.localdomain",
      "version": "6.5.4"
    }
  },
  "fields": {
    "@timestamp": [
      "2019-02-20T14:29:32.000Z"
    ]
  },
  "sort": [
    1550672972000
  ]
}

person 500 Server error    schedule 20.02.2019    source источник
comment
Не похоже, что вы разбираете сообщение журнала. В документации по logstash есть пример: elastic.co/guide/en/logstash/6.6/   -  person baudsp    schedule 20.02.2019
comment
Спасибо чувак. это полезно. хотя я думал, что, поскольку filebeat отправляет напрямую в elasticsearch, отправляется полный объект, прохождение через logstash должно делать то же самое. И у меня это работало на моем локальном компьютере. Теперь я не могу заставить его работать. Я не выполнял никакой фильтрации в logstash, и у меня все работало. вот почему мне это так странно. @baudsp   -  person 500 Server error    schedule 20.02.2019
comment
Я не знаю. У меня очень мало опыта работы с filebeat, я даже не знал, что он может самостоятельно разбираться.   -  person baudsp    schedule 21.02.2019
comment
@baudsp, если у вас есть время, попробуйте использовать filebeat напрямую с elasticsearch и kibana. установите информационные панели и индексы следующим образом: filebeat setup --dashboards. включить какой-либо модуль, даже системный модуль: модули filebeat включают систему, а затем запустить ее. Попробуйте открыть одну из системных панелей на кибане. это довольно мило.   -  person 500 Server error    schedule 21.02.2019
comment
@baudsp ваш первый комментарий почти сработал. Это анализ данных, которого недостаточно для работы с предопределенными панелями мониторинга кибаны, но я буду строить их оттуда. Опубликуйте это как ответ, и я приму это, если хотите!   -  person 500 Server error    schedule 21.02.2019
comment
Похоже, это же обсуждение проходило здесь: обсуждение.elastic.co/t/   -  person Matthew Clark    schedule 17.10.2019


Ответы (2)


Судя по вашей конфигурации logstash, не похоже, что вы разбираете сообщение журнала.

Есть пример < / a> в документации logstash о том, как анализировать журналы nginx:

Журналы Nginx

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

  input {
    beats {
      port => 5044
      host => "0.0.0.0"
    }
  }
  filter {
    if [fileset][module] == "nginx" {
      if [fileset][name] == "access" {
        grok {
          match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\" \"%{DATA:[nginx][access][agent]}\""] }
          remove_field => "message"
        }
        mutate {
          add_field => { "read_timestamp" => "%{@timestamp}" }
        }
        date {
          match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
          remove_field => "[nginx][access][time]"
        }
        useragent {
          source => "[nginx][access][agent]"
          target => "[nginx][access][user_agent]"
          remove_field => "[nginx][access][agent]"
        }
        geoip {
          source => "[nginx][access][remote_ip]"
          target => "[nginx][access][geoip]"
        }
      }
      else if [fileset][name] == "error" {
        grok {
          match => { "message" => ["%{DATA:[nginx][error][time]} \[%{DATA:[nginx][error][level]}\] %{NUMBER:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: (\*%{NUMBER:[nginx][error][connection_id]} )?%{GREEDYDATA:[nginx][error][message]}"] }
          remove_field => "message"
        }
        mutate {
          rename => { "@timestamp" => "read_timestamp" }
        }
        date {
          match => [ "[nginx][error][time]", "YYYY/MM/dd H:m:s" ]
          remove_field => "[nginx][error][time]"
        }
      }
    }
  }

Я знаю, что это не касается того, почему filebeat не отправляет в logstash полный объект, но он должен дать начало тому, как анализировать журналы nginx в logstash.

person baudsp    schedule 21.02.2019
comment
Есть ли что-нибудь похожее на настройку auditbeat в logstash? Я не могу найти никаких примеров. - person 500 Server error; 21.02.2019
comment
@ 500Servererror Я ничего не нашел в документации. Придется написать самому. - person baudsp; 21.02.2019
comment
как ни странно auditbeat отправляет все поля - person 500 Server error; 21.02.2019
comment
У меня точно такая же проблема, как описано в исходном вопросе: Filebeat, отправляющий журналы Nginx через Logstash, а не напрямую в Elastic Search, приводит к отсутствию почти всех интересных полей (все, что я хочу видеть, все еще только в сообщении поле). У меня есть конфигурация Logstash точно такая же, как указано выше (из того же источника), поэтому, если мне не хватает чего-то еще, это не похоже на решение. - person Matthew Clark; 17.10.2019
comment
вероятно зависит от версии стека ELK. на этот вопрос уже был дан ответ почти год назад. - person 500 Server error; 19.10.2019

Ответ @baudsp был в основном правильным, но неполным. У меня была точно такая же проблема, и у меня также было точно такое же фильтр, упомянутый в документации (и в ответе @baudsp), но документы в Elastic Search по-прежнему не содержат ни одного из ожидаемых полей.

Я наконец нашел проблему: потому что у меня был настроен Filebeat для отправки журналов Nginx через модуль Nginx, а не Ввод журнала, данные, поступающие из Logbeat, не совсем соответствовали тому, что ожидал пример фильтра Logstash.

Условным условием в примере является if [fileset][module] == "nginx", что верно, если Filebeat отправлял данные из входа журнала. Однако, поскольку данные журнала поступают из модуля Nginx, свойство fileset не содержит свойства module.

Чтобы фильтр работал с данными Logstash, поступающими из модуля Nginx, необходимо изменить условное выражение, чтобы искать что-то еще. Я обнаружил, что [event][module] работает вместо [fileset][module].

Рабочий фильтр:

filter {
  if [event][module] == "nginx" {
    if [fileset][name] == "access" {
      grok {
        match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\" \"%{DATA:[nginx][access][agent]}\""] }
        remove_field => "message"
      }
      mutate {
        add_field => { "read_timestamp" => "%{@timestamp}" }
      }
      date {
        match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
        remove_field => "[nginx][access][time]"
      }
      useragent {
        source => "[nginx][access][agent]"
        target => "[nginx][access][user_agent]"
        remove_field => "[nginx][access][agent]"
      }
      geoip {
        source => "[nginx][access][remote_ip]"
        target => "[nginx][access][geoip]"
      }
    }
    else if [fileset][name] == "error" {
      grok {
        match => { "message" => ["%{DATA:[nginx][error][time]} \[%{DATA:[nginx][error][level]}\] %{NUMBER:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: (\*%{NUMBER:[nginx][error][connection_id]} )?%{GREEDYDATA:[nginx][error][message]}"] }
        remove_field => "message"
      }
      mutate {
        rename => { "@timestamp" => "read_timestamp" }
      }
      date {
        match => [ "[nginx][error][time]", "YYYY/MM/dd H:m:s" ]
        remove_field => "[nginx][error][time]"
      }
    }
  }
}

Теперь документы в эластичном поиске имеют все ожидаемые поля:  Скриншот записи журнала доступа Nginx в эластичном поиске

Примечание. У вас будет такая же проблема с другими Модули Filebeat тоже. Просто используйте [event][module] вместо [fileset][module].

person Matthew Clark    schedule 17.10.2019