如何从发送到 Logstash 的 syslog 日志中检索标签?
Posted
技术标签:
【中文标题】如何从发送到 Logstash 的 syslog 日志中检索标签?【英文标题】:How can I retrieve the tag from the syslog logs that are sent to Logstash? 【发布时间】:2019-05-15 13:42:44 【问题描述】:我已经设置了我的 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”一部分的“标签”。
我尝试的是简单地将其作为变量检索并将其转发到 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
的一部分;因此我不知道从哪里可以找回它。
【问题讨论】:
@baudsp 你指的是哪个 JSON? syslog 不会将日志行作为纯字符串传输吗? 对不起,我误读了您的问题。您能否从您的日志中发布一两条示例行? 同样在做add_field => "tag" => "%tag"
时,你添加了一个新的字段,叫做标签,它的值是一个已经存在的字段,这里是标签;所以如果字段标签之前不存在,它只会将%tag
放入其中。您必须编辑您的 grok 模式,以便它检索标签值。
@baudsp 我用 syslog 发送的日志行示例编辑了问题。如您所见,我正在寻找的 tag
不是其中的一部分
您的守护进程看起来已经在添加标签 - 您不需要在您的 logstash 管道中执行此操作。您可以通过条件过滤基于标签,例如if "tagName" in [tags]
【参考方案1】:
看起来问题可能与您选择的日志驱动程序有关。
将日志驱动程序更改为 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
]
示例来自: 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]
【讨论】:
谢谢!我花了一段时间才明白 syslog 对日志行来自哪些容器一无所知,但 gelf 知道。如果您想编辑它,只需对您的答案进行一些评论:1)我已经通过 UDP 发送日志(请参阅我的daemon.json
),但我必须将 gelf-address
替换为 syslog-address
。 2) 我为 Logstash 配置的端口显示在我共享的 logstash.conf
配置中:它是端口 5000。以上是关于如何从发送到 Logstash 的 syslog 日志中检索标签?的主要内容,如果未能解决你的问题,请参考以下文章
Logstash + Syslog 输入插件 VS Logstash + 文件输入插件 + Syslog 服务器
Python SysLogHandler -> syslog:logstash。设施未变
syslog 到 logstash _grokparsefailure