fluentd 0.12.40 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

Files changed (252) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +33 -21
  5. data/CONTRIBUTING.md +1 -0
  6. data/ChangeLog +810 -237
  7. data/README.md +0 -25
  8. data/Rakefile +2 -1
  9. data/Vagrantfile +17 -0
  10. data/appveyor.yml +35 -0
  11. data/example/filter_stdout.conf +5 -5
  12. data/example/in_forward.conf +2 -2
  13. data/example/in_http.conf +2 -2
  14. data/example/in_out_forward.conf +17 -0
  15. data/example/in_syslog.conf +2 -2
  16. data/example/in_tail.conf +2 -2
  17. data/example/in_tcp.conf +2 -2
  18. data/example/in_udp.conf +2 -2
  19. data/example/out_copy.conf +4 -4
  20. data/example/out_file.conf +2 -2
  21. data/example/out_forward.conf +2 -2
  22. data/example/out_forward_buf_file.conf +23 -0
  23. data/example/v0_12_filter.conf +8 -8
  24. data/fluent.conf +29 -0
  25. data/fluentd.gemspec +18 -11
  26. data/lib/fluent/agent.rb +60 -58
  27. data/lib/fluent/command/cat.rb +1 -1
  28. data/lib/fluent/command/debug.rb +7 -5
  29. data/lib/fluent/command/fluentd.rb +97 -2
  30. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  31. data/lib/fluent/compat/filter.rb +50 -0
  32. data/lib/fluent/compat/formatter.rb +109 -0
  33. data/lib/fluent/compat/input.rb +50 -0
  34. data/lib/fluent/compat/output.rb +617 -0
  35. data/lib/fluent/compat/output_chain.rb +60 -0
  36. data/lib/fluent/compat/parser.rb +163 -0
  37. data/lib/fluent/compat/propagate_default.rb +62 -0
  38. data/lib/fluent/config.rb +23 -20
  39. data/lib/fluent/config/configure_proxy.rb +119 -70
  40. data/lib/fluent/config/dsl.rb +5 -18
  41. data/lib/fluent/config/element.rb +72 -8
  42. data/lib/fluent/config/error.rb +0 -3
  43. data/lib/fluent/config/literal_parser.rb +0 -2
  44. data/lib/fluent/config/parser.rb +4 -4
  45. data/lib/fluent/config/section.rb +39 -28
  46. data/lib/fluent/config/types.rb +2 -13
  47. data/lib/fluent/config/v1_parser.rb +1 -3
  48. data/lib/fluent/configurable.rb +48 -16
  49. data/lib/fluent/daemon.rb +15 -0
  50. data/lib/fluent/engine.rb +26 -52
  51. data/lib/fluent/env.rb +6 -4
  52. data/lib/fluent/event.rb +58 -11
  53. data/lib/fluent/event_router.rb +5 -5
  54. data/lib/fluent/filter.rb +2 -50
  55. data/lib/fluent/formatter.rb +4 -293
  56. data/lib/fluent/input.rb +2 -32
  57. data/lib/fluent/label.rb +2 -2
  58. data/lib/fluent/load.rb +3 -2
  59. data/lib/fluent/log.rb +107 -38
  60. data/lib/fluent/match.rb +0 -36
  61. data/lib/fluent/mixin.rb +117 -7
  62. data/lib/fluent/msgpack_factory.rb +62 -0
  63. data/lib/fluent/output.rb +7 -612
  64. data/lib/fluent/output_chain.rb +23 -0
  65. data/lib/fluent/parser.rb +4 -800
  66. data/lib/fluent/plugin.rb +100 -121
  67. data/lib/fluent/plugin/bare_output.rb +63 -0
  68. data/lib/fluent/plugin/base.rb +121 -0
  69. data/lib/fluent/plugin/buf_file.rb +101 -182
  70. data/lib/fluent/plugin/buf_memory.rb +9 -92
  71. data/lib/fluent/plugin/buffer.rb +473 -0
  72. data/lib/fluent/plugin/buffer/chunk.rb +135 -0
  73. data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
  74. data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
  75. data/lib/fluent/plugin/exec_util.rb +80 -75
  76. data/lib/fluent/plugin/file_util.rb +33 -28
  77. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  78. data/lib/fluent/plugin/filter.rb +51 -0
  79. data/lib/fluent/plugin/filter_grep.rb +13 -40
  80. data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
  81. data/lib/fluent/plugin/formatter.rb +93 -0
  82. data/lib/fluent/plugin/formatter_csv.rb +48 -0
  83. data/lib/fluent/plugin/formatter_hash.rb +32 -0
  84. data/lib/fluent/plugin/formatter_json.rb +47 -0
  85. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  86. data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
  87. data/lib/fluent/plugin/formatter_out_file.rb +45 -0
  88. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  89. data/lib/fluent/plugin/formatter_stdout.rb +39 -0
  90. data/lib/fluent/plugin/in_debug_agent.rb +4 -0
  91. data/lib/fluent/plugin/in_dummy.rb +22 -18
  92. data/lib/fluent/plugin/in_exec.rb +18 -8
  93. data/lib/fluent/plugin/in_forward.rb +36 -79
  94. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  95. data/lib/fluent/plugin/in_http.rb +21 -18
  96. data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
  97. data/lib/fluent/plugin/in_object_space.rb +6 -1
  98. data/lib/fluent/plugin/in_stream.rb +7 -3
  99. data/lib/fluent/plugin/in_syslog.rb +46 -95
  100. data/lib/fluent/plugin/in_tail.rb +51 -595
  101. data/lib/fluent/plugin/in_tcp.rb +8 -1
  102. data/lib/fluent/plugin/in_udp.rb +8 -14
  103. data/lib/fluent/plugin/input.rb +33 -0
  104. data/lib/fluent/plugin/multi_output.rb +95 -0
  105. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  106. data/lib/fluent/plugin/out_copy.rb +11 -7
  107. data/lib/fluent/plugin/out_exec.rb +15 -11
  108. data/lib/fluent/plugin/out_exec_filter.rb +18 -10
  109. data/lib/fluent/plugin/out_file.rb +34 -5
  110. data/lib/fluent/plugin/out_forward.rb +19 -9
  111. data/lib/fluent/plugin/out_null.rb +0 -14
  112. data/lib/fluent/plugin/out_roundrobin.rb +11 -7
  113. data/lib/fluent/plugin/out_stdout.rb +5 -7
  114. data/lib/fluent/plugin/out_stream.rb +3 -1
  115. data/lib/fluent/plugin/output.rb +979 -0
  116. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  117. data/lib/fluent/plugin/parser.rb +244 -0
  118. data/lib/fluent/plugin/parser_apache.rb +24 -0
  119. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  120. data/lib/fluent/plugin/parser_apache_error.rb +21 -0
  121. data/lib/fluent/plugin/parser_csv.rb +31 -0
  122. data/lib/fluent/plugin/parser_json.rb +79 -0
  123. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  124. data/lib/fluent/plugin/parser_multiline.rb +102 -0
  125. data/lib/fluent/plugin/parser_nginx.rb +24 -0
  126. data/lib/fluent/plugin/parser_none.rb +36 -0
  127. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  128. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  129. data/lib/fluent/plugin/socket_util.rb +120 -114
  130. data/lib/fluent/plugin/storage.rb +84 -0
  131. data/lib/fluent/plugin/storage_local.rb +116 -0
  132. data/lib/fluent/plugin/string_util.rb +16 -13
  133. data/lib/fluent/plugin_helper.rb +39 -0
  134. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  135. data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
  136. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  137. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  138. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  139. data/lib/fluent/plugin_helper/storage.rb +308 -0
  140. data/lib/fluent/plugin_helper/thread.rb +147 -0
  141. data/lib/fluent/plugin_helper/timer.rb +85 -0
  142. data/lib/fluent/plugin_id.rb +63 -0
  143. data/lib/fluent/process.rb +21 -30
  144. data/lib/fluent/registry.rb +21 -9
  145. data/lib/fluent/root_agent.rb +115 -40
  146. data/lib/fluent/supervisor.rb +330 -320
  147. data/lib/fluent/system_config.rb +42 -18
  148. data/lib/fluent/test.rb +6 -1
  149. data/lib/fluent/test/base.rb +23 -3
  150. data/lib/fluent/test/driver/base.rb +247 -0
  151. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  152. data/lib/fluent/test/driver/filter.rb +35 -0
  153. data/lib/fluent/test/driver/input.rb +31 -0
  154. data/lib/fluent/test/driver/output.rb +78 -0
  155. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  156. data/lib/fluent/test/filter_test.rb +0 -1
  157. data/lib/fluent/test/formatter_test.rb +2 -1
  158. data/lib/fluent/test/input_test.rb +23 -17
  159. data/lib/fluent/test/output_test.rb +28 -39
  160. data/lib/fluent/test/parser_test.rb +1 -1
  161. data/lib/fluent/time.rb +104 -1
  162. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  163. data/lib/fluent/version.rb +1 -1
  164. data/lib/fluent/winsvc.rb +72 -0
  165. data/test/compat/test_calls_super.rb +164 -0
  166. data/test/config/test_config_parser.rb +83 -0
  167. data/test/config/test_configurable.rb +547 -274
  168. data/test/config/test_configure_proxy.rb +146 -29
  169. data/test/config/test_dsl.rb +3 -181
  170. data/test/config/test_element.rb +274 -0
  171. data/test/config/test_literal_parser.rb +1 -1
  172. data/test/config/test_section.rb +79 -7
  173. data/test/config/test_system_config.rb +21 -0
  174. data/test/config/test_types.rb +3 -26
  175. data/test/helper.rb +78 -8
  176. data/test/plugin/test_bare_output.rb +118 -0
  177. data/test/plugin/test_base.rb +75 -0
  178. data/test/plugin/test_buf_file.rb +420 -521
  179. data/test/plugin/test_buf_memory.rb +32 -194
  180. data/test/plugin/test_buffer.rb +981 -0
  181. data/test/plugin/test_buffer_chunk.rb +110 -0
  182. data/test/plugin/test_buffer_file_chunk.rb +770 -0
  183. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  184. data/test/plugin/test_filter.rb +255 -0
  185. data/test/plugin/test_filter_grep.rb +2 -73
  186. data/test/plugin/test_filter_record_transformer.rb +24 -68
  187. data/test/plugin/test_filter_stdout.rb +6 -6
  188. data/test/plugin/test_in_debug_agent.rb +2 -0
  189. data/test/plugin/test_in_dummy.rb +11 -17
  190. data/test/plugin/test_in_exec.rb +6 -25
  191. data/test/plugin/test_in_forward.rb +112 -151
  192. data/test/plugin/test_in_gc_stat.rb +2 -0
  193. data/test/plugin/test_in_http.rb +106 -157
  194. data/test/plugin/test_in_object_space.rb +21 -5
  195. data/test/plugin/test_in_stream.rb +14 -13
  196. data/test/plugin/test_in_syslog.rb +30 -275
  197. data/test/plugin/test_in_tail.rb +95 -234
  198. data/test/plugin/test_in_tcp.rb +14 -0
  199. data/test/plugin/test_in_udp.rb +21 -13
  200. data/test/plugin/test_input.rb +122 -0
  201. data/test/plugin/test_multi_output.rb +180 -0
  202. data/test/plugin/test_out_buffered_null.rb +79 -0
  203. data/test/plugin/test_out_copy.rb +15 -2
  204. data/test/plugin/test_out_exec.rb +75 -25
  205. data/test/plugin/test_out_exec_filter.rb +74 -8
  206. data/test/plugin/test_out_file.rb +61 -7
  207. data/test/plugin/test_out_forward.rb +92 -15
  208. data/test/plugin/test_out_roundrobin.rb +1 -0
  209. data/test/plugin/test_out_stdout.rb +22 -13
  210. data/test/plugin/test_out_stream.rb +18 -0
  211. data/test/plugin/test_output.rb +515 -0
  212. data/test/plugin/test_output_as_buffered.rb +1540 -0
  213. data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
  214. data/test/plugin/test_output_as_buffered_retries.rb +808 -0
  215. data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
  216. data/test/plugin/test_output_as_standard.rb +362 -0
  217. data/test/plugin/test_owned_by.rb +35 -0
  218. data/test/plugin/test_storage.rb +167 -0
  219. data/test/plugin/test_storage_local.rb +8 -0
  220. data/test/plugin_helper/test_child_process.rb +599 -0
  221. data/test/plugin_helper/test_compat_parameters.rb +175 -0
  222. data/test/plugin_helper/test_event_emitter.rb +51 -0
  223. data/test/plugin_helper/test_event_loop.rb +52 -0
  224. data/test/plugin_helper/test_retry_state.rb +399 -0
  225. data/test/plugin_helper/test_storage.rb +411 -0
  226. data/test/plugin_helper/test_thread.rb +164 -0
  227. data/test/plugin_helper/test_timer.rb +100 -0
  228. data/test/scripts/exec_script.rb +0 -6
  229. data/test/scripts/fluent/plugin/out_test.rb +3 -0
  230. data/test/test_config.rb +13 -4
  231. data/test/test_event.rb +24 -13
  232. data/test/test_event_router.rb +8 -7
  233. data/test/test_event_time.rb +187 -0
  234. data/test/test_formatter.rb +13 -51
  235. data/test/test_input.rb +1 -1
  236. data/test/test_log.rb +239 -16
  237. data/test/test_mixin.rb +1 -1
  238. data/test/test_output.rb +53 -66
  239. data/test/test_parser.rb +105 -323
  240. data/test/test_plugin_helper.rb +81 -0
  241. data/test/test_root_agent.rb +4 -52
  242. data/test/test_supervisor.rb +272 -0
  243. data/test/test_unique_id.rb +47 -0
  244. metadata +180 -54
  245. data/lib/fluent/buffer.rb +0 -365
  246. data/lib/fluent/plugin/filter_parser.rb +0 -107
  247. data/lib/fluent/plugin/in_status.rb +0 -76
  248. data/lib/fluent/test/helpers.rb +0 -86
  249. data/test/plugin/data/log/foo/bar2 +0 -0
  250. data/test/plugin/test_filter_parser.rb +0 -744
  251. data/test/plugin/test_in_status.rb +0 -38
  252. data/test/test_buffer.rb +0 -624
