diff --git a/lib/logstash/filters/json.rb b/lib/logstash/filters/json.rb index b542431..010e5ec 100644 --- a/lib/logstash/filters/json.rb +++ b/lib/logstash/filters/json.rb @@ -52,6 +52,12 @@ class LogStash::Filters::Json < LogStash::Filters::Base # JSON in the value of the `source` field will be expanded into a # data structure in the `target` field. # + # The string in the `target` option may contain dynamic sprintf-style + # field references, i.e. the contents of one field can be used to choose + # the name of the target field. Dynamic field references can only refer + # to already existing fields, so the JSON string being parsed can't + # contain the name of the target field. + # # NOTE: if the `target` field already exists, it will be overwritten! config :target, :validate => :string @@ -83,7 +89,7 @@ def filter(event) end if @target - event.set(@target, parsed) + event.set(event.sprintf(@target), parsed) else unless parsed.is_a?(Hash) @tag_on_failure.each{|tag| event.tag(tag)} diff --git a/spec/filters/json_spec.rb b/spec/filters/json_spec.rb index 0cc296c..287c192 100644 --- a/spec/filters/json_spec.rb +++ b/spec/filters/json_spec.rb @@ -41,6 +41,23 @@ end end + describe "parse message into a dynamically named target field" do + config <<-CONFIG + filter { + json { + # Parse message as JSON, store the results in the field named + # by the contents of the 'target' field' + source => "message" + target => "%{target}" + } + } + CONFIG + + sample({"target" => "data", "message" => '{ "hello": "world" }'}) do + insist { subject.get("[data][hello]") } == "world" + end + end + describe "tag invalid json" do config <<-CONFIG filter {