fluentd 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/example/copy_roundrobin.conf +39 -0
  3. data/example/filter_stdout.conf +5 -5
  4. data/example/in_forward.conf +2 -2
  5. data/example/in_http.conf +2 -2
  6. data/example/in_syslog.conf +2 -2
  7. data/example/in_tail.conf +2 -2
  8. data/example/in_tcp.conf +2 -2
  9. data/example/in_udp.conf +2 -2
  10. data/example/out_buffered_null.conf +32 -0
  11. data/example/out_copy.conf +4 -4
  12. data/example/out_file.conf +2 -2
  13. data/example/out_forward.conf +2 -2
  14. data/example/v0_12_filter.conf +8 -8
  15. data/fluentd.gemspec +1 -1
  16. data/lib/fluent/command/fluentd.rb +6 -1
  17. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  18. data/lib/fluent/compat/input.rb +1 -0
  19. data/lib/fluent/compat/output.rb +1 -0
  20. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  21. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  22. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  23. data/lib/fluent/compat/type_converter.rb +90 -0
  24. data/lib/fluent/config/configure_proxy.rb +24 -4
  25. data/lib/fluent/config/dsl.rb +18 -1
  26. data/lib/fluent/config/v1_parser.rb +3 -2
  27. data/lib/fluent/configurable.rb +1 -1
  28. data/lib/fluent/event.rb +37 -9
  29. data/lib/fluent/mixin.rb +12 -286
  30. data/lib/fluent/plugin/buffer.rb +2 -2
  31. data/lib/fluent/plugin/in_dummy.rb +5 -1
  32. data/lib/fluent/plugin/in_gc_stat.rb +7 -37
  33. data/lib/fluent/plugin/in_http.rb +2 -0
  34. data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +0 -0
  35. data/lib/fluent/plugin/out_buffered_stdout.rb +60 -0
  36. data/lib/fluent/plugin/out_copy.rb +8 -51
  37. data/lib/fluent/plugin/out_null.rb +5 -5
  38. data/lib/fluent/plugin/out_relabel.rb +5 -5
  39. data/lib/fluent/plugin/out_roundrobin.rb +13 -40
  40. data/lib/fluent/plugin/output.rb +9 -0
  41. data/lib/fluent/plugin_helper.rb +2 -0
  42. data/lib/fluent/plugin_helper/formatter.rb +138 -0
  43. data/lib/fluent/plugin_helper/inject.rb +112 -0
  44. data/lib/fluent/plugin_helper/parser.rb +138 -0
  45. data/lib/fluent/plugin_helper/storage.rb +64 -50
  46. data/lib/fluent/process.rb +6 -1
  47. data/lib/fluent/registry.rb +1 -1
  48. data/lib/fluent/supervisor.rb +20 -2
  49. data/lib/fluent/test.rb +30 -5
  50. data/lib/fluent/test/base.rb +2 -66
  51. data/lib/fluent/test/driver/base.rb +3 -0
  52. data/lib/fluent/test/driver/base_owned.rb +106 -0
  53. data/lib/fluent/test/driver/formatter.rb +30 -0
  54. data/lib/fluent/test/driver/multi_output.rb +52 -0
  55. data/lib/fluent/test/driver/owner.rb +32 -0
  56. data/lib/fluent/test/driver/parser.rb +30 -0
  57. data/lib/fluent/test/helpers.rb +54 -0
  58. data/lib/fluent/test/log.rb +73 -0
  59. data/lib/fluent/time.rb +71 -0
  60. data/lib/fluent/version.rb +1 -1
  61. data/test/compat/test_parser.rb +82 -0
  62. data/test/config/test_configure_proxy.rb +15 -0
  63. data/test/config/test_dsl.rb +180 -2
  64. data/test/helper.rb +2 -24
  65. data/test/plugin/test_in_gc_stat.rb +6 -6
  66. data/test/plugin/test_in_http.rb +49 -32
  67. data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +1 -1
  68. data/test/plugin/test_out_buffered_stdout.rb +108 -0
  69. data/test/plugin/test_out_copy.rb +88 -127
  70. data/test/plugin/test_out_null.rb +29 -0
  71. data/test/plugin/test_out_relabel.rb +28 -0
  72. data/test/plugin/test_out_roundrobin.rb +35 -29
  73. data/test/plugin/test_out_stdout.rb +4 -4
  74. data/test/plugin/test_output_as_buffered.rb +51 -0
  75. data/test/plugin/test_output_as_buffered_secondary.rb +13 -0
  76. data/test/plugin/test_parser_apache.rb +38 -0
  77. data/test/plugin/test_parser_apache2.rb +38 -0
  78. data/test/plugin/test_parser_apache_error.rb +40 -0
  79. data/test/plugin/test_parser_base.rb +32 -0
  80. data/test/plugin/test_parser_csv.rb +94 -0
  81. data/test/plugin/test_parser_json.rb +107 -0
  82. data/test/plugin/test_parser_labeled_tsv.rb +129 -0
  83. data/test/plugin/test_parser_multiline.rb +100 -0
  84. data/test/plugin/test_parser_nginx.rb +42 -0
  85. data/test/plugin/test_parser_none.rb +53 -0
  86. data/test/plugin/test_parser_regexp.rb +110 -0
  87. data/test/plugin/test_parser_syslog.rb +66 -0
  88. data/test/plugin/test_parser_time.rb +46 -0
  89. data/test/plugin/test_parser_tsv.rb +125 -0
  90. data/test/plugin_helper/test_child_process.rb +11 -2
  91. data/test/plugin_helper/test_formatter.rb +212 -0
  92. data/test/plugin_helper/test_inject.rb +388 -0
  93. data/test/plugin_helper/test_parser.rb +223 -0
  94. data/test/plugin_helper/test_retry_state.rb +40 -40
  95. data/test/plugin_helper/test_storage.rb +77 -10
  96. data/test/scripts/fluent/plugin/out_test.rb +22 -17
  97. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  98. data/test/test_event.rb +57 -0
  99. data/test/test_formatter.rb +0 -178
  100. data/test/test_output.rb +2 -152
  101. data/test/test_root_agent.rb +3 -2
  102. data/test/test_supervisor.rb +93 -26
  103. data/test/test_time_formatter.rb +186 -0
  104. metadata +69 -7
  105. data/test/test_parser.rb +0 -1087