@@ -1,76 +0,0 @@
1
- #
2
- # Fluentd
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
-
17
- module Fluent
18
- class StatusInput < Input
19
- Plugin.register_input('status', self)
20
-
21
- def initialize
22
- super
23
- end
24
-
25
- config_param :emit_interval, :time, :default => 60
26
- config_param :tag, :string
27
-
28
- class TimerWatcher < Coolio::TimerWatcher
29
- def initialize(interval, repeat, log, &callback)
30
- @callback = callback
31
- @log = log
32
- super(interval, repeat)
33
- end
34
-
35
- def on_timer
36
- @callback.call
37
- rescue
38
- # TODO log?
39
- @log.error $!.to_s
40
- @log.error_backtrace
41
- end
42
- end
43
-
44
- def configure(conf)
45
- super
46
- $log.warn "in_status plugin will be removed v0.14 or later. Use in_monitor_agent instead"
47
- end
48
-
49
- def start
50
- @loop = Coolio::Loop.new
51
- @timer = TimerWatcher.new(@emit_interval, true, log, &method(:on_timer))
52
- @loop.attach(@timer)
53
- @thread = Thread.new(&method(:run))
54
- end
55
-
56
- def shutdown
57
- @loop.watchers.each {|w| w.detach }
58
- @loop.stop
59
- @thread.join
60
- end
61
-
62
- def run
63
- @loop.run
64
- rescue
65
- log.error "unexpected error", :error=>$!.to_s
66
- log.error_backtrace
67
- end
68
-
69
- def on_timer
70
- now = Engine.now
71
- Status.each {|record|
72
- router.emit(@tag, now, record)
73
- }
74
- end
75
- end
76
- end
@@ -1,86 +0,0 @@
1
- #
2
- # Fluentd
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
-
17
- require 'fluent/config/element'
18
- require 'time'
19
- require 'fluent/time'
20
-
21
- module Fluent
22
- module Test
23
- module Helpers
24
- # See "Example Custom Assertion: http://test-unit.github.io/test-unit/en/Test/Unit/Assertions.html
25
- def assert_equal_event_time(expected, actual, message = nil)
26
- expected_s = "#{expected}"
27
- actual_s = "#{actual}"
28
- message = build_message(message, <<EOT, expected_s, actual_s)
29
- <?> time expected but was
30
- <?>.
31
- EOT
32
- assert_block(message) do
33
- expected.is_a?(Integer) && actual.is_a?(Integer) && expected == actual
34
- end
35
- end
36
-
37
- def config_element(name = 'test', argument = '', params = {}, elements = [])
38
- Fluent::Config::Element.new(name, argument, params, elements)
39
- end
40
-
41
- def event_time(str = nil, format: nil)
42
- if str
43
- if format
44
- Time.strptime(str, format).to_i
45
- else
46
- Time.parse(str).to_i
47
- end
48
- else
49
- Time.now.to_i
50
- end
51
- end
52
-
53
- def with_timezone(tz)
54
- oldtz, ENV['TZ'] = ENV['TZ'], tz
55
- yield
56
- ensure
57
- ENV['TZ'] = oldtz
58
- end
59
-
60
- def time2str(time, localtime: false, format: nil)
61
- if format
62
- if localtime
63
- Time.at(time).strftime(format)
64
- else
65
- Time.at(time).utc.strftime(format)
66
- end
67
- else
68
- if localtime
69
- Time.at(time).iso8601
70
- else
71
- Time.at(time).utc.iso8601
72
- end
73
- end
74
- end
75
-
76
- def capture_log(driver)
77
- tmp = driver.instance.log.out
78
- driver.instance.log.out = StringIO.new
79
- yield
80
- return driver.instance.log.out.string
81
- ensure
82
- driver.instance.log.out = tmp
83
- end
84
- end
85
- end
86
- end
File without changes
@@ -1,744 +0,0 @@
1
- require_relative '../helper'
2
- require 'timecop'
3
- require 'fluent/plugin/filter_parser'
4
- require 'flexmock/test_unit'
5
-
6
- class ParserFilterTest < Test::Unit::TestCase
7
- include FlexMock::TestCase
8
-
9
- setup do
10
- Fluent::Test.setup
11
- @time = Time.parse("2012-01-02 13:14:15")
12
- Timecop.freeze(@time)
13
- end
14
-
15
- teardown do
16
- Timecop.return
17
- end
18
-
19
- CONFIG = %[
20
- key_name message
21
- format /^(?<x>.)(?<y>.) (?<time>.+)$/
22
- time_format %Y%m%d%H%M%S
23
- reserve_data true
24
- ]
25
-
26
- def create_driver(conf=CONFIG,tag='test')
27
- Fluent::Test::FilterTestDriver.new(Fluent::ParserFilter, tag).configure(conf)
28
- end
29
-
30
- def test_configure
31
- assert_raise(Fluent::ConfigError) {
32
- d = create_driver('')
33
- }
34
- assert_raise(Fluent::ConfigError) {
35
- d = create_driver %[
36
- format unknown_format_that_will_never_be_implemented
37
- key_name foo
38
- ]
39
- }
40
- assert_nothing_raised {
41
- d = create_driver %[
42
- format /(?<x>.)/
43
- key_name foo
44
- ]
45
- }
46
- assert_nothing_raised {
47
- d = create_driver %[
48
- format /(?<x>.)/
49
- key_name foo
50
- ]
51
- }
52
- assert_nothing_raised {
53
- d = create_driver %[
54
- format /(?<x>.)/
55
- key_name foo
56
- ]
57
- }
58
- assert_nothing_raised {
59
- d = create_driver %[
60
- format /(?<x>.)/
61
- key_name foo
62
- ]
63
- }
64
- assert_nothing_raised {
65
- d = create_driver %[
66
- format json
67
- key_name foo
68
- ]
69
- }
70
- assert_nothing_raised {
71
- d = create_driver %[
72
- format ltsv
73
- key_name foo
74
- ]
75
- }
76
- assert_nothing_raised {
77
- d = create_driver %[
78
- format /^col1=(?<col1>.+) col2=(?<col2>.+)$/
79
- key_name message
80
- suppress_parse_error_log true
81
- ]
82
- }
83
- assert_nothing_raised {
84
- d = create_driver %[
85
- format /^col1=(?<col1>.+) col2=(?<col2>.+)$/
86
- key_name message
87
- suppress_parse_error_log false
88
- ]
89
- }
90
- d = create_driver %[
91
- key_name foo
92
- format /(?<x>.)/
93
- ]
94
- assert_equal false, d.instance.reserve_data
95
- end
96
-
97
- # CONFIG = %[
98
- # remove_prefix test
99
- # add_prefix parsed
100
- # key_name message
101
- # format /^(?<x>.)(?<y>.) (?<time>.+)$/
102
- # time_format %Y%m%d%H%M%S
103
- # reserve_data true
104
- # ]
105
- def test_filter
106
- d1 = create_driver(CONFIG, 'test.no.change')
107
- time = @time.to_i
108
- d1.run do
109
- d1.filter({'message' => '12 20120402182059'}, time)
110
- d1.filter({'message' => '34 20120402182100'}, time)
111
- d1.filter({'message' => '56 20120402182100'}, time)
112
- d1.filter({'message' => '78 20120402182101'}, time)
113
- d1.filter({'message' => '90 20120402182100'}, time)
114
- end
115
- filtered = d1.filtered_as_array
116
- assert_equal 5, filtered.length
117
-
118
- first = filtered[0]
119
- assert_equal 'test.no.change', first[0]
120
- assert_equal Time.parse("2012-04-02 18:20:59").to_i, first[1]
121
- assert_equal '1', first[2]['x']
122
- assert_equal '2', first[2]['y']
123
- assert_equal '12 20120402182059', first[2]['message']
124
-
125
- second = filtered[1]
126
- assert_equal 'test.no.change', second[0]
127
- assert_equal Time.parse("2012-04-02 18:21:00").to_i, second[1]
128
- assert_equal '3', second[2]['x']
129
- assert_equal '4', second[2]['y']
130
-
131
- third = filtered[2]
132
- assert_equal 'test.no.change', third[0]
133
- assert_equal Time.parse("2012-04-02 18:21:00").to_i, third[1]
134
- assert_equal '5', third[2]['x']
135
- assert_equal '6', third[2]['y']
136
-
137
- fourth = filtered[3]
138
- assert_equal 'test.no.change', fourth[0]
139
- assert_equal Time.parse("2012-04-02 18:21:01").to_i, fourth[1]
140
- assert_equal '7', fourth[2]['x']
141
- assert_equal '8', fourth[2]['y']
142
-
143
- fifth = filtered[4]
144
- assert_equal 'test.no.change', fifth[0]
145
- assert_equal Time.parse("2012-04-02 18:21:00").to_i, fifth[1]
146
- assert_equal '9', fifth[2]['x']
147
- assert_equal '0', fifth[2]['y']
148
-
149
- d2 = create_driver(%[
150
- tag parsed
151
- key_name data
152
- format /^(?<x>.)(?<y>.) (?<t>.+)$/
153
- ], 'test.no.change')
154
- time = @time.to_i
155
- d2.run do
156
- d2.filter({'data' => '12 20120402182059'}, time)
157
- d2.filter({'data' => '34 20120402182100'}, time)
158
- end
159
- filtered = d2.filtered_as_array
160
- assert_equal 2, filtered.length
161
-
162
- first = filtered[0]
163
- assert_equal 'test.no.change', first[0]
164
- assert_equal time, first[1]
165
- assert_nil first[2]['data']
166
- assert_equal '1', first[2]['x']
167
- assert_equal '2', first[2]['y']
168
- assert_equal '20120402182059', first[2]['t']
169
-
170
- second = filtered[1]
171
- assert_equal 'test.no.change', second[0]
172
- assert_equal time, second[1]
173
- assert_nil second[2]['data']
174
- assert_equal '3', second[2]['x']
175
- assert_equal '4', second[2]['y']
176
- assert_equal '20120402182100', second[2]['t']
177
-
178
- d3 = create_driver(%[
179
- tag parsed
180
- key_name data
181
- format /^(?<x>[0-9])(?<y>[0-9]) (?<t>.+)$/
182
- ], 'test.no.change')
183
- time = @time.to_i
184
- d3.run do
185
- d3.filter({'data' => '12 20120402182059'}, time)
186
- d3.filter({'data' => '34 20120402182100'}, time)
187
- d3.filter({'data' => 'xy 20120402182101'}, time)
188
- end
189
- filtered = d3.filtered_as_array
190
- assert_equal 2, filtered.length
191
-
192
- d3x = create_driver(%[
193
- tag parsed
194
- key_name data
195
- format /^(?<x>\\d)(?<y>\\d) (?<t>.+)$/
196
- reserve_data yes
197
- ], 'test.no.change')
198
- time = @time.to_i
199
- d3x.run do
200
- d3x.filter({'data' => '12 20120402182059'}, time)
201
- d3x.filter({'data' => '34 20120402182100'}, time)
202
- d3x.filter({'data' => 'xy 20120402182101'}, time)
203
- end
204
- filtered = d3x.filtered_as_array
205
- assert_equal 3, filtered.length
206
-
207
- d4 = create_driver(%[
208
- tag parsed
209
- key_name data
210
- format json
211
- ], 'test.no.change')
212
- time = @time.to_i
213
- d4.run do
214
- d4.filter({'data' => '{"xxx":"first","yyy":"second"}', 'xxx' => 'x', 'yyy' => 'y'}, time)
215
- d4.filter({'data' => 'foobar', 'xxx' => 'x', 'yyy' => 'y'}, time)
216
- end
217
- filtered = d4.filtered_as_array
218
- assert_equal 1, filtered.length
219
-
220
- d4x = create_driver(%[
221
- tag parsed
222
- key_name data
223
- format json
224
- reserve_data yes
225
- ], 'test.no.change')
226
- time = @time.to_i
227
- d4x.run do
228
- d4x.filter({'data' => '{"xxx":"first","yyy":"second"}', 'xxx' => 'x', 'yyy' => 'y'}, time)
229
- d4x.filter({'data' => 'foobar', 'xxx' => 'x', 'yyy' => 'y'}, time)
230
- end
231
- filtered = d4x.filtered_as_array
232
- assert_equal 2, filtered.length
233
-
234
- first = filtered[0]
235
- assert_equal 'test.no.change', first[0]
236
- assert_equal time, first[1]
237
- assert_equal '{"xxx":"first","yyy":"second"}', first[2]['data']
238
- assert_equal 'first', first[2]['xxx']
239
- assert_equal 'second', first[2]['yyy']
240
-
241
- second = filtered[1]
242
- assert_equal 'test.no.change', second[0]
243
- assert_equal time, second[1]
244
- assert_equal 'foobar', second[2]['data']
245
- assert_equal 'x', second[2]['xxx']
246
- assert_equal 'y', second[2]['yyy']
247
- end
248
-
249
- CONFIG_LTSV = %[
250
- format ltsv
251
- key_name data
252
- ]
253
- def test_filter_ltsv
254
- d = create_driver(CONFIG_LTSV, 'test.no.change')
255
- time = @time.to_i
256
- d.run do
257
- d.filter({'data' => "xxx:first\tyyy:second", 'xxx' => 'x', 'yyy' => 'y'}, time)
258
- d.filter({'data' => "xxx:first\tyyy:second2", 'xxx' => 'x', 'yyy' => 'y'}, time)
259
- end
260
- filtered = d.filtered_as_array
261
- assert_equal 2, filtered.length
262
-
263
- first = filtered[0]
264
- assert_equal 'test.no.change', first[0]
265
- assert_equal time, first[1]
266
- assert_nil first[2]['data']
267
- assert_equal 'first', first[2]['xxx']
268
- assert_equal 'second', first[2]['yyy']
269
-
270
- second = filtered[1]
271
- assert_equal 'test.no.change', second[0]
272
- assert_equal time, second[1]
273
- assert_nil first[2]['data']
274
- assert_equal 'first', second[2]['xxx']
275
- assert_equal 'second2', second[2]['yyy']
276
-
277
- d = create_driver(CONFIG_LTSV + %[
278
- reserve_data yes
279
- ], 'test.no.change')
280
- time = @time.to_i
281
- d.run do
282
- d.filter({'data' => "xxx:first\tyyy:second", 'xxx' => 'x', 'yyy' => 'y'}, time)
283
- d.filter({'data' => "xxx:first\tyyy:second2", 'xxx' => 'x', 'yyy' => 'y'}, time)
284
- end
285
- filtered = d.filtered_as_array
286
- assert_equal 2, filtered.length
287
-
288
- first = filtered[0]
289
- assert_equal 'test.no.change', first[0]
290
- assert_equal time, first[1]
291
- assert_equal "xxx:first\tyyy:second", first[2]['data']
292
- assert_equal 'first', first[2]['xxx']
293
- assert_equal 'second', first[2]['yyy']
294
-
295
- second = filtered[1]
296
- assert_equal 'test.no.change', second[0]
297
- assert_equal time, second[1]
298
- assert_equal "xxx:first\tyyy:second", first[2]['data']
299
- assert_equal 'first', second[2]['xxx']
300
- assert_equal 'second2', second[2]['yyy']
301
-
302
- # convert types
303
- d = create_driver(CONFIG_LTSV + %[
304
- types i:integer,s:string,f:float,b:bool
305
- ], 'test.no.change')
306
- time = @time.to_i
307
- d.run do
308
- d.filter({'data' => "i:1\ts:2\tf:3\tb:true\tx:123"}, time)
309
- end
310
- filtered = d.filtered_as_array
311
- assert_equal 1, filtered.length
312
-
313
- first = filtered[0]
314
- assert_equal 'test.no.change', first[0]
315
- assert_equal time, first[1]
316
- assert_equal 1, first[2]['i']
317
- assert_equal '2', first[2]['s']
318
- assert_equal 3.0, first[2]['f']
319
- assert_equal true, first[2]['b']
320
- assert_equal '123', first[2]['x']
321
- end
322
-
323
- CONFIG_TSV = %[
324
- format tsv
325
- key_name data
326
- keys key1,key2,key3
327
- ]
328
- def test_filter_tsv
329
- d = create_driver(CONFIG_TSV, 'test.no.change')
330
- time = @time.to_i
331
- d.run do
332
- d.filter({'data' => "value1\tvalue2\tvalueThree", 'xxx' => 'x', 'yyy' => 'y'}, time)
333
- end
334
- filtered = d.filtered_as_array
335
- assert_equal 1, filtered.length
336
-
337
- first = filtered[0]
338
- assert_equal 'test.no.change', first[0]
339
- assert_equal time, first[1]
340
- assert_nil first[2]['data']
341
- assert_equal 'value1', first[2]['key1']
342
- assert_equal 'value2', first[2]['key2']
343
- assert_equal 'valueThree', first[2]['key3']
344
- end
345
-
346
- CONFIG_CSV = %[
347
- format csv
348
- key_name data
349
- keys key1,key2,key3
350
- ]
351
- def test_filter_csv
352
- d = create_driver(CONFIG_CSV, 'test.no.change')
353
- time = @time.to_i
354
- d.run do
355
- d.filter({'data' => 'value1,"value2","value""ThreeYes!"', 'xxx' => 'x', 'yyy' => 'y'}, time)
356
- end
357
- filtered = d.filtered_as_array
358
- assert_equal 1, filtered.length
359
-
360
- first = filtered[0]
361
- assert_equal 'test.no.change', first[0]
362
- assert_equal time, first[1]
363
- assert_nil first[2]['data']
364
- assert_equal 'value1', first[2]['key1']
365
- assert_equal 'value2', first[2]['key2']
366
- assert_equal 'value"ThreeYes!', first[2]['key3']
367
- end
368
-
369
- CONFIG_HASH_VALUE_FIELD = %[
370
- format json
371
- key_name data
372
- hash_value_field parsed
373
- ]
374
- CONFIG_HASH_VALUE_FIELD_RESERVE_DATA = %[
375
- format json
376
- key_name data
377
- reserve_data yes
378
- hash_value_field parsed
379
- ]
380
- CONFIG_HASH_VALUE_FIELD_WITH_INJECT_KEY_PREFIX = %[
381
- format json
382
- key_name data
383
- hash_value_field parsed
384
- inject_key_prefix data.
385
- ]
386
- def test_filter_inject_hash_value_field
387
- original = {'data' => '{"xxx":"first","yyy":"second"}', 'xxx' => 'x', 'yyy' => 'y'}
388
-
389
- d = create_driver(CONFIG_HASH_VALUE_FIELD, 'test.no.change')
390
- time = @time.to_i
391
- d.run do
392
- d.filter(original, time)
393
- end
394
- filtered = d.filtered_as_array
395
- assert_equal 1, filtered.length
396
-
397
- first = filtered[0]
398
- assert_equal 'test.no.change', first[0]
399
- assert_equal time, first[1]
400
-
401
- record = first[2]
402
- assert_equal 1, record.keys.size
403
- assert_equal({"xxx"=>"first","yyy"=>"second"}, record['parsed'])
404
-
405
- d = create_driver(CONFIG_HASH_VALUE_FIELD_RESERVE_DATA, 'test.no.change')
406
- time = @time.to_i
407
- d.run do
408
- d.filter(original, time)
409
- end
410
- filtered = d.filtered_as_array
411
- assert_equal 1, filtered.length
412
-
413
- first = filtered[0]
414
- assert_equal 'test.no.change', first[0]
415
- assert_equal time, first[1]
416
-
417
- record = first[2]
418
- assert_equal 4, record.keys.size
419
- assert_equal original['data'], record['data']
420
- assert_equal original['xxx'], record['xxx']
421
- assert_equal original['yyy'], record['yyy']
422
- assert_equal({"xxx"=>"first","yyy"=>"second"}, record['parsed'])
423
-
424
- d = create_driver(CONFIG_HASH_VALUE_FIELD_WITH_INJECT_KEY_PREFIX, 'test.no.change')
425
- time = @time.to_i
426
- d.run do
427
- d.filter(original, time)
428
- end
429
- filtered = d.filtered_as_array
430
- assert_equal 1, filtered.length
431
-
432
- first = filtered[0]
433
- assert_equal 'test.no.change', first[0]
434
- assert_equal time, first[1]
435
-
436
- record = first[2]
437
- assert_equal 1, record.keys.size
438
- assert_equal({"data.xxx"=>"first","data.yyy"=>"second"}, record['parsed'])
439
- end
440
-
441
- CONFIG_DONT_PARSE_TIME = %[
442
- key_name data
443
- format json
444
- time_parse no
445
- ]
446
- def test_time_should_be_reserved
447
- t = Time.now.to_i
448
- d = create_driver(CONFIG_DONT_PARSE_TIME, 'test.no.change')
449
-
450
- d.run do
451
- d.filter({'data' => '{"time":1383190430, "f1":"v1"}'}, t)
452
- d.filter({'data' => '{"time":"1383190430", "f1":"v1"}'}, t)
453
- d.filter({'data' => '{"time":"2013-10-31 12:34:03 +0900", "f1":"v1"}'}, t)
454
- end
455
- filtered = d.filtered_as_array
456
- assert_equal 3, filtered.length
457
-
458
- assert_equal 'test.no.change', filtered[0][0]
459
- assert_equal 'v1', filtered[0][2]['f1']
460
- assert_equal 1383190430, filtered[0][2]['time']
461
- assert_equal t, filtered[0][1]
462
-
463
- assert_equal 'test.no.change', filtered[1][0]
464
- assert_equal 'v1', filtered[1][2]['f1']
465
- assert_equal "1383190430", filtered[1][2]['time']
466
- assert_equal t, filtered[1][1]
467
-
468
- assert_equal 'test.no.change', filtered[2][0]
469
- assert_equal 'v1', filtered[2][2]['f1']
470
- assert_equal '2013-10-31 12:34:03 +0900', filtered[2][2]['time']
471
- assert_equal t, filtered[2][1]
472
- end
473
-
474
- CONFIG_INVALID_TIME_VALUE = %[
475
- remove_prefix test
476
- key_name data
477
- format json
478
- ] # 'time' is implicit @time_key
479
- def test_filter_invalid_time_data
480
- # should not raise errors
481
- t = Time.now.to_i
482
- d = create_driver(CONFIG_INVALID_TIME_VALUE, 'test.no.change')
483
- assert_nothing_raised {
484
- d.run do
485
- d.filter({'data' => '{"time":[], "f1":"v1"}'}, t)
486
- d.filter({'data' => '{"time":"thisisnottime", "f1":"v1"}'}, t)
487
- end
488
- }
489
- filtered = d.filtered_as_array
490
- assert_equal 1, filtered.length
491
-
492
- assert_equal 'test.no.change', filtered[0][0]
493
- assert_equal 0, filtered[0][1]
494
- assert_equal 'v1', filtered[0][2]['f1']
495
- assert_equal 0, filtered[0][2]['time'].to_i
496
- end
497
-
498
- # REGEXP = /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
499
-
500
- CONFIG_NOT_REPLACE = %[
501
- remove_prefix test
502
- key_name data
503
- format /^(?<message>.*)$/
504
- ]
505
- CONFIG_INVALID_BYTE = CONFIG_NOT_REPLACE + %[
506
- replace_invalid_sequence true
507
- ]
508
- def test_filter_invalid_byte
509
- invalid_utf8 = "\xff".force_encoding('UTF-8')
510
-
511
- d = create_driver(CONFIG_NOT_REPLACE, 'test.no.change')
512
- assert_raise(ArgumentError) {
513
- d.run do
514
- d.filter({'data' => invalid_utf8}, Time.now.to_i)
515
- end
516
- }
517
-
518
- d = create_driver(CONFIG_INVALID_BYTE, 'test.in')
519
- assert_nothing_raised {
520
- d.run do
521
- d.emit({'data' => invalid_utf8}, Time.now.to_i)
522
- end
523
- }
524
- filtered = d.filtered_as_array
525
- assert_equal 1, filtered.length
526
- assert_nil filtered[0][2]['data']
527
- assert_equal '?'.force_encoding('UTF-8'), filtered[0][2]['message']
528
-
529
- d = create_driver(CONFIG_INVALID_BYTE + %[
530
- reserve_data yes
531
- ], 'test.no.change')
532
- assert_nothing_raised {
533
- d.run do
534
- d.filter({'data' => invalid_utf8}, Time.now.to_i)
535
- end
536
- }
537
- filtered = d.filtered_as_array
538
- assert_equal 1, filtered.length
539
- assert_equal invalid_utf8, filtered[0][2]['data']
540
- assert_equal '?'.force_encoding('UTF-8'), filtered[0][2]['message']
541
-
542
- invalid_ascii = "\xff".force_encoding('US-ASCII')
543
- d = create_driver(CONFIG_INVALID_BYTE, 'test.no.change')
544
- assert_nothing_raised {
545
- d.run do
546
- d.filter({'data' => invalid_ascii}, Time.now.to_i)
547
- end
548
- }
549
- filtered = d.filtered_as_array
550
- assert_equal 1, filtered.length
551
- assert_nil filtered[0][2]['data']
552
- assert_equal '?'.force_encoding('US-ASCII'), filtered[0][2]['message']
553
- end
554
-
555
- CONFIG_NOT_IGNORE = %[
556
- remove_prefix test
557
- key_name data
558
- format json
559
- hash_value_field parsed
560
- ]
561
- CONFIG_IGNORE = CONFIG_NOT_IGNORE + %[
562
- ignore_key_not_exist true
563
- ]
564
- CONFIG_PASS_SAME_RECORD = CONFIG_IGNORE + %[
565
- reserve_data true
566
- ]
567
- def test_filter_key_not_exist
568
- d = create_driver(CONFIG_NOT_IGNORE, 'test.no.ignore')
569
- assert_nothing_raised {
570
- d.run do
571
- d.filter({'foo' => 'bar'}, Time.now.to_i)
572
- end
573
- }
574
- assert_match /data does not exist/, d.instance.log.out.logs.first
575
-
576
- d = create_driver(CONFIG_IGNORE, 'test.ignore')
577
- assert_nothing_raised {
578
- d.run do
579
- d.filter({'foo' => 'bar'}, Time.now.to_i)
580
- end
581
- }
582
- assert_not_match /data does not exist/, d.instance.log.out.logs.first
583
-
584
- d = create_driver(CONFIG_PASS_SAME_RECORD, 'test.pass_same_record')
585
- assert_nothing_raised {
586
- d.run do
587
- d.filter({'foo' => 'bar'}, Time.now.to_i)
588
- end
589
- }
590
- filtered = d.filtered_as_array
591
- assert_equal 1, filtered.length
592
- assert_nil filtered[0][2]['data']
593
- assert_equal 'bar', filtered[0][2]['foo']
594
-
595
- d = create_driver(CONFIG_NOT_IGNORE + "emit_invalid_record_to_error true", 'test.no.ignore')
596
- assert_nothing_raised {
597
- flexmock(d.instance.router).should_receive(:emit_error_event).
598
- with(String, Integer, Hash, ArgumentError).once
599
- d.run do
600
- d.filter({'foo' => 'bar'}, Time.now.to_i)
601
- end
602
- }
603
- end
604
-
605
- # suppress_parse_error_log test
606
- CONFIG_DISABELED_SUPPRESS_PARSE_ERROR_LOG = %[
607
- tag hogelog
608
- format /^col1=(?<col1>.+) col2=(?<col2>.+)$/
609
- key_name message
610
- suppress_parse_error_log false
611
- ]
612
- CONFIG_ENABELED_SUPPRESS_PARSE_ERROR_LOG = %[
613
- tag hogelog
614
- format /^col1=(?<col1>.+) col2=(?<col2>.+)$/
615
- key_name message
616
- suppress_parse_error_log true
617
- ]
618
- CONFIG_DEFAULT_SUPPRESS_PARSE_ERROR_LOG = %[
619
- tag hogelog
620
- format /^col1=(?<col1>.+) col2=(?<col2>.+)$/
621
- key_name message
622
- ]
623
-
624
- INVALID_MESSAGE = 'foo bar'
625
- VALID_MESSAGE = 'col1=foo col2=bar'
626
-
627
- # if call warn() raise exception
628
- class DummyLoggerWarnedException < StandardError; end
629
- class DummyLogger
630
- def reset
631
- end
632
- def warn(message)
633
- raise DummyLoggerWarnedException
634
- end
635
- end
636
-
637
- def swap_logger(instance)
638
- raise "use with block" unless block_given?
639
- dummy = DummyLogger.new
640
- saved_logger = instance.log
641
- instance.log = dummy
642
- restore = lambda{ instance.log = saved_logger }
643
-
644
- yield
645
-
646
- restore.call
647
- end
648
-
649
- def test_parser_error_warning
650
- d = create_driver(CONFIG_INVALID_TIME_VALUE, 'test.no.change')
651
- swap_logger(d.instance) do
652
- assert_raise(DummyLoggerWarnedException) {
653
- d.run do
654
- d.filter({'data' => '{"time":[], "f1":"v1"}'}, Time.now.to_i)
655
- end
656
- }
657
- end
658
- end
659
-
660
- class DefaultSuppressParseErrorLogTest < self
661
- def setup
662
- # default(disabled) 'suppress_parse_error_log' is not specify
663
- @d = create_driver(CONFIG_DEFAULT_SUPPRESS_PARSE_ERROR_LOG, 'test.no.change')
664
- end
665
-
666
- def test_raise_exception
667
- swap_logger(@d.instance) do
668
- assert_raise(DummyLoggerWarnedException) {
669
- @d.run do
670
- @d.filter({'message' => INVALID_MESSAGE}, Time.now.to_i)
671
- end
672
- }
673
- end
674
- end
675
-
676
- def test_nothing_raised
677
- swap_logger(@d.instance) do
678
- assert_nothing_raised {
679
- @d.run do
680
- @d.filter({'message' => VALID_MESSAGE}, Time.now.to_i)
681
- end
682
- }
683
- end
684
- end
685
- end
686
-
687
- class DisabledSuppressParseErrorLogTest < self
688
- def setup
689
- # disabled 'suppress_parse_error_log'
690
- @d = create_driver(CONFIG_DISABELED_SUPPRESS_PARSE_ERROR_LOG, 'test.no.change')
691
- end
692
-
693
- def test_raise_exception
694
- swap_logger(@d.instance) do
695
- assert_raise(DummyLoggerWarnedException) {
696
- @d.run do
697
- @d.filter({'message' => INVALID_MESSAGE}, Time.now.to_i)
698
- end
699
- }
700
- end
701
- end
702
-
703
- def test_nothing_raised
704
- assert_nothing_raised {
705
- @d.run do
706
- @d.filter({'message' => VALID_MESSAGE}, Time.now.to_i)
707
- end
708
- }
709
- end
710
- end
711
-
712
- class EnabledSuppressParseErrorLogTest < self
713
- def setup
714
- # enabled 'suppress_parse_error_log'
715
- @d = create_driver(CONFIG_ENABELED_SUPPRESS_PARSE_ERROR_LOG, 'test.no.change')
716
- end
717
-
718
- def test_nothing_raised
719
- assert_nothing_raised {
720
- @d.run do
721
- @d.filter({'message' => INVALID_MESSAGE}, Time.now.to_i)
722
- @d.filter({'message' => VALID_MESSAGE}, Time.now.to_i)
723
- end
724
- }
725
- end
726
- end
727
-
728
- class EmitInvalidRecordErrorTest < self
729
- def setup
730
- # enabled 'suppress_parse_error_log'
731
- @d = create_driver(CONFIG_ENABELED_SUPPRESS_PARSE_ERROR_LOG + "emit_invalid_record_to_error true", 'test.no.change')
732
- end
733
-
734
- def test_nothing_raised
735
- flexmock(@d.instance.router).should_receive(:emit_error_event).
736
- with(String, Integer, Hash, Fluent::ParserError).once
737
- assert_nothing_raised {
738
- @d.run do
739
- @d.filter({'message' => INVALID_MESSAGE}, Time.now.to_i)
740
- end
741
- }
742
- end
743
- end
744
- end