diff --git a/lib/logstash/filters/json.rb b/lib/logstash/filters/json.rb index 569bfe8f9..650b43e73 100644 --- a/lib/logstash/filters/json.rb +++ b/lib/logstash/filters/json.rb @@ -54,11 +54,17 @@ class LogStash::Filters::Json < LogStash::Filters::Base return unless event.include?(@source) + source = event[@source] if @target.nil? # Default is to write to the root of the event. dest = event.to_hash else - dest = event[@target] ||= {} + if @target == @source + # Overwrite source + dest = event[@target] = {} + else + dest = event[@target] ||= {} + end end begin @@ -66,13 +72,15 @@ class LogStash::Filters::Json < LogStash::Filters::Base # like your text is '[ 1,2,3 ]' JSON.parse gives you an array (correctly) # which won't merge into a hash. If someone needs this, we can fix it # later. - dest.merge!(JSON.parse(event[@source])) + dest.merge!(JSON.parse(source)) - # This is a hack to help folks who are mucking with @timestamp during - # their json filter. You aren't supposed to do anything with "@timestamp" - # outside of the date filter, but nobody listens... ;) - if event["@timestamp"].is_a?(String) - event["@timestamp"] = Time.parse(event["@timestamp"]).gmtime + # If no target, we target the root of the event object. This can allow + # you to overwrite @timestamp. If so, let's parse it as a timestamp! + if @target && event["@timestamp"].is_a?(String) + # This is a hack to help folks who are mucking with @timestamp during + # their json filter. You aren't supposed to do anything with + # "@timestamp" outside of the date filter, but nobody listens... ;) + event["@timestamp"] = Time.parse(event["@timestamp"]).utc end filter_matched(event) diff --git a/spec/filters/json.rb b/spec/filters/json.rb index 340bfb79c..5f596ed04 100644 --- a/spec/filters/json.rb +++ b/spec/filters/json.rb @@ -69,4 +69,21 @@ describe LogStash::Filters::Json do insist { subject["@timestamp"].to_json } == "\"2013-10-19T00:14:32.996Z\"" end end + + describe "source == target" do + config <<-CONFIG + filter { + json { + source => "example" + target => "example" + } + } + CONFIG + + sample({ "example" => "{ \"hello\": \"world\" }" }) do + insist { subject["example"] }.is_a?(Hash) + insist { subject["example"]["hello"] } == "world" + end + end + end