fluentd 0.12.43 → 0.14.0

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 (253) 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 +1239 -0
  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 +58 -640
  101. data/lib/fluent/plugin/in_tcp.rb +8 -1
  102. data/lib/fluent/plugin/in_udp.rb +8 -18
  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 +25 -19
  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 +119 -117
  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 -282
  198. data/test/plugin/test_in_tcp.rb +14 -0
  199. data/test/plugin/test_in_udp.rb +21 -67
  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 +181 -55
  245. data/CHANGELOG.md +0 -710
  246. data/lib/fluent/buffer.rb +0 -365
  247. data/lib/fluent/plugin/filter_parser.rb +0 -107
  248. data/lib/fluent/plugin/in_status.rb +0 -76
  249. data/lib/fluent/test/helpers.rb +0 -86
  250. data/test/plugin/data/log/foo/bar2 +0 -0
  251. data/test/plugin/test_filter_parser.rb +0 -744
  252. data/test/plugin/test_in_status.rb +0 -38
  253. data/test/test_buffer.rb +0 -624
@@ -0,0 +1,79 @@
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/plugin/parser'
18
+ require 'fluent/time'
19
+
20
+ require 'yajl'
21
+
22
+ module Fluent
23
+ module Plugin
24
+ class JSONParser < Parser
25
+ Plugin.register_parser('json', self)
26
+
27
+ config_param :time_key, :string, default: 'time'
28
+ config_param :time_format, :string, default: nil
29
+ config_param :json_parser, :string, default: 'oj'
30
+
31
+ def configure(conf)
32
+ super
33
+
34
+ unless @time_format.nil?
35
+ @time_parser = TimeParser.new(@time_format)
36
+ @mutex = Mutex.new
37
+ end
38
+
39
+ begin
40
+ raise LoadError unless @json_parser == 'oj'
41
+ require 'oj'
42
+ Oj.default_options = {bigdecimal_load: :float}
43
+ @load_proc = Oj.method(:load)
44
+ @error_class = Oj::ParseError
45
+ rescue LoadError
46
+ @load_proc = Yajl.method(:load)
47
+ @error_class = Yajl::ParseError
48
+ end
49
+ end
50
+
51
+ def parse(text)
52
+ record = @load_proc.call(text)
53
+
54
+ value = @keep_time_key ? record[@time_key] : record.delete(@time_key)
55
+ if value
56
+ if @time_format
57
+ time = @mutex.synchronize { @time_parser.parse(value) }
58
+ else
59
+ begin
60
+ time = Fluent::EventTime.from_time(Time.at(value.to_f))
61
+ rescue => e
62
+ raise ParserError, "invalid time value: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
63
+ end
64
+ end
65
+ else
66
+ if @estimate_current_event
67
+ time = Fluent::EventTime.now
68
+ else
69
+ time = nil
70
+ end
71
+ end
72
+
73
+ yield time, record
74
+ rescue @error_class
75
+ yield nil, nil
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,50 @@
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/plugin/parser'
18
+ require 'fluent/time'
19
+
20
+ module Fluent
21
+ module Plugin
22
+ class LabeledTSVParser < ValuesParser
23
+ Plugin.register_parser('ltsv', self)
24
+
25
+ config_param :delimiter, :string, default: "\t"
26
+ config_param :label_delimiter, :string, default: ":"
27
+ config_param :time_key, :string, default: "time"
28
+
29
+ def configure(conf)
30
+ # this assignment is not to raise ConfigError in ValuesParser#configure
31
+ conf['keys'] = conf['time_key'] || 'time'
32
+ super(conf)
33
+ end
34
+
35
+ def parse(text)
36
+ # TODO: thread unsafe: @keys might be changed by other threads
37
+ @keys = []
38
+ values = []
39
+
40
+ text.split(delimiter).each do |pair|
41
+ key, value = pair.split(label_delimiter, 2)
42
+ @keys.push(key)
43
+ values.push(value)
44
+ end
45
+
46
+ yield values_map(values)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,102 @@
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/plugin/parser'
18
+
19
+ module Fluent
20
+ module Plugin
21
+ class MultilineParser < Parser
22
+ Plugin.register_parser('multiline', self)
23
+
24
+ config_param :format_firstline, :string, default: nil
25
+
26
+ FORMAT_MAX_NUM = 20
27
+
28
+ def configure(conf)
29
+ super
30
+
31
+ formats = parse_formats(conf).compact.map { |f| f[1..-2] }.join
32
+ begin
33
+ @regex = Regexp.new(formats, Regexp::MULTILINE)
34
+ if @regex.named_captures.empty?
35
+ raise "No named captures"
36
+ end
37
+ @parser = RegexpParser.new(@regex, conf)
38
+ rescue => e
39
+ raise ConfigError, "Invalid regexp '#{formats}': #{e}"
40
+ end
41
+
42
+ if @format_firstline
43
+ check_format_regexp(@format_firstline, 'format_firstline')
44
+ @firstline_regex = Regexp.new(@format_firstline[1..-2])
45
+ end
46
+ end
47
+
48
+ def parse(text, &block)
49
+ @parser.call(text, &block)
50
+ end
51
+
52
+ def has_firstline?
53
+ !!@format_firstline
54
+ end
55
+
56
+ def firstline?(text)
57
+ @firstline_regex.match(text)
58
+ end
59
+
60
+ private
61
+
62
+ def parse_formats(conf)
63
+ check_format_range(conf)
64
+
65
+ prev_format = nil
66
+ (1..FORMAT_MAX_NUM).map { |i|
67
+ format = conf["format#{i}"]
68
+ if (i > 1) && prev_format.nil? && !format.nil?
69
+ raise ConfigError, "Jump of format index found. format#{i - 1} is missing."
70
+ end
71
+ prev_format = format
72
+ next if format.nil?
73
+
74
+ check_format_regexp(format, "format#{i}")
75
+ format
76
+ }
77
+ end
78
+
79
+ def check_format_range(conf)
80
+ invalid_formats = conf.keys.select { |k|
81
+ m = k.match(/^format(\d+)$/)
82
+ m ? !((1..FORMAT_MAX_NUM).include?(m[1].to_i)) : false
83
+ }
84
+ unless invalid_formats.empty?
85
+ raise ConfigError, "Invalid formatN found. N should be 1 - #{FORMAT_MAX_NUM}: " + invalid_formats.join(",")
86
+ end
87
+ end
88
+
89
+ def check_format_regexp(format, key)
90
+ if format[0] == '/' && format[-1] == '/'
91
+ begin
92
+ Regexp.new(format[1..-2], Regexp::MULTILINE)
93
+ rescue => e
94
+ raise ConfigError, "Invalid regexp in #{key}: #{e}"
95
+ end
96
+ else
97
+ raise ConfigError, "format should be Regexp, need //, in #{key}: '#{format}'"
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,24 @@
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/plugin/parser'
18
+
19
+ Fluent::Plugin.register_parser('nginx', Proc.new {
20
+ Fluent::Plugin::RegexpParser.new(
21
+ /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/,
22
+ {'time_format'=>"%d/%b/%Y:%H:%M:%S %z"}
23
+ )
24
+ })
@@ -0,0 +1,36 @@
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/plugin/parser'
18
+
19
+ require 'fluent/time'
20
+
21
+ module Fluent
22
+ module Plugin
23
+ class NoneParser < Parser
24
+ Plugin.register_parser('none', self)
25
+
26
+ config_param :message_key, :string, default: 'message'
27
+
28
+ def parse(text)
29
+ record = {}
30
+ record[@message_key] = text
31
+ time = @estimate_current_event ? Fluent::EventTime.now : nil
32
+ yield time, record
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,82 @@
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/plugin/parser'
18
+
19
+ require 'fluent/time'
20
+
21
+ module Fluent
22
+ module Plugin
23
+ class SyslogParser < Parser
24
+ Plugin.register_parser('syslog', self)
25
+
26
+ # From existence TextParser pattern
27
+ REGEXP = /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
28
+ # From in_syslog default pattern
29
+ REGEXP_WITH_PRI = /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
30
+
31
+ config_param :time_format, :string, default: "%b %d %H:%M:%S"
32
+ config_param :with_priority, :bool, default: false
33
+
34
+ def initialize
35
+ super
36
+ @mutex = Mutex.new
37
+ end
38
+
39
+ def configure(conf)
40
+ super
41
+
42
+ @regexp = @with_priority ? REGEXP_WITH_PRI : REGEXP
43
+ @time_parser = TimeParser.new(@time_format)
44
+ end
45
+
46
+ def patterns
47
+ {'format' => @regexp, 'time_format' => @time_format}
48
+ end
49
+
50
+ def parse(text)
51
+ m = @regexp.match(text)
52
+ unless m
53
+ yield nil, nil
54
+ return
55
+ end
56
+
57
+ time = nil
58
+ record = {}
59
+
60
+ m.names.each { |name|
61
+ if value = m[name]
62
+ case name
63
+ when "pri"
64
+ record['pri'] = value.to_i
65
+ when "time"
66
+ time = @mutex.synchronize { @time_parser.parse(value.gsub(/ +/, ' ')) }
67
+ record[name] = value if @keep_time_key
68
+ else
69
+ record[name] = value
70
+ end
71
+ end
72
+ }
73
+
74
+ if @estimate_current_event
75
+ time ||= Fluent::EventTime.now
76
+ end
77
+
78
+ yield time, record
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,37 @@
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/plugin/parser'
18
+ require 'fluent/time'
19
+
20
+ module Fluent
21
+ module Plugin
22
+ class TSVParser < ValuesParser
23
+ Plugin.register_parser('tsv', self)
24
+
25
+ config_param :delimiter, :string, default: "\t"
26
+
27
+ def configure(conf)
28
+ super
29
+ @key_num = @keys.length
30
+ end
31
+
32
+ def parse(text)
33
+ yield values_map(text.split(@delimiter, @key_num))
34
+ end
35
+ end
36
+ end
37
+ end
@@ -19,148 +19,150 @@ require 'ipaddr'
19
19
  require 'cool.io'
