如何从发送到 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 =&gt; "tag" =&gt; "%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 服务器

Logstash 如何与 Syslog 集成?

Python SysLogHandler -> syslog:logstash。设施未变

syslog 到 logstash _grokparsefailure

未设置 logback logstash 编码器 Syslog 标头

syslog+rsyslog+logstash+elasticsearch+kibana搭建日志收集