Как отправить журналы Apache из одного контейнера в журнал в другом контейнере?

Последние три дня я пытался собрать все журналы из контейнеров, которые есть в моем Docker, и отправить их в Logstash. Я работал со стеком ELK (Elasticsearch, Logstash и Kibana), и я использую Logspout в качестве маршрутизатора для этих журналов.

Все три экземпляра стека ELK работают в разных контейнерах. Я следовал этой настройке.

Мой текущий файл конфигурации Logstash выглядит так:

input {
  tcp {
    port => 5000
    type => syslog
  }
  udp {
    port => 5000
    type => syslog
  }
}

filter {
  if [type] == "syslog" {
    grok {
      match => { "message" => "%{SYSLOG5424PRI}%{NONNEGINT:ver} +(?:%{TIMESTAMP_ISO8601:ts}|-) +(?:%{HOSTNAME:containerid}|-) +(?:%{NOTSPACE:containername}|-) +(?:%{NOTSPACE:proc}|-) +(?:%{WORD:msgid}|-) +(?:%{SYSLOG5424SD:sd}|-|) +%{GREEDYDATA:msg}" }
    }
    syslog_pri { }
    date {
      match => [ "syslog_timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
    }
    if !("_grokparsefailure" in [tags]) {
      mutate {
        replace => [ "@source_host", "%{syslog_hostname}" ]
        replace => [ "@message", "%{syslog_message}" ]
      }
    }
    mutate {
      remove_field => [ "syslog_hostname", "syslog_message", "syslog_timestamp" ]
    }
  }
}

output {
  elasticsearch { host => "elasticsearch" }
  stdout { codec => rubydebug }
}

Моя текущая проблема заключается в том, что я регистрирую почти все необходимые события, за исключением ошибок и журналов доступа из моего контейнера apache2, называемого laravel2. Он регистрирует некоторые события из контейнера, но не все. Если я выдам ошибку, изменив файл index.php, он не будет корректно регистрироваться в asticsearch.

Какой тип конфигурации я должен иметь, чтобы иметь возможность получать эти журналы apache (как доступ, так и ошибки)? Я видел некоторые решения вокруг, но они имеют в качестве входного файла, который я не могу сделать, так как я запускаю вещи в разных контейнерах.

РЕДАКТИРОВАТЬ:

Мой новый файл logstash.sample.conf:

input {
  tcp {
    port => 5000
    type => syslog
  }
  udp {
    port => 5000
    type => syslog
  }
  beats {
    # The port to listen on for filebeat connections.
    port => 5044
    # The IP address to listen for filebeat connections.
    host => "0.0.0.0"
    type => apachelog
  }
}

filter {
  if [type] == "apachelog" {
    grok {
      match => { "message" => ["%{IPORHOST:[apache2][access][remote_ip]} - %{DATA:[apache2][access][user_name]} \[%{HTTPDATE:[apache2][access][time]}\] \"%{WORD:[apache2][access][method]} %{DATA:[apache2][access][url]} HTTP/%{NUMBER:[apache2][access][http_version]}\" %{NUMBER:[apache2][access][response_code]} %{NUMBER:[apache2][access][body_sent][bytes]}( \"%{DATA:[apache2][access][referrer]}\")?( \"%{DATA:[apache2][access][agent]}\")?",
        "%{IPORHOST:[apache2][access][remote_ip]} - %{DATA:[apache2][access][user_name]} \\[%{HTTPDATE:[apache2][access][time]}\\] \"-\" %{NUMBER:[apache2][access][response_code]} -" ] }
      remove_field => "message"
    }
    mutate {
      add_field => { "read_timestamp" => "%{@timestamp}" }
    }
    date {
      match => [ "[apache2][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
      remove_field => "[apache2][access][time]"
    }
    useragent {
      source => "[apache2][access][agent]"
      target => "[apache2][access][user_agent]"
      remove_field => "[apache2][access][agent]"
    }
    geoip {
      source => "[apache2][access][remote_ip]"
      target => "[apache2][access][geoip]"
    }
  }
  if [type] == "syslog" {
    grok {
      match => { "message" => "%{SYSLOG5424PRI}%{NONNEGINT:ver} +(?:%{TIMESTAMP_ISO8601:ts}|-) +(?:%{HOSTNAME:containerid}|-) +(?:%{NOTSPACE:containername}|-) +(?:%{NOTSPACE:proc}|-) +(?:%{WORD:msgid}|-) +(?:%{SYSLOG5424SD:sd}|-|) +%{GREEDYDATA:msg}" }
    }
    syslog_pri { }
    date {
      match => [ "syslog_timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
    }
    if !("_grokparsefailure" in [tags]) {
      mutate {
        replace => [ "@source_host", "%{syslog_hostname}" ]
        replace => [ "@message", "%{syslog_message}" ]
      }
    }
    mutate {
      remove_field => [ "syslog_hostname", "syslog_message", "syslog_timestamp" ]
    }
  }
}

output {
  elasticsearch { 
    host => "elasticsearch"
  }
  stdout { codec => rubydebug }
}

И мой файл filebeat.full.yml:

#----------------------------- Logstash output ---------------------------------
#output.logstash:
  # Boolean flag to enable or disable the output module.
  enabled: true

  # The Logstash hosts
  hosts: ["localhost:5044"]

И, наконец, мой файл filebeat.yml:

filebeat.prospectors:
- input_type: log
  paths:
    - /var/log/apache2/access.log*
    - /var/log/apache2/other_vhosts_access.log*
  exclude_files: [".gz$"]

output.logstash:
  hosts: ["localhost:5044"]

processors:
- add_cloud_metadata:

output.elasticsearch:
  hosts: ['elasticsearch:9200']
  username: elastic
  password: changeme

1 ответ

Решение

Вероятно, ваш контейнер apache2 регистрирует доступ и ошибки только на стандартный вывод.

Один вариант у вас есть, чтобы добавить еще один контейнер, который работает filebeat сконфигурирован для отправки данных в logstash (вам также необходимо настроить конфигурацию logstash), создать общий том между вашим контейнером apache и этим новым контейнером, и, наконец, сделать записи в apache в сохраненном томе.

Посмотрите эту ссылку, чтобы узнать, как запустить filebeat на докере

Посмотрите эту ссылку, чтобы узнать, как настроить filebeat для отправки данных в logstash.

Наконец, посмотрите здесь, чтобы включить logstash для получения данных от filebeat

Прежде всего, вам нужно создать общий том:

docker volume create --name apache-logs

После этого вы можете запускать ваши док-контейнеры следующим образом:

docker run -v apache-logs:/var/log/apache2 ... apache:version
docker run -v apache-logs:/var/log/apache2 ... filebeat:version

Таким образом, контейнер 2 будет иметь общий каталог. Вам нужно настроить apache, чтобы записывать его журналы в /var/log/apache2 и настраивать filebeat для пересылки данных из /var/log/apache2 в logstash.

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