Skip to content

Commit

Permalink
parser_json: fix wrong LoadError warning
Browse files Browse the repository at this point in the history
If Oj is not installed, LoadError with the empty message is raised.
So, the current condition `/\boj\z/.match?(ex.message)` does not work
and the following meaningless warning is displayed.

    {datetime} [warn]: #x {id} LoadError

After this fix, the log message will be:

    {datetime} [info]: #x {id} Oj is not installed, and failing back to
    Yajl for json parser

Refactor "rescue" logic because this falling back feature is
currently only for "oj" (LoadError can not occur for "json" and
"yajl").

Signed-off-by: Daijiro Fukuda <[email protected]>
Co-authored-by: Takuro Ashie <[email protected]>
  • Loading branch information
daipom and ashie committed Jun 12, 2024
1 parent ec6f307 commit d515b3a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
16 changes: 4 additions & 12 deletions lib/fluent/plugin/parser_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,15 @@ def configure(conf)
def configure_json_parser(name)
case name
when :oj
raise LoadError unless Fluent::OjOptions.available?
[Oj.method(:load), Oj::ParseError]
return [Oj.method(:load), Oj::ParseError] if Fluent::OjOptions.available?

log&.info "Oj is not installed, and failing back to Yajl for json parser"
configure_json_parser(:yajl)
when :json then [JSON.method(:load), JSON::ParserError]
when :yajl then [Yajl.method(:load), Yajl::ParseError]
else
raise "BUG: unknown json parser specified: #{name}"
end
rescue LoadError => ex
name = :yajl
if log
if /\boj\z/.match?(ex.message)
log.info "Oj is not installed, and failing back to Yajl for json parser"
else
log.warn ex.message
end
end
retry
end

def parse(text)
Expand Down
31 changes: 31 additions & 0 deletions test/plugin/test_parser_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,37 @@ def setup
@parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
end

sub_test_case "configure_json_parser" do
data("oj", [:oj, [Oj.method(:load), Oj::ParseError]])
data("json", [:json, [JSON.method(:load), JSON::ParserError]])
data("yajil", [:yajl, [Yajl.method(:load), Yajl::ParseError]])
def test_return_each_loader((input, expected_return))
result = @parser.instance.configure_json_parser(input)
assert_equal expected_return, result
end

def test_raise_exception_for_unknown_input
assert_raise RuntimeError do
@parser.instance.configure_json_parser(:unknown)
end
end

def test_fall_back_oj_to_yajl_if_oj_not_available
stub(Fluent::OjOptions).available? { false }

result = @parser.instance.configure_json_parser(:oj)

assert_equal [Yajl.method(:load), Yajl::ParseError], result
logs = @parser.logs.collect do |log|
log.gsub(/\A\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4} /, "")
end
assert_equal(
["[info]: Oj is not installed, and failing back to Yajl for json parser\n"],
logs
)
end
end

data('oj' => 'oj', 'yajl' => 'yajl')
def test_parse(data)
@parser.configure('json_parser' => data)
Expand Down

0 comments on commit d515b3a

Please sign in to comment.