Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide CRLF newline style choice on formatter plugins. Fix #3151 #3152

Merged
merged 5 commits into from
Oct 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions lib/fluent/plugin/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,29 @@ def format(tag, time, record)
@proc.call(tag, time, record)
end
end

module Newline
module Mixin
include Fluent::Configurable

DEFAULT_NEWLINE = if Fluent.windows?
:crlf
else
:lf
end

config_param :newline, :enum, list: [:lf, :crlf], default: DEFAULT_NEWLINE

def configure(conf)
super
@newline = case newline
when :lf
"\n"
when :crlf
"\r\n"
end
end
end
end
end
end
4 changes: 3 additions & 1 deletion lib/fluent/plugin/formatter_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
module Fluent
module Plugin
class HashFormatter < Formatter
include Fluent::Plugin::Newline::Mixin

Plugin.register_formatter('hash', self)

config_param :add_newline, :bool, default: true

def format(tag, time, record)
line = record.to_s
line << "\n".freeze if @add_newline
line << @newline.freeze if @add_newline
line
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/fluent/plugin/formatter_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
module Fluent
module Plugin
class JSONFormatter < Formatter
include Fluent::Plugin::Newline::Mixin

Plugin.register_formatter('json', self)

config_param :json_parser, :string, default: 'oj'
Expand All @@ -44,7 +46,7 @@ def configure(conf)
end

def format(tag, time, record)
"#{@dump_proc.call(record)}\n"
"#{@dump_proc.call(record)}#{@newline}"
end

def format_without_nl(tag, time, record)
Expand Down
4 changes: 3 additions & 1 deletion lib/fluent/plugin/formatter_ltsv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
module Fluent
module Plugin
class LabeledTSVFormatter < Formatter
include Fluent::Plugin::Newline::Mixin

Plugin.register_formatter('ltsv', self)

# http://ltsv.org/
Expand All @@ -34,7 +36,7 @@ def format(tag, time, record)
formatted << @delimiter if formatted.length.nonzero?
formatted << "#{label}#{@label_delimiter}#{value}"
end
formatted << "\n".freeze if @add_newline
formatted << @newline.freeze if @add_newline
formatted
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/fluent/plugin/formatter_out_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
module Fluent
module Plugin
class OutFileFormatter < Formatter
include Fluent::Plugin::Newline::Mixin

Plugin.register_formatter('out_file', self)

config_param :output_time, :bool, default: true
Expand All @@ -44,7 +46,7 @@ def format(tag, time, record)
header = ''
header << "#{@timef.format(time)}#{@delimiter}" if @output_time
header << "#{tag}#{@delimiter}" if @output_tag
"#{header}#{Yajl.dump(record)}\n"
"#{header}#{Yajl.dump(record)}#{@newline}"
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/fluent/plugin/formatter_single_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@
module Fluent
module Plugin
class SingleValueFormatter < Formatter
include Fluent::Plugin::Newline::Mixin

Plugin.register_formatter('single_value', self)

config_param :message_key, :string, default: 'message'
config_param :add_newline, :bool, default: true

def format(tag, time, record)
text = record[@message_key].to_s.dup
text << "\n" if @add_newline
text << @newline.freeze if @add_newline
text
end
end
Expand Down
4 changes: 3 additions & 1 deletion lib/fluent/plugin/formatter_tsv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
module Fluent
module Plugin
class TSVFormatter < Formatter
include Fluent::Plugin::Newline::Mixin

Plugin.register_formatter('tsv', self)

desc 'Field names included in each lines'
Expand All @@ -30,7 +32,7 @@ class TSVFormatter < Formatter

def format(tag, time, record)
formatted = @keys.map{|k| record[k].to_s }.join(@delimiter)
formatted << "\n".freeze if @add_newline
formatted << @newline.freeze if @add_newline
formatted
end
end
Expand Down
28 changes: 22 additions & 6 deletions test/command/test_binlog_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ def timezone(timezone = 'UTC')
end

class TestHead < TestBaseCommand
setup do
@default_newline = if Fluent.windows?
"\r\n"
else
"\n"
end
end

sub_test_case 'initialize' do
data(
'file is not passed' => %w(),
Expand Down Expand Up @@ -138,7 +146,7 @@ class TestHead < TestBaseCommand
create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
head = BinlogReaderCommand::Head.new(argv)
out = capture_stdout { head.call }
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n" * 5, out
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}" * 5, out
end
end

Expand All @@ -149,7 +157,7 @@ class TestHead < TestBaseCommand
create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
head = BinlogReaderCommand::Head.new(argv)
out = capture_stdout { head.call }
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n", out
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}", out
end
end

Expand All @@ -169,7 +177,7 @@ class TestHead < TestBaseCommand
create_message_packed_file(@file_name, [event_time(@t).to_i], [@record])
head = BinlogReaderCommand::Head.new(argv)
out = capture_stdout { head.call }
assert_equal "#{Yajl.dump(@record)}\n", out
assert_equal "#{Yajl.dump(@record)}#{@default_newline}", out
end
end

Expand Down Expand Up @@ -198,6 +206,14 @@ class TestHead < TestBaseCommand
end

class TestCat < TestBaseCommand
setup do
@default_newline = if Fluent.windows?
"\r\n"
else
"\n"
end
end