20
20
 
21
21
  require 'fluent/plugin'
22
+ require 'fluent/input'
22
23
 
23
24
  module Fluent
24
- module SocketUtil
25
- def create_udp_socket(host)
26
- if IPAddr.new(IPSocket.getaddress(host)).ipv4?
27
- UDPSocket.new
28
- else
29
- UDPSocket.new(Socket::AF_INET6)
30
- end
31
- end
32
- module_function :create_udp_socket
33
-
34
- class UdpHandler < Coolio::IO
35
- def initialize(io, log, body_size_limit, callback, resolve_hostname = false, remove_newline = true, receive_buffer_size = nil)
36
- super(io)
37
- if io.is_a?(UDPSocket) && receive_buffer_size
38
- io.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVBUF, receive_buffer_size)
25
+ module Plugin
26
+ module SocketUtil
27
+ def create_udp_socket(host)
28
+ if IPAddr.new(IPSocket.getaddress(host)).ipv4?
29
+ UDPSocket.new
30
+ else
31
+ UDPSocket.new(Socket::AF_INET6)
39
32
  end
40
- @io = io
41
- @io.do_not_reverse_lookup = !resolve_hostname
42
- @log = log
43
- @body_size_limit = body_size_limit
44
- @remove_newline = remove_newline
45
- @callback = callback
46
33
  end
