与发送到Logstash相比,如何从syslog日志中检索标签?

时间:2019-05-15 13:42:45

标签: docker logstash syslog

我已经设置了Docker守护程序,以便使用daemon.json的以下配置将所有容器的日志转发到侦听端口5000的Logstash应用程序:

{
  "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的一部分;因此我不知道从哪里可以找到它。

1 个答案:

答案 0 :(得分:0)

该问题可能与您选择的日志驱动程序有关。 将日志驱动程序更改为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,logstash似乎默认为12201。

将消息发送到logstash之后,您可以创建管道以提取您选择的字段。例如[container_name]