Skip to content

Commit

Permalink
Fix json codec to accept json on a single line
Browse files Browse the repository at this point in the history
  • Loading branch information
nickethier committed Oct 9, 2013
1 parent 6711986 commit fd89b22
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
27 changes: 15 additions & 12 deletions lib/logstash/codecs/json.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "logstash/codecs/base"
require "logstash/codecs/line"
require "json"

# This codec will encode and decode JSON.
Expand All @@ -18,21 +19,23 @@ class LogStash::Codecs::JSON < LogStash::Codecs::Base
# For nxlog users, you'll want to set this to "CP1252"
config :charset, :validate => ::Encoding.name_list, :default => "UTF-8"

public
def initialize(params={})
super(params)
@lines = LogStash::Codecs::Line.new
@lines.charset = @charset
end

public
def decode(data)
data.force_encoding(@charset)
if @charset != "UTF-8"
# The user has declared the character encoding of this data is
# something other than UTF-8. Let's convert it (as cleanly as possible)
# into UTF-8 so we can use it with JSON, etc.
data = data.encode("UTF-8", :invalid => :replace, :undef => :replace)
end

begin
yield LogStash::Event.new(JSON.parse(data))
rescue JSON::ParserError => e
@logger.info("JSON parse failure. Falling back to plain-text", :error => e, :data => data)
yield LogStash::Event.new("message" => data)
@lines.decode(data) do |event|
begin
yield LogStash::Event.new(JSON.parse(event["message"]))
rescue JSON::ParserError => e
@logger.info("JSON parse failure. Falling back to plain-text", :error => e, :data => data)
yield LogStash::Event.new("message" => data)
end
end
end # def decode

Expand Down
13 changes: 13 additions & 0 deletions spec/codecs/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,21 @@

context "#decode" do
it "should return an event from json data" do
data = {"foo" => "bar", "baz" => {"bah" => ["a","b","c"]}}
subject.decode(data.to_json+"\n") do |event|
insist { event.is_a? LogStash::Event }
insist { event["foo"] } == data["foo"]
insist { event["baz"] } == data["baz"]
insist { event["bah"] } == data["bah"]
end
end

it "should return an event from json data when a newline is recieved" do
data = {"foo" => "bar", "baz" => {"bah" => ["a","b","c"]}}
subject.decode(data.to_json) do |event|
insist {false}
end
subject.decode("\n") do |event|
insist { event.is_a? LogStash::Event }
insist { event["foo"] } == data["foo"]
insist { event["baz"] } == data["baz"]
Expand Down

0 comments on commit fd89b22

Please sign in to comment.