34
+ module_function :create_udp_socket
35
+
36
+ class UdpHandler < Coolio::IO
37
+ def initialize(io, log, body_size_limit, callback)
38
+ super(io)
39
+ @io = io
40
+ @log = log
41
+ @body_size_limit = body_size_limit
42
+ @callback = callback
43
+ end
47
44
 
48
- def on_readable
49
- msg, addr = @io.recvfrom_nonblock(@body_size_limit)
50
- msg.chomp! if @remove_newline
51
- @callback.call(msg, addr)
52
- rescue => e
53
- @log.error "unexpected error", error: e, error_class: e.class
45
+ def on_readable
46
+ msg, addr = @io.recvfrom_nonblock(@body_size_limit)
47
+ msg.chomp!
48
+ @callback.call(msg, addr)
49
+ rescue => e
50
+ @log.error "unexpected error", error: e
51
+ end
54
52
  end
55
- end
56
53
 
57
- class TcpHandler < Coolio::Socket
58
- PEERADDR_FAILED = ["?", "?", "name resolusion failed", "?"]
54
+ class TcpHandler < Coolio::Socket
55
+ PEERADDR_FAILED = ["?", "?", "name resolusion failed", "?"]
59
56
 
60
- def initialize(io, log, delimiter, callback, resolve_hostname = false)
61
- super(io)
62
- if io.is_a?(TCPSocket)
63
- io.do_not_reverse_lookup = resolve_hostname
64
- @addr = (io.peeraddr rescue PEERADDR_FAILED)
57
+ def initialize(io, log, delimiter, callback)
58
+ super(io)
59
+ @timeout = 0
60
+ if io.is_a?(TCPSocket)
61
+ @addr = (io.peeraddr rescue PEERADDR_FAILED)
65
62
 
