Logstash使用mutate.add_field创建一个嵌套字段

时间:2016-08-24 13:01:31

标签: logstash

我想在Logstash过滤器中复制一个嵌套字段,但我无法弄清楚正确的语法。 这是我尝试的:

语法错误:

mutate {
    add_field => { "received_from" => %{beat.hostname} }
}

beat.hostname未被替换

mutate {
    add_field => { "received_from" => "%{beat.hostname}" }
}

beat.hostname未被替换

mutate {
    add_field => { "received_from" => "%{[beat][hostname]}" }
}

beat.hostname未被替换

mutate {
    add_field => { "received_from" => "%[beat][hostname]" }
}

没办法。如果我给出一个非嵌套字段,它会按预期工作。

logstash收到的数据结构如下:

{
       "@timestamp" => "2016-08-24T13:01:28.369Z",
             "beat" => {
                "hostname" => "etg-dbs-master-tmp",
                "name" => "etg-dbs-master-tmp"
    },
            "count" => 1,
               "fs" => {
        "device_name" => "/dev/vdb",
              "total" => 5150212096,
               "used" => 99287040,
             "used_p" => 0.02,
               "free" => 5050925056,
              "avail" => 4765712384,
              "files" => 327680,
         "free_files" => 326476,
        "mount_point" => "/opt/ws-etg/datas"
    },
             "type" => "filesystem",
         "@version" => "1",
             "tags" => [
                [0] "topbeat"
              ],
      "received_at" => "2016-08-24T13:01:28.369Z",
    "received_from" => "%[beat][hostname]"
}

1 个答案:

答案 0 :(得分:19)

编辑:

由于您没有显示输入消息,因此我处理了您的输出。在您的输出中,您尝试复制的字段已存在,这就是您需要使用replace的原因。如果它不存在,那么你需要使用add_field。我更新了两个案例的答案。

编辑2:我意识到你的问题可能是访问嵌套的值,所以我也添加了:)

你正在使用mutate过滤器错误/向后。

第一个错误:

您想要替换字段,而不是添加字段。在文档中,它为您提供“替换”选项。请参阅:https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-replace

第二个错误,你正在反向使用语法。看来你认为这是真的:

"text I want to write" => "Field I want to write it in" 

虽然这是真的:

"myDestinationFieldName" => "My Value to be in the field" 

有了这些知识,我们现在可以这样做:

mutate {
    replace => { "[test][a]" => "%{s}"}
}

或者如果你想实际添加一个新的NOT NOTISTOR FIELD:

mutate {
        add_field => {"[test][myNewField]" => "%{s}"}
}

或者使用嵌套字段的值添加新的现有字段:

mutate {
        add_field =>  {"some" => "%{[test][a]}"}
}

或者更多细节,在我的例子中:

input {
  stdin {
  }
}

filter {
    json {
        source => "message"
    }

    mutate {
        replace => { "[test][a]" => "%{s}"}
        add_field => {"[test][myNewField]" => "%{s}"}
        add_field => {"some" => "%{[test][a]}"}
    }
}

output {
          stdout { codec => rubydebug }
}

此示例将stdin和输出带到stdout。它使用json过滤器来解析消息,然后使用mutate过滤器来替换嵌套字段。我还在嵌套的测试对象中添加了一个全新的字段。 最后创建一个具有test.a

值的新字段“some”

所以对于这条消息:

{"test" : { "a": "hello"}, "s" : "to_Repalce"}

我们想用s(值:“to_Repalce”)替换test.a(值:“Hello”),并添加一个值为s的test.myNewField字段。

在我的终端上:

artur@pandaadb:~/dev/logstash$ ./logstash-2.3.2/bin/logstash -f conf2/
Settings: Default pipeline workers: 8
Pipeline main started
{"test" : { "a": "hello"}, "s" : "to_Repalce"}
{
   "message" => "{\"test\" : { \"a\": \"hello\"}, \"s\" : \"to_Repalce\"}",
  "@version" => "1",
"@timestamp" => "2016-08-24T14:39:52.002Z",
      "host" => "pandaadb",
      "test" => {
             "a" => "to_Repalce",
    "myNewField" => "to_Repalce"
},
         "s" => "to_Repalce"
         "some" => "to_Repalce"
}

该值已成功替换。

已添加具有替换值的字段“some”

添加了嵌套数组中的新字段。

如果你使用add_field,它会将a转换为数组并在那里附加你的值。

希望这能解决您的问题,

Artur