Skip to content

Commit

Permalink
Merge pull request #489 from takumakanari/add-csv-formatter
Browse files Browse the repository at this point in the history
add new csv formatter
  • Loading branch information
repeatedly committed Nov 24, 2014
2 parents 6463165 + fe2a1a0 commit 3874866
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/fluent/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,37 @@ def format(tag, time, record)
end
end

class CsvFormatter
include Configurable
include HandleTagAndTimeMixin

config_param :delimiter, :default => ',' do |val|
['\t', 'TAB'].include?(val) ? "\t" : val
end
config_param :force_quotes, :bool, :default => true
config_param :fields, :default => [] do |val|
val.split(',').map do |f|
f.strip!
f.size > 0 ? f : nil
end.compact
end

def initialize
super
require 'csv'
end

def format(tag, time, record)
filter_record(tag, time, record)
row = @fields.inject([]) do |memo, key|
memo << record[key]
memo
end
CSV.generate_line(row, :col_sep => @delimiter,
:force_quotes => @force_quotes)
end
end

class SingleValueFormatter
include Configurable

Expand All @@ -161,6 +192,7 @@ def format(tag, time, record)
'json' => Proc.new { JSONFormatter.new },
'msgpack' => Proc.new { MessagePackFormatter.new },
'ltsv' => Proc.new { LabeledTSVFormatter.new },
'csv' => Proc.new { CsvFormatter.new },
'single_value' => Proc.new { SingleValueFormatter.new },
}.each { |name, factory|
TEMPLATE_REGISTRY.register(name, factory)
Expand Down
112 changes: 112 additions & 0 deletions test/test_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,118 @@ def test_format_with_customized_delimiters
end
end

class CsvFormatterTest < ::Test::Unit::TestCase
include FormatterTest

def setup
@formatter = TextFormatter::CsvFormatter.new
@time = Engine.now
end

def test_config_params
assert_equal ',', @formatter.delimiter
assert_equal true, @formatter.force_quotes
assert_equal [], @formatter.fields
end

data(
'tab_char' => ["\t", '\t'],
'tab_string' => ["\t", 'TAB'],
'pipe' => ['|', '|'])
def test_config_params_with_customized_delimiters(data)
expected, target = data
@formatter.configure('delimiter' => target)
assert_equal expected, @formatter.delimiter
end

def test_format
@formatter.configure('fields' => 'message,message2')
formatted = @formatter.format(tag, @time, {
'message' => 'awesome',
'message2' => 'awesome2'
})
assert_equal("\"awesome\",\"awesome2\"\n", formatted)
end

def test_format_with_tag
@formatter.configure(
'fields' => 'tag,message,message2',
'include_tag_key' => 'true'
)
formatted = @formatter.format(tag, @time, {
'message' => 'awesome',
'message2' => 'awesome2'
})
assert_equal("\"tag\",\"awesome\",\"awesome2\"\n", formatted)
end

def test_format_with_time
@formatter.configure(
'fields' => 'time,message,message2',
'include_time_key' => 'true',
'time_format' => '%Y'
)
formatted = @formatter.format(tag, @time, {
'message' => 'awesome',
'message2' => 'awesome2'
})
assert_equal("\"#{Time.now.year}\",\"awesome\",\"awesome2\"\n",
formatted)
end

def test_format_with_customized_delimiters
@formatter.configure(
'fields' => 'message,message2',
'delimiter' => '\t'
)
formatted = @formatter.format(tag, @time, {
'message' => 'awesome',
'message2' => 'awesome2'
})
assert_equal("\"awesome\"\t\"awesome2\"\n", formatted)
end

def test_format_with_non_quote
@formatter.configure(
'fields' => 'message,message2',
'force_quotes' => 'false'
)
formatted = @formatter.format(tag, @time, {
'message' => 'awesome',
'message2' => 'awesome2'
})
assert_equal("awesome,awesome2\n", formatted)
end

data(
'nil' => {
'message' => 'awesome',
'message2' => nil,
'message3' => 'awesome3'
},
'blank' => {
'message' => 'awesome',
'message2' => '',
'message3' => 'awesome3'
})
def test_format_with_empty_fields(data)
@formatter.configure(
'fields' => 'message,message2,message3'
)
formatted = @formatter.format(tag, @time, data)
assert_equal("\"awesome\",\"\",\"awesome3\"\n", formatted)
end

data(
'normally' => 'one,two,three',
'white_space' => 'one , two , three',
'blank' => 'one,,two,three')
def test_config_params_with_fields(data)
@formatter.configure('fields' => data)
assert_equal %w(one two three), @formatter.fields
end
end

class SingleValueFormatterTest < ::Test::Unit::TestCase
include FormatterTest

Expand Down

0 comments on commit 3874866

Please sign in to comment.