如何从发送到 Logstash 的系统日志中检索标签?
How can I retrieve the tag from the syslog logs that are sent to Logstash?
我已经设置了我的 Docker 守护进程,以便将我所有容器的日志转发到侦听端口 5000 的 Logstash 应用程序,对 daemon.json
使用以下配置:
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "udp://localhost:5000",
"syslog-format": "rfc3164",
"tag": "{{.Name}}"
},
"hosts": [
"tcp://0.0.0.0:2375",
"unix:///var/run/docker.sock"
]
}
由于许多不同的容器同时创建日志,我希望在我的 ELK 堆栈中可视化它们的日志时能够过滤容器名称。但是,我不确定如何在 Logstash 中检索我在上面的 Docker 守护程序配置中设置为 "log-opts" 一部分的 "tag"。
我尝试的是简单地将其作为变量检索并将其转发到 Logstash 配置中的字段,但它只是将文本“%{tag}”存储为字符串。是否可以在 Logstash 配置中检索源容器的标记?
logstash.conf :
input {
udp {
port => 5000
type => syslog
}
}
output {
elasticsearch {
hosts => ["elasticsearch"]
}
}
filter {
if [type] == "syslog" {
if [message] =~ "^<\d+>\s*\w+\s+\d+\s\d+:\d+:\d+\s\S+\s\w+(\/\S+|)\[\d+\]:.*$" {
grok {
match => {
"message" => "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:container_hash}(?:\[%{POSINT}\])?: %{GREEDYDATA:real_message}"
}
remove_field => ["message"]
}
mutate {
add_field => {
"tag" => "%{tag}"
}
}
}
}
}
编辑:如果我不像在 logstash 配置中那样删除 message
字段,那么当我在 Kibana 中查看日志时,message
字段看起来像这样:
<30>May 15 15:13:23 devlocal e9713f013ebb[1284]: 192.168.56.110 - - [15/May/2019:15:13:23 +0200] "GET /server/status HTTP/1.0" 200 54 0.003 "-" "GuzzleHttp/6.3.3 curl/7.64.0 PHP/7.2.17" "172.30.0.2"
所以我要找的 tag
不是 message
的一部分;因此我不知道从哪里可以取回它。
看起来问题可能与您选择的 log-driver 有关。
将 log-driver 更改为 gelf
应该可以让您访问标签和各种其他字段,例如以下
{
"_index": "logstash-2017.04.27",
"_type": "docker",
"_id": "AVuuiZbeYg9q2vv-JShe",
"_score": null,
"_source": {
"source_host": "172.18.0.1",
"level": 6,
"created": "2017-04-27T08:24:45.69023959Z",
"message": "My Message Thu Apr 27 08:31:44 UTC 2017",
"type": "docker",
"version": "1.1",
"command": "/bin/sh -c while true; do echo My Message `date`; sleep 1; done;",
"image_name": "alpine",
"@timestamp": "2017-04-27T08:31:44.338Z",
"container_name": "squarescaleweb_plop_1",
"host": "plop-xps",
"@version": "1",
"tag": "staging",
"image_id": "sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526",
"container_id": "12b7bcd3f2f54e017680090d01330f542e629a4528f558323e33f7894ec6be53"
},
"fields": {
"created": [
1493281485690
],
"@timestamp": [
1493281904338
]
},
"sort": [
1493281904338
]
}
example from:
https://gist.github.com/eunomie/e7a183602b8734c47058d277700fdc2d
您还需要通过 UDP 而不是 TCP 发送日志。
您可以将 daemon.json 更改为阅读
{
"log-driver": "syslog",
"log-opts": {
"gelf-address": "udp://localhost:<PORT>"
"tag": "{{.Name}}"
},
"hosts": [
"tcp://0.0.0.0:2375",
"unix:///var/run/docker.sock"
]
}
我不确定您将 logstash 配置为哪个端口来接收 UDP 数据包,但是对于 GELF,12201 似乎是 logstash 的默认端口。
将消息发送到 logstash 后,您可以创建一个管道来提取您选择的字段。例如[container_name]
我已经设置了我的 Docker 守护进程,以便将我所有容器的日志转发到侦听端口 5000 的 Logstash 应用程序,对 daemon.json
使用以下配置:
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "udp://localhost:5000",
"syslog-format": "rfc3164",
"tag": "{{.Name}}"
},
"hosts": [
"tcp://0.0.0.0:2375",
"unix:///var/run/docker.sock"
]
}
由于许多不同的容器同时创建日志,我希望在我的 ELK 堆栈中可视化它们的日志时能够过滤容器名称。但是,我不确定如何在 Logstash 中检索我在上面的 Docker 守护程序配置中设置为 "log-opts" 一部分的 "tag"。
我尝试的是简单地将其作为变量检索并将其转发到 Logstash 配置中的字段,但它只是将文本“%{tag}”存储为字符串。是否可以在 Logstash 配置中检索源容器的标记?
logstash.conf :
input {
udp {
port => 5000
type => syslog
}
}
output {
elasticsearch {
hosts => ["elasticsearch"]
}
}
filter {
if [type] == "syslog" {
if [message] =~ "^<\d+>\s*\w+\s+\d+\s\d+:\d+:\d+\s\S+\s\w+(\/\S+|)\[\d+\]:.*$" {
grok {
match => {
"message" => "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:container_hash}(?:\[%{POSINT}\])?: %{GREEDYDATA:real_message}"
}
remove_field => ["message"]
}
mutate {
add_field => {
"tag" => "%{tag}"
}
}
}
}
}
编辑:如果我不像在 logstash 配置中那样删除 message
字段,那么当我在 Kibana 中查看日志时,message
字段看起来像这样:
<30>May 15 15:13:23 devlocal e9713f013ebb[1284]: 192.168.56.110 - - [15/May/2019:15:13:23 +0200] "GET /server/status HTTP/1.0" 200 54 0.003 "-" "GuzzleHttp/6.3.3 curl/7.64.0 PHP/7.2.17" "172.30.0.2"
所以我要找的 tag
不是 message
的一部分;因此我不知道从哪里可以取回它。
看起来问题可能与您选择的 log-driver 有关。
将 log-driver 更改为 gelf
应该可以让您访问标签和各种其他字段,例如以下
{
"_index": "logstash-2017.04.27",
"_type": "docker",
"_id": "AVuuiZbeYg9q2vv-JShe",
"_score": null,
"_source": {
"source_host": "172.18.0.1",
"level": 6,
"created": "2017-04-27T08:24:45.69023959Z",
"message": "My Message Thu Apr 27 08:31:44 UTC 2017",
"type": "docker",
"version": "1.1",
"command": "/bin/sh -c while true; do echo My Message `date`; sleep 1; done;",
"image_name": "alpine",
"@timestamp": "2017-04-27T08:31:44.338Z",
"container_name": "squarescaleweb_plop_1",
"host": "plop-xps",
"@version": "1",
"tag": "staging",
"image_id": "sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526",
"container_id": "12b7bcd3f2f54e017680090d01330f542e629a4528f558323e33f7894ec6be53"
},
"fields": {
"created": [
1493281485690
],
"@timestamp": [
1493281904338
]
},
"sort": [
1493281904338
]
}
example from: https://gist.github.com/eunomie/e7a183602b8734c47058d277700fdc2d
您还需要通过 UDP 而不是 TCP 发送日志。 您可以将 daemon.json 更改为阅读
{
"log-driver": "syslog",
"log-opts": {
"gelf-address": "udp://localhost:<PORT>"
"tag": "{{.Name}}"
},
"hosts": [
"tcp://0.0.0.0:2375",
"unix:///var/run/docker.sock"
]
}
我不确定您将 logstash 配置为哪个端口来接收 UDP 数据包,但是对于 GELF,12201 似乎是 logstash 的默认端口。
将消息发送到 logstash 后,您可以创建一个管道来提取您选择的字段。例如[container_name]