如何将 apache 日志从一个容器发送到另一个容器中的 logstash?
How to send apache logs from one container to a logstash in another container?
在过去的三天里,我一直在尝试从我 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
您的 apache2 容器可能仅将访问和错误记录到标准输出。
您有一个选择是添加另一个 运行s filebeat
配置为将数据推送到 logstash 的容器(您也需要调整 logstash 配置),在两者之间创建一个共享卷您的 apache 容器和这个新容器,最终使 apache 将日志写入 sared 卷。
看看 this link 如何在 docker
上 运行 filebeat
查看 this link 了解如何配置 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。
在过去的三天里,我一直在尝试从我 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
您的 apache2 容器可能仅将访问和错误记录到标准输出。
您有一个选择是添加另一个 运行s filebeat
配置为将数据推送到 logstash 的容器(您也需要调整 logstash 配置),在两者之间创建一个共享卷您的 apache 容器和这个新容器,最终使 apache 将日志写入 sared 卷。
看看 this link 如何在 docker
上 运行 filebeat查看 this link 了解如何配置 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。