66
- opt = [1, @timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
67
- io.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
63
+ opt = [1, @timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
64
+ io.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
65
+ end
66
+ @delimiter = delimiter
67
+ @callback = callback
68
+ @log = log
69
+ @log.trace { "accepted fluent socket object_id=#{self.object_id}" }
70
+ @buffer = "".force_encoding('ASCII-8BIT')
68
71
  end
69
- @delimiter = delimiter
70
- @callback = callback
71
- @log = log
72
- @log.trace { "accepted fluent socket object_id=#{self.object_id}" }
73
- @buffer = "".force_encoding('ASCII-8BIT')
74
- end
75
72
 
76
- def on_connect
77
- end
73
+ def on_connect
74
+ end
78
75
 
79
- def on_read(data)
80
- @buffer << data
81
- pos = 0
76
+ def on_read(data)
77
+ @buffer << data
78
+ pos = 0
82
79
 
83
- while i = @buffer.index(@delimiter, pos)
84
- msg = @buffer[pos...i]
85
- @callback.call(msg, @addr)
86
- pos = i + @delimiter.length
80
+ while i = @buffer.index(@delimiter, pos)
81
+ msg = @buffer[pos...i]
82
+ @callback.call(msg, @addr)
83
+ pos = i + @delimiter.length
84
+ end
85
+ @buffer.slice!(0, pos) if pos > 0
86
+ rescue => e
87
+ @log.error "unexpected error", error: e
88
+ close
87
89
  end
88
- @buffer.slice!(0, pos) if pos > 0
89
- rescue => e
90
- @log.error "unexpected error", error: e, error_class: e.class
91
- close
92
- end
93
90
 
94
- def on_close
95
- @log.trace { "closed fluent socket object_id=#{self.object_id}" }
91
+ def on_close
92
+ @log.trace { "closed fluent socket object_id=#{self.object_id}" }
93
+ end
96
94
  end
97
- end
98
95
 
99
- class BaseInput < Fluent::Input
100
- def initialize
101
- super
102
- require 'fluent/parser'
103
- end
96
+ class BaseInput < Fluent::Input
97
+ def initialize
98
+ super
99
+ require 'fluent/parser'
100
+ end
104
101
 
105
- desc 'Tag of output events.'
106
- config_param :tag, :string
107
- desc 'The format of the payload.'
108
- config_param :format, :string
109
- desc 'The port to listen to.'
110
- config_param :port, :integer, default: 5150
111
- desc 'The bind address to listen to.'
112
- config_param :bind, :string, default: '0.0.0.0'
113
- desc "Deprecated parameter. Use source_hostname_key instead"
114
- config_param :source_host_key, :string, default: nil, deprecated: "Use source_hostname_key instead"
115
- desc "The field name of the client's hostname."
116
- config_param :source_hostname_key, :string, default: nil
117
- config_param :blocking_timeout, :time, default: 0.5
118
-
119
- def configure(conf)
120
- super
121
-
122
- @source_hostname_key = @source_host_key if @source_host_key
123
- @parser = Plugin.new_parser(@format)
124
- @parser.configure(conf)
125
- end
102
+ desc 'Tag of output events.'
103
+ config_param :tag, :string
104
+ desc 'The format of the payload.'
105
+ config_param :format, :string
106
+ desc 'The port to listen to.'
107
+ config_param :port, :integer, default: 5150
108
+ desc 'The bind address to listen to.'
109
+ config_param :bind, :string, default: '0.0.0.0'
110
+ desc "The field name of the client's hostname."
111
+ config_param :source_host_key, :string, default: nil
112
+ config_param :blocking_timeout, :time, default: 0.5
113
+
114
+ def configure(conf)
115
+ super
116
+
117
+ @parser = Plugin.new_parser(@format)
118
+ @parser.configure(conf)
119
+ end
126
120
 
127
- def start
128
- @loop = Coolio::Loop.new
129
- @handler = listen(method(:on_message))
130
- @loop.attach(@handler)
131
- @thread = Thread.new(&method(:run))
132
- end
121
+ def start
122
+ super
133
123
 
134
- def shutdown
135
- @loop.watchers.each { |w| w.detach }
136
- @loop.stop
137
- @handler.close
138
- @thread.join
139
- end
124
+ @loop = Coolio::Loop.new
125
+ @handler = listen(method(:on_message))
126
+ @loop.attach(@handler)
127
+ @thread = Thread.new(&method(:run))
128
+ end
140
129
 
141
- def run
142
- @loop.run(@blocking_timeout)
143
- rescue => e
144
- log.error "unexpected error", error: e, error_class: e.class
145
- log.error_backtrace
146
- end
130
+ def shutdown
131
+ @loop.watchers.each { |w| w.detach }
132
+ @loop.stop if @loop.instance_variable_get("@running")
133
+ @handler.close
134
+ @thread.join
147
135
 
148
- private
136
+ super
137
+ end
149
138
 
150
- def on_message(msg, addr)
151
- @parser.parse(msg) { |time, record|
152
- unless time && record
153
- log.warn "pattern not match: #{msg.inspect}"
154
- return
155
- end
139
+ def run
140
+ @loop.run(@blocking_timeout)
141
+ rescue => e
142
+ log.error "unexpected error", error: e
143
+ log.error_backtrace
144
+ end
156
145
 
157
- record[@source_hostname_key] = addr[2] if @source_hostname_key
158
- router.emit(@tag, time, record)
159
- }
160
- rescue => e
161
- log.error msg.dump, error: e, error_class: e.class, host: addr[3]
162
- log.error_backtrace
146
+ private
147
+
148
+ def on_message(msg, addr)
149
+ @parser.parse(msg) { |time, record|
150
+ unless time && record
151
+ log.warn "pattern not match: #{msg.inspect}"
152
+ return
153
+ end
154
+
155
+ record[@source_host_key] = addr[3] if @source_host_key
156
+ router.emit(@tag, time, record)
157
+ }
158
+ rescue => e
159
+ log.error msg.dump, error: e, host: addr[3]
160
+ log.error_backtrace
161
+ end
163
162
  end
164
163
  end
165
164
  end
165
+
166
+ # obsolete
167
+ SocketUtil = Fluent::Plugin::SocketUtil
166
168
  end