Logstash http_poller で 取得したデータのfilter方法について

こんにちは。 http_poller pluginで取得したデータをfilterしたいと思っています。

http_pollerで得たデータは下記としまして、


"content" => [
  [0] {
    "AList" => [
      [0] {
        "name" => "X",
      },
      [1] {
        "name" => "Y,
      }
    ],
    "BList" => [
      [0] {
        "name" => "X",
      },
      [1] {
        "name" => "Y",
      }
    ],
  },

  [1] {
    "AList" => [
      [0] {
        "name" => "X",
      },
      [1] {
        "name" => "Y,
      }
    ],
    "BList" => [
      [0] {
        "name" => "X",
      },
      [1] {
        "name" => "Y",
      }
    ],
  }
],

"allFetched" => false,
"result" => true,
"number" => 0
}


以下のを削除したく
[content][0][AList]
[content][0][BlList]
[content][1][AList]
[content][1][BList]

以下にすれば削除してくれるのですが、[0]、[1]とある分指定する必要があり非常に非効率のため、
色々試してみたものの、かなっておりません。
お手数ですがアドバイスをいただけないでしょうか?

filter {
        mutate {
                remove_field => [
                "[content][0][AList]",
                "[content][1][AList]",
                "[content][0][BList]",
                "[content][1][BList]"
                ]
        }
}

@unisuke さん

こんばんは。ちょっと自分で試せていないのですが、参考までに。
残念ながら mutateremove_field ではワイルドカード指定のオプションがなさそうです。
代替え案として、 ruby フィルタを使うと、配列の要素でループしながら削除するスクリプトを書けそうです。

参考になりそうなコードスニペットを共有させていただきます。
配列の要素をループする例

event.get('db_user_details').each do |item|
  if item['country'] == 'india'
    event.set('flagger', 'done')
  end
end

フィールドを削除する例

event['outputdata'].keys.each { |k|
  event['outputdata'].delete(k) if k.start_with?('ID')
}

上記の二つを組み合わせればループしながら content 配列内のそれぞれで AListBList を削除できないでしょうか?

@Koji_Kawamura さん

コメント頂き大変ありがとうございます。
お返事が2日遅れて申し訳ありません。
やはりワイルドカードは無理ということがわかってよかったです。
rubyで頑張ればいけるのではと思っていたものの、あまりアイディアがなく、ご提示頂き大変ありがとうございます。
いちど試してみたいと思います。

@Koji_Kawamura さん
こんばんは。やっているもののruby力が足りなくて、うまくいきません。。
もし、具体的な案を頂けましたら幸いです。

こちらで試してみたところ、何もフィルターせずの結果でした。

input {
        http_poller {
                urls => {
                        db1 => {
                                method => POST
                                url => "http://xxx.com"
                                headers => {"Content-Type" => "application/json"}
                                body => '{"statuses": [ "OPEN"]"}'
                        }
                }
                request_timeout => 10
                schedule => {every => "30s"}
                codec => "json"
                metadata_target => "http_poller_metadata"
        }
}

filter {
        ruby {
                code => "
                        event.get('content').each do |num|
                                event['content'].keys.each { |k|
                                        event['content'].delete(k) if k.end_with?('List')
                                }
                        end
                "
        }
}

output {
        stdout {
                codec => rubydebug
        }
}

できました!
こちらのが大変ヒントというかそのままでしたいことができました。

filter {
        ruby {
                code => '
                        event.get("content").each_with_index { |b,index|
                                event.remove("[content][#{index}][AList]")
                        }
                '
        }
}
1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.