web-dev-qa-db-ja.com

Logstashは、mutate.add_fieldを使用してネストされたフィールドのコピーを作成します

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]"
}
13
jmcollin92

編集:

入力メッセージを表示しなかったので、出力を調整しました。出力には、コピー先のフィールドがすでに存在しているため、replaceを使用する必要があります。存在しない場合は、add_fieldを使用する必要があります。どちらの場合も回答を更新しました。

編集2:私はあなたの問題がネストされた値にアクセスすることであるかもしれないと気付いたので、私もそれを追加しました:)

mutateフィルターを間違って/逆方向に使用しています。

最初の間違い:

フィールドを追加するのではなく、置き換えたい。ドキュメントでは、「置換」オプションが提供されています。参照: https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-replace

2番目の間違いは、構文を逆に使用していることです。あなたはこれが真実であると信じているようです:

"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}"}
}

または実際に新しい存在しないフィールドを追加したい場合:

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"}

Test.a(値: "Hello")をs(値: "to_Repalce")に置き換え、フィールドtest.myNewFieldに値sを追加します。

私の端末で:

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"
}

値は正常に置き換えられました。

Replaces値を含むフィールド「some」が追加されました

ネストされた配列の新しいフィールドが追加されました。

add_fieldを使用すると、aが配列に変換され、そこに値が追加されます。

これで問題が解決することを願って、

アルトゥール

23
pandaadb