sub_test_case 'initialize' do
data(
'file is not passed' => [],
Expand Down Expand Up @@ -254,7 +270,7 @@ class TestCat < TestBaseCommand
create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
head = BinlogReaderCommand::Cat.new(argv)
out = capture_stdout { head.call }
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n" * 6, out
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}" * 6, out
end
end

Expand All @@ -265,7 +281,7 @@ class TestCat < TestBaseCommand
create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
head = BinlogReaderCommand::Cat.new(argv)
out = capture_stdout { head.call }
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n", out
assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}", out
end
end

Expand All @@ -276,7 +292,7 @@ class TestCat < TestBaseCommand
create_message_packed_file(@file_name, [event_time(@t).to_i], [@record])
head = BinlogReaderCommand::Cat.new(argv)
out = capture_stdout { head.call }
assert_equal "#{Yajl.dump(@record)}\n", out
assert_equal "#{Yajl.dump(@record)}#{@default_newline}", out
end
end

Expand Down
7 changes: 6 additions & 1 deletion test/plugin/test_filter_stdout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ def setup
@old_tz = ENV["TZ"]
ENV["TZ"] = "UTC"
Timecop.freeze
@default_newline = if Fluent.windows?
"\r\n"
else
"\n"
end
end

def teardown
Expand Down Expand Up @@ -106,7 +111,7 @@ def test_include_time_key
def test_format_json
d = create_driver(CONFIG + config_element("", "", { "format" => "json" }))
out = capture_log(d) { filter(d, event_time, {'test' => 'test'}) }
assert_equal "{\"test\":\"test\"}\n", out
assert_equal "{\"test\":\"test\"}#{@default_newline}", out
end
end

Expand Down
9 changes: 6 additions & 3 deletions test/plugin/test_formatter_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ def record
{'message' => 'awesome', 'greeting' => 'hello'}
end

def test_format
d = create_driver({})
data("newline (LF)" => ["lf", "\n"],
"newline (CRLF)" => ["crlf", "\r\n"])
def test_format(data)
newline_conf, newline = data
d = create_driver({"newline" => newline_conf})
formatted = d.instance.format(tag, @time, record)

assert_equal(%Q!{"message"=>"awesome", "greeting"=>"hello"}\n!, formatted.encode(Encoding::UTF_8))
assert_equal(%Q!{"message"=>"awesome", "greeting"=>"hello"}#{newline}!, formatted.encode(Encoding::UTF_8))
end

def test_format_without_newline
Expand Down
18 changes: 14 additions & 4 deletions test/plugin/test_formatter_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ class JsonFormatterTest < ::Test::Unit::TestCase

def setup
@time = event_time
@default_newline = if Fluent.windows?
"\r\n"
else
"\n"
end
end

def create_driver(conf = "")
Expand All @@ -25,12 +30,17 @@ def symbolic_record
{:message => :awesome}
end

data('oj' => 'oj', 'yajl' => 'yajl')
data('oj with LF' => ['oj', "lf", "\n"],
'oj with CRLF' => ['oj', "crlf", "\r\n"],
'yajl with LF' => ['yajl', "lf", "\n"],
'yajl with CRLF' => ['yajl', "crlf", "\r\n"]
)
def test_format(data)
d = create_driver('json_parser' => data)
parser, newline_conf, newline = data
d = create_driver('json_parser' => parser, 'newline' => newline_conf)
formatted = d.instance.format(tag, @time, record)

assert_equal("#{JSON.generate(record)}\n", formatted)
assert_equal("#{JSON.generate(record)}#{newline}", formatted)
end

data('oj' => 'oj', 'yajl' => 'yajl')
Expand All @@ -46,6 +56,6 @@ def test_format_with_symbolic_record(data)
d = create_driver('json_parser' => data)
formatted = d.instance.format(tag, @time, symbolic_record)

assert_equal("#{JSON.generate(record)}\n", formatted)
assert_equal("#{JSON.generate(record)}#{@default_newline}", formatted)
end
end
18 changes: 13 additions & 5 deletions test/plugin/test_formatter_ltsv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,14 @@ def test_config_params
assert_equal false, d.instance.add_newline
end

def test_format
d = create_driver({})
data("newline (LF)" => ["lf", "\n"],
"newline (CRLF)" => ["crlf", "\r\n"])
def test_format(data)
newline_conf, newline = data
d = create_driver({"newline" => newline_conf})
formatted = d.instance.format(tag, @time, record)

assert_equal("message:awesome\tgreeting:hello\n", formatted)
assert_equal("message:awesome\tgreeting:hello#{newline}", formatted)
end

def test_format_without_newline
Expand All @@ -50,13 +53,18 @@ def test_format_without_newline
assert_equal("message:awesome\tgreeting:hello", formatted)
end

def test_format_with_customized_delimiters
data("newline (LF)" => ["lf", "\n"],
"newline (CRLF)" => ["crlf", "\r\n"])
def test_format_with_customized_delimiters(data)
newline_conf, newline = data

d = create_driver(
'delimiter' => ',',
'label_delimiter' => '=',
'newline' => newline_conf,
)
formatted = d.instance.format(tag, @time, record)

assert_equal("message=awesome,greeting=hello\n", formatted)
assert_equal("message=awesome,greeting=hello#{newline}", formatted)
end
end