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
@@ -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,144 +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)
36
- super(io)
37
- @io = io
38
- @io.do_not_reverse_lookup = !resolve_hostname
39
- @log = log
40
- @body_size_limit = body_size_limit
41
- @callback = callback
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)
32
+ end
42
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
43
44
 
44
- def on_readable
45
- msg, addr = @io.recvfrom_nonblock(@body_size_limit)
46
- msg.chomp!
47
- @callback.call(msg, addr)
48
- rescue => e
49
- @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
50
52
  end
51
- end
52
53
 
53
- class TcpHandler < Coolio::Socket
54
- PEERADDR_FAILED = ["?", "?", "name resolusion failed", "?"]
54
+ class TcpHandler < Coolio::Socket
55
+ PEERADDR_FAILED = ["?", "?", "name resolusion failed", "?"]
55
56
 
56
- def initialize(io, log, delimiter, callback, resolve_hostname = false)
57
- super(io)
58
- if io.is_a?(TCPSocket)
59
- io.do_not_reverse_lookup = resolve_hostname
60
- @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)
61
62
 
62
- opt = [1, @timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
63
- 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')
64
71
  end
65
- @delimiter = delimiter
66
- @callback = callback
67
- @log = log
68
- @log.trace { "accepted fluent socket object_id=#{self.object_id}" }
69
- @buffer = "".force_encoding('ASCII-8BIT')
70
- end
71
72
 
72
- def on_connect
73
- end
73
+ def on_connect
74
+ end
74
75
 
75
- def on_read(data)
76
- @buffer << data
77
- pos = 0
76
+ def on_read(data)
77
+ @buffer << data
78
+ pos = 0
78
79
 
79
- while i = @buffer.index(@delimiter, pos)
80
- msg = @buffer[pos...i]
81
- @callback.call(msg, @addr)
82
- 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
83
89
  end
84
- @buffer.slice!(0, pos) if pos > 0
85
- rescue => e
86
- @log.error "unexpected error", error: e, error_class: e.class
87
- close
88
- end
89
90
 
90
- def on_close
91
- @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
92
94
  end
93
- end
94
95
 
95
- class BaseInput < Fluent::Input
96
- def initialize
97
- super
98
- require 'fluent/parser'
99
- end
96
+ class BaseInput < Fluent::Input
97
+ def initialize
98
+ super
99
+ require 'fluent/parser'
100
+ end
100
101
 
101
- desc 'Tag of output events.'
102
- config_param :tag, :string
103
- desc 'The format of the payload.'
104
- config_param :format, :string
105
- desc 'The port to listen to.'
106
- config_param :port, :integer, default: 5150
107
- desc 'The bind address to listen to.'
108
- config_param :bind, :string, default: '0.0.0.0'
109
- desc "Deprecated parameter. Use source_hostname_key instead"
110
- config_param :source_host_key, :string, default: nil, deprecated: "Use source_hostname_key instead"
111
- desc "The field name of the client's hostname."
112
- config_param :source_hostname_key, :string, default: nil
113
- config_param :blocking_timeout, :time, default: 0.5
114
-
115
- def configure(conf)
116
- super
117
-
118
- @source_hostname_key = @source_host_key if @source_host_key
119
- @parser = Plugin.new_parser(@format)
120
- @parser.configure(conf)
121
- 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
122
120
 
123
- def start
124
- @loop = Coolio::Loop.new
125
- @handler = listen(method(:on_message))
126
- @loop.attach(@handler)
127
- @thread = Thread.new(&method(:run))
128
- end
121
+ def start
122
+ super
129
123
 
130
- def shutdown
131
- @loop.watchers.each { |w| w.detach }
132
- @loop.stop
133
- @handler.close
134
- @thread.join
135
- end
124
+ @loop = Coolio::Loop.new
125
+ @handler = listen(method(:on_message))
126
+ @loop.attach(@handler)
127
+ @thread = Thread.new(&method(:run))
128
+ end
136
129
 
137
- def run
138
- @loop.run(@blocking_timeout)
139
- rescue => e
140
- log.error "unexpected error", error: e, error_class: e.class
141
- log.error_backtrace
142
- 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
143
135
 
144
- private
136
+ super
137
+ end
145
138
 
146
- def on_message(msg, addr)
147
- @parser.parse(msg) { |time, record|
148
- unless time && record
149
- log.warn "pattern not match: #{msg.inspect}"
150
- return
151
- 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
152
145
 
153
- record[@source_hostname_key] = addr[2] if @source_hostname_key
154
- router.emit(@tag, time, record)
155
- }
156
- rescue => e
157
- log.error msg.dump, error: e, error_class: e.class, host: addr[3]
158
- 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
159
162
  end
160
163
  end
161
164
  end
165
+
166
+ # obsolete
167
+ SocketUtil = Fluent::Plugin::SocketUtil
162
168
  end