【问题标题】:How to send apache logs from one container to a logstash in another container?如何将apache日志从一个容器发送到另一个容器中的logstash?
【发布时间】:2017-08-25 08:45:39
【问题描述】:

在过去的三天里,我一直在尝试从 Docker 中的容器中收集所有日志并将它们发送到 Logstash。我一直在使用 ELK Stack(Elasticsearch、Logstash 和 Kibana),并且我使用 Logspout 作为此日志的路由器。

ELK Stack 的所有三个实例都在不同的容器中运行。我关注了this setup。

我当前的 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 }
}

我目前的问题是,除了错误和来自名为 laravel2 的 apache2 容器的访问日志之外,我几乎记录了所有必要的事件。它记录来自容器的一些事件,但不是所有事件。如果我通过更改 index.php 文件产生错误,它将无法在 elasticsearch 中正确登录。

我需要什么类型的配置才能获得这个 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

【问题讨论】:

    标签: docker logging containers elastic-stack


    【解决方案1】:

    很可能,您的 apache2 容器仅将访问和错误记录到标准输出。

    您可以选择添加另一个运行filebeat 的容器,该容器配置为将数据推送到logstash(您也需要调整logstash 配置),最后在您的apache 容器和这个新容器之间创建一个共享卷,让apache在sared卷中写入日志。

    查看this 链接了解如何在 docker 上运行 filebeat

    查看this链接了解如何配置filebeat以将数据发送到logstash

    最后看here,让logstash能够从filebeat接收数据

    首先,你需要创建一个共享卷:

    docker volume create --name apache-logs
    

    之后,您可以像这样运行 docker 容器:

    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。

    【讨论】:

    • 我是否必须为 apache 创建一个新的 docker 镜像才能共享卷?
    • 不是为了共享卷,而是根据您的需要,您可能需要创建一个自定义映像来调整 Apache 的配置文件
    • 我对Docker还是有点青涩,不知道怎么弄,不过我试试,谢谢。
    • 我会尽力为您提供一些帮助
    • 非常感谢您的努力,仍然未能成功,但我会继续努力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多