@@ -0,0 +1,94 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/parser'
3
+ require 'fluent/plugin/parser'
4
+
5
+ class CSVParserTest < ::Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ data('array param' => '["time","c","d"]', 'string param' => 'time,c,d')
11
+ def test_parse(param)
12
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::CSVParser)
13
+ parser.configure('keys' => param, 'time_key' => 'time')
14
+ parser.instance.parse("2013/02/28 12:00:00,192.168.0.1,111") { |time, record|
15
+ assert_equal(event_time('2013/02/28 12:00:00', format: '%Y/%m/%d %H:%M:%S'), time)
16
+ assert_equal({
17
+ 'c' => '192.168.0.1',
18
+ 'd' => '111',
19
+ }, record)
20
+ }
21
+ end
22
+
23
+ data('array param' => '["c","d"]', 'string param' => 'c,d')
24
+ def test_parse_without_time(param)
25
+ time_at_start = Time.now.to_i
26
+
27
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::CSVParser)
28
+ parser.configure('keys' => param)
29
+ parser.instance.parse("192.168.0.1,111") { |time, record|
30
+ assert time && time >= time_at_start, "parser puts current time without time input"
31
+ assert_equal({
32
+ 'c' => '192.168.0.1',
33
+ 'd' => '111',
34
+ }, record)
35
+ }
36
+
37
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::CSVParser)
38
+ parser.instance.estimate_current_event = false
39
+ parser.configure('keys' => param, 'time_key' => 'time')
40
+ parser.instance.parse("192.168.0.1,111") { |time, record|
41
+ assert_equal({
42
+ 'c' => '192.168.0.1',
43
+ 'd' => '111',
44
+ }, record)
45
+ assert_nil time, "parser returns nil w/o time and if configured so"
46
+ }
47
+ end
48
+
49
+ def test_parse_with_keep_time_key
50
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::CSVParser)
51
+ parser.configure(
52
+ 'keys'=>'time',
53
+ 'time_key'=>'time',
54
+ 'time_format'=>"%d/%b/%Y:%H:%M:%S %z",
55
+ 'keep_time_key'=>'true',
56
+ )
57
+ text = '28/Feb/2013:12:00:00 +0900'
58
+ parser.instance.parse(text) do |time, record|
59
+ assert_equal text, record['time']
60
+ end
61
+ end
62
+
63
+ data('array param' => '["a","b","c","d","e","f"]', 'string param' => 'a,b,c,d,e,f')
64
+ def test_parse_with_null_value_pattern
65
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::CSVParser)
66
+ parser.configure(
67
+ 'keys'=>param,
68
+ 'time_key'=>'time',
69
+ 'null_value_pattern'=>'^(-|null|NULL)$'
70
+ )
71
+ parser.instance.parse("-,null,NULL,,--,nuLL") do |time, record|
72
+ assert_nil record['a']
73
+ assert_nil record['b']
74
+ assert_nil record['c']
75
+ assert_equal record['d'], ''
76
+ assert_equal record['e'], '--'
77
+ assert_equal record['f'], 'nuLL'
78
+ end
79
+ end
80
+
81
+ data('array param' => '["a","b"]', 'string param' => 'a,b')
82
+ def test_parse_with_null_empty_string
83
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::CSVParser)
84
+ parser.configure(
85
+ 'keys'=>param,
86
+ 'time_key'=>'time',
87
+ 'null_empty_string'=>true
88
+ )
89
+ parser.instance.parse(", ") do |time, record|
90
+ assert_nil record['a']
91
+ assert_equal record['b'], ' '
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,107 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/parser'
3
+ require 'fluent/plugin/parser'
4
+
5
+ class JsonParserTest < ::Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ @parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
9
+ end
10
+
11
+ data('oj' => 'oj', 'yajl' => 'yajl')
12
+ def test_parse(data)
13
+ @parser.configure('json_parser' => data)
14
+ @parser.instance.parse('{"time":1362020400,"host":"192.168.0.1","size":777,"method":"PUT"}') { |time, record|
15
+ assert_equal(event_time('2013-02-28 12:00:00 +0900').to_i, time)
16
+ assert_equal({
17
+ 'host' => '192.168.0.1',
18
+ 'size' => 777,
19
+ 'method' => 'PUT',
20
+ }, record)
21
+ }
22
+ end
23
+
24
+ data('oj' => 'oj', 'yajl' => 'yajl')
25
+ def test_parse_with_large_float(data)
26
+ @parser.configure('json_parser' => data)
27
+ @parser.instance.parse('{"num":999999999999999999999999999999.99999}') { |time, record|
28
+ assert_equal(Float, record['num'].class)
29
+ }
30
+ end
31
+
32
+ data('oj' => 'oj', 'yajl' => 'yajl')
33
+ def test_parse_without_time(data)
34
+ time_at_start = Time.now.to_i
35
+
36
+ @parser.configure('json_parser' => data)
37
+ @parser.instance.parse('{"host":"192.168.0.1","size":777,"method":"PUT"}') { |time, record|
38
+ assert time && time >= time_at_start, "parser puts current time without time input"
39
+ assert_equal({
40
+ 'host' => '192.168.0.1',
41
+ 'size' => 777,
42
+ 'method' => 'PUT',
43
+ }, record)
44
+ }
45
+
46
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
47
+ parser.instance.estimate_current_event = false
48
+ parser.configure('json_parser' => data)
49
+ parser.instance.parse('{"host":"192.168.0.1","size":777,"method":"PUT"}') { |time, record|
50
+ assert_equal({
51
+ 'host' => '192.168.0.1',
52
+ 'size' => 777,
53
+ 'method' => 'PUT',
54
+ }, record)
55
+ assert_nil time, "parser return nil w/o time and if specified so"
56
+ }
57
+ end
58
+
59
+ data('oj' => 'oj', 'yajl' => 'yajl')
60
+ def test_parse_with_invalid_time(data)
61
+ @parser.configure('json_parser' => data)
62
+ assert_raise Fluent::ParserError do
63
+ @parser.instance.parse('{"time":[],"k":"v"}') { |time, record| }
64
+ end
65
+ end
66
+
67
+ data('oj' => 'oj', 'yajl' => 'yajl')
68
+ def test_parse_float_time(data)
69
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
70
+ parser.configure('json_parser' => data)
71
+ text = "100.1"
72
+ parser.instance.parse("{\"time\":\"#{text}\"}") do |time, record|
73
+ assert_equal Time.at(text.to_f).to_i, time.sec
74
+ assert_equal Time.at(text.to_f).nsec, time.nsec
75
+ end
76
+ end
77
+
78
+ data('oj' => 'oj', 'yajl' => 'yajl')
79
+ def test_parse_with_keep_time_key(data)
80
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
81
+ format = "%d/%b/%Y:%H:%M:%S %z"
82
+ parser.configure(
83
+ 'time_format' => format,
84
+ 'keep_time_key' => 'true',
85
+ 'json_parser' => data
86
+ )
87
+ text = "28/Feb/2013:12:00:00 +0900"
88
+ parser.instance.parse("{\"time\":\"#{text}\"}") do |time, record|
89
+ assert_equal Time.strptime(text, format).to_i, time.sec
90
+ assert_equal text, record['time']
91
+ end
92
+ end
93
+
94
+ data('oj' => 'oj', 'yajl' => 'yajl')
95
+ def test_parse_with_keep_time_key_without_time_format(data)
96
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::JSONParser)
97
+ parser.configure(
98
+ 'keep_time_key' => 'true',
99
+ 'json_parser' => data
100
+ )
101
+ text = "100"
102
+ parser.instance.parse("{\"time\":\"#{text}\"}") do |time, record|
103
+ assert_equal text.to_i, time.sec
104
+ assert_equal text, record['time']
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,129 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/parser'
3
+ require 'fluent/plugin/parser'
4
+
5
+ class LabeledTSVParserTest < ::Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ def test_config_params
11
+ parser = Fluent::Test::Driver::Parser.new(Fluent::TextParser::LabeledTSVParser)
12
+
13
+ assert_equal "\t", parser.instance.delimiter
14
+ assert_equal ":", parser.instance.label_delimiter
15
+
16
+ parser.configure(
17
+ 'delimiter' => ',',
18
+ 'label_delimiter' => '=',
19
+ )
20
+
21
+ assert_equal ",", parser.instance.delimiter
22
+ assert_equal "=", parser.instance.label_delimiter
23
+ end
24
+
25
+ def test_parse
26
+ parser = Fluent::Test::Driver::Parser.new(Fluent::TextParser::LabeledTSVParser)
27
+ parser.configure({})
28
+ parser.instance.parse("time:2013/02/28 12:00:00\thost:192.168.0.1\treq_id:111") { |time, record|
29
+ assert_equal(event_time('2013/02/28 12:00:00', format: '%Y/%m/%d %H:%M:%S'), time)
30
+ assert_equal({
31
+ 'host' => '192.168.0.1',
32
+ 'req_id' => '111',
33
+ }, record)
34
+ }
35
+ end
36
+
37
+ def test_parse_with_customized_delimiter
38
+ parser = Fluent::Test::Driver::Parser.new(Fluent::TextParser::LabeledTSVParser)
39
+ parser.configure(
40
+ 'delimiter' => ',',
41
+ 'label_delimiter' => '=',
42
+ )
43
+ parser.instance.parse('time=2013/02/28 12:00:00,host=192.168.0.1,req_id=111') { |time, record|
44
+ assert_equal(event_time('2013/02/28 12:00:00', format: '%Y/%m/%d %H:%M:%S'), time)
45
+ assert_equal({
46
+ 'host' => '192.168.0.1',
47
+ 'req_id' => '111',
48
+ }, record)
49
+ }
50
+ end
51
+
52
+ def test_parse_with_customized_time_format
53
+ parser = Fluent::Test::Driver::Parser.new(Fluent::TextParser::LabeledTSVParser)
54
+ parser.configure(
55
+ 'time_key' => 'mytime',
56
+ 'time_format' => '%d/%b/%Y:%H:%M:%S %z',
57
+ )
58
+ parser.instance.parse("mytime:28/Feb/2013:12:00:00 +0900\thost:192.168.0.1\treq_id:111") { |time, record|
59
+ assert_equal(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
60
+ assert_equal({
61
+ 'host' => '192.168.0.1',
62
+ 'req_id' => '111',
63
+ }, record)
64
+ }
65
+ end
66
+
67
+ def test_parse_without_time
68
+ time_at_start = Time.now.to_i
69
+
70
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::LabeledTSVParser)
71
+ parser.configure({})
72
+ parser.instance.parse("host:192.168.0.1\treq_id:111") { |time, record|
73
+ assert time && time >= time_at_start, "parser puts current time without time input"
74
+ assert_equal({
75
+ 'host' => '192.168.0.1',
76
+ 'req_id' => '111',
77
+ }, record)
78
+ }
79
+
80
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::LabeledTSVParser)
81
+ parser.instance.estimate_current_event = false
82
+ parser.configure({})
83
+ parser.instance.parse("host:192.168.0.1\treq_id:111") { |time, record|
84
+ assert_equal({
85
+ 'host' => '192.168.0.1',
86
+ 'req_id' => '111',
87
+ }, record)
88
+ assert_nil time, "parser returns nil w/o time and if configured so"
89
+ }
90
+ end
91
+
92
+ def test_parse_with_keep_time_key
93
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::LabeledTSVParser)
94
+ parser.configure(
95
+ 'time_format'=>"%d/%b/%Y:%H:%M:%S %z",
96
+ 'keep_time_key'=>'true',
97
+ )
98
+ text = '28/Feb/2013:12:00:00 +0900'
99
+ parser.instance.parse("time:#{text}") do |time, record|
100
+ assert_equal text, record['time']
101
+ end
102
+ end
103
+
104
+ def test_parse_with_null_value_pattern
105
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::LabeledTSVParser)
106
+ parser.configure(
107
+ 'null_value_pattern'=>'^(-|null|NULL)$'
108
+ )
109
+ parser.instance.parse("a:-\tb:null\tc:NULL\td:\te:--\tf:nuLL") do |time, record|
110
+ assert_nil record['a']
111
+ assert_nil record['b']
112
+ assert_nil record['c']
113
+ assert_equal record['d'], ''
114
+ assert_equal record['e'], '--'
115
+ assert_equal record['f'], 'nuLL'
116
+ end
117
+ end
118
+
119
+ def test_parse_with_null_empty_string
120
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::LabeledTSVParser)
121
+ parser.configure(
122
+ 'null_empty_string'=>true
123
+ )
124
+ parser.instance.parse("a:\tb: ") do |time, record|
125
+ assert_nil record['a']
126
+ assert_equal record['b'], ' '
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,100 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/parser'
3
+ require 'fluent/plugin/parser'
4
+
5
+ class MultilineParserTest < ::Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ def create_parser(conf)
11
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::MultilineParser).configure(conf)
12
+ parser
13
+ end
14
+
15
+ def test_configure_with_invalid_params
16
+ [{'format100' => '/(?<msg>.*)/'}, {'format1' => '/(?<msg>.*)/', 'format3' => '/(?<msg>.*)/'}, 'format1' => '/(?<msg>.*)'].each { |config|
17
+ assert_raise(Fluent::ConfigError) {
18
+ create_parser(config)
19
+ }
20
+ }
21
+ end
22
+
23
+ def test_parse
24
+ parser = create_parser('format1' => '/^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}) \[(?<thread>.*)\] (?<level>[^\s]+)(?<message>.*)/')
25
+ parser.instance.parse(<<EOS.chomp) { |time, record|
26
+ 2013-3-03 14:27:33 [main] ERROR Main - Exception
27
+ javax.management.RuntimeErrorException: null
28
+ \tat Main.main(Main.java:16) ~[bin/:na]
29
+ EOS
30
+
31
+ assert_equal(event_time('2013-3-03 14:27:33').to_i, time)
32
+ assert_equal({
33
+ "thread" => "main",
34
+ "level" => "ERROR",
35
+ "message" => " Main - Exception\njavax.management.RuntimeErrorException: null\n\tat Main.main(Main.java:16) ~[bin/:na]"
36
+ }, record)
37
+ }
38
+ end
39
+
40
+ def test_parse_with_firstline
41
+ parser = create_parser('format_firstline' => '/----/', 'format1' => '/time=(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}).*message=(?<message>.*)/')
42
+ parser.instance.parse(<<EOS.chomp) { |time, record|
43
+ ----
44
+ time=2013-3-03 14:27:33
45
+ message=test1
46
+ EOS
47
+
48
+ assert(parser.instance.firstline?('----'))
49
+ assert_equal(event_time('2013-3-03 14:27:33').to_i, time)
50
+ assert_equal({"message" => "test1"}, record)
51
+ }
52
+ end
53
+
54
+ def test_parse_with_multiple_formats
55
+ parser = create_parser('format_firstline' => '/^Started/',
56
+ 'format1' => '/Started (?<method>[^ ]+) "(?<path>[^"]+)" for (?<host>[^ ]+) at (?<time>[^ ]+ [^ ]+ [^ ]+)\n/',
57
+ 'format2' => '/Processing by (?<controller>[^\u0023]+)\u0023(?<controller_method>[^ ]+) as (?<format>[^ ]+?)\n/',
58
+ 'format3' => '/( Parameters: (?<parameters>[^ ]+)\n)?/',
59
+ 'format4' => '/ Rendered (?<template>[^ ]+) within (?<layout>.+) \([\d\.]+ms\)\n/',
60
+ 'format5' => '/Completed (?<code>[^ ]+) [^ ]+ in (?<runtime>[\d\.]+)ms \(Views: (?<view_runtime>[\d\.]+)ms \| ActiveRecord: (?<ar_runtime>[\d\.]+)ms\)/'
61
+ )
62
+ parser.instance.parse(<<EOS.chomp) { |time, record|
63
+ Started GET "/users/123/" for 127.0.0.1 at 2013-06-14 12:00:11 +0900
64
+ Processing by UsersController#show as HTML
65
+ Parameters: {"user_id"=>"123"}
66
+ Rendered users/show.html.erb within layouts/application (0.3ms)
67
+ Completed 200 OK in 4ms (Views: 3.2ms | ActiveRecord: 0.0ms)
68
+ EOS
69
+
70
+ assert(parser.instance.firstline?('Started GET "/users/123/" for 127.0.0.1...'))
71
+ assert_equal(event_time('2013-06-14 12:00:11 +0900').to_i, time)
72
+ assert_equal({
73
+ "method" => "GET",
74
+ "path" => "/users/123/",
75
+ "host" => "127.0.0.1",
76
+ "controller" => "UsersController",
77
+ "controller_method" => "show",
78
+ "format" => "HTML",
79
+ "parameters" => "{\"user_id\"=>\"123\"}",
80
+ "template" => "users/show.html.erb",
81
+ "layout" => "layouts/application",
82
+ "code" => "200",
83
+ "runtime" => "4",
84
+ "view_runtime" => "3.2",
85
+ "ar_runtime" => "0.0"
86
+ }, record)
87
+ }
88
+ end
89
+
90
+ def test_parse_with_keep_time_key
91
+ parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin::MultilineParser).configure(
92
+ 'format1' => '/^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2})/',
93
+ 'keep_time_key' => 'true'
94
+ )
95
+ text = '2013-3-03 14:27:33'
96
+ parser.instance.parse(text) { |time, record|
97
+ assert_equal text, record['time']
98
+ }
99
+ end
100
+ end
@@ -0,0 +1,42 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/parser'
3
+ require 'fluent/plugin/parser'
4
+
5
+ class NginxParserTest < ::Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ @parser = Fluent::Test::Driver::Parser.new(Fluent::Plugin.new_parser('nginx'))
9
+ @expected = {
10
+ 'remote' => '127.0.0.1',
11
+ 'host' => '192.168.0.1',
12
+ 'user' => '-',
13
+ 'method' => 'GET',
14
+ 'path' => '/',
15
+ 'code' => '200',
16
+ 'size' => '777',
17
+ 'referer' => '-',
18
+ 'agent' => 'Opera/12.0'
19
+ }
20
+ end
21
+
22
+ def test_parse
23
+ @parser.instance.parse('127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET / HTTP/1.1" 200 777 "-" "Opera/12.0"') { |time, record|
24
+ assert_equal(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
25
+ assert_equal(@expected, record)
26
+ }
27
+ end
28
+
29
+ def test_parse_with_empty_included_path
30
+ @parser.instance.parse('127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET /a[ ]b HTTP/1.1" 200 777 "-" "Opera/12.0"') { |time, record|
31
+ assert_equal(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
32
+ assert_equal(@expected.merge('path' => '/a[ ]b'), record)
33
+ }
34
+ end
35
+
36
+ def test_parse_without_http_version
37
+ @parser.instance.parse('127.0.0.1 192.168.0.1 - [28/Feb/2013:12:00:00 +0900] "GET /" 200 777 "-" "Opera/12.0"') { |time, record|
38
+ assert_equal(event_time('28/Feb/2013:12:00:00 +0900', format: '%d/%b/%Y:%H:%M:%S %z'), time)
39
+ assert_equal(@expected, record)
40
+ }
41
+ end
42
+ end