fluentd 0.12.40 → 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 (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
@@ -28,7 +28,14 @@ module Fluent
28
28
 
29
29
  def listen(callback)
30
30
  log.info "listening tcp socket on #{@bind}:#{@port}"
31
- Coolio::TCPServer.new(@bind, @port, SocketUtil::TcpHandler, log, @delimiter, callback, !!@source_hostname_key)
31
+
32
+ socket_manager_path = ENV['SERVERENGINE_SOCKETMANAGER_PATH']
33
+ if Fluent.windows?
34
+ socket_manager_path = socket_manager_path.to_i
35
+ end
36
+ client = ServerEngine::SocketManager::Client.new(socket_manager_path)
37
+ lsock = client.listen_tcp(@bind, @port)
38
+ Coolio::TCPServer.new(lsock, nil, SocketUtil::TcpHandler, log, @delimiter, callback)
32
39
  end
33
40
  end
34
41
  end
@@ -21,23 +21,17 @@ module Fluent
21
21
  Plugin.register_input('udp', self)
22
22
 
23
23
  config_set_default :port, 5160
24
-
25
- desc "Deprecated parameter. Use message_length_limit instead"
26
- config_param :body_size_limit, :size, default: nil, deprecated: "use message_length_limit instead."
27
- desc "The max bytes of message"
28
- config_param :message_length_limit, :size, default: 4096
29
-
30
- def configure(conf)
31
- super
32
-
33
- @message_length_limit = @body_size_limit if @body_size_limit
34
- end
24
+ config_param :body_size_limit, :size, default: 4096
35
25
 
36
26
  def listen(callback)
37
27
  log.info "listening udp socket on #{@bind}:#{@port}"
38
- @usock = SocketUtil.create_udp_socket(@bind)
39
- @usock.bind(@bind, @port)
40
- SocketUtil::UdpHandler.new(@usock, log, @message_length_limit, callback, !!@source_hostname_key)
28
+ socket_manager_path = ENV['SERVERENGINE_SOCKETMANAGER_PATH']
29
+ if Fluent.windows?
30
+ socket_manager_path = socket_manager_path.to_i
31
+ end
32
+ client = ServerEngine::SocketManager::Client.new(socket_manager_path)
33
+ @usock = client.listen_udp(@bind, @port)
34
+ SocketUtil::UdpHandler.new(@usock, log, @body_size_limit, callback)
41
35
  end
42
36
  end
43
37
  end
@@ -0,0 +1,33 @@
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/base'
18
+
19
+ require 'fluent/log'
20
+ require 'fluent/plugin_id'
21
+ require 'fluent/plugin_helper'
22
+
23
+ module Fluent
24
+ module Plugin
25
+ class Input < Base
26
+ include PluginId
27
+ include PluginLoggerMixin
28
+ include PluginHelper::Mixin
29
+
30
+ helpers :event_emitter
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,95 @@
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/base'
18
+ require 'fluent/log'
19
+ require 'fluent/plugin_id'
20
+ require 'fluent/plugin_helper'
21
+
22
+ module Fluent
23
+ module Plugin
24
+ class MultiOutput < Base
25
+ include PluginId
26
+ include PluginLoggerMixin
27
+ include PluginHelper::Mixin # for event_emitter
28
+
29
+ helpers :event_emitter # to get router from agent, which will be supplied to child plugins
30
+
31
+ config_section :store, param_name: :stores, multi: true, required: true do
32
+ config_param :@type, :string, default: nil
33
+ end
34
+
35
+ attr_reader :outputs
36
+
37
+ def process(tag, es)
38
+ raise NotImplementedError, "BUG: output plugins MUST implement this method"
39
+ end
40
+
41
+ def initialize
42
+ super
43
+ @outputs = []
44
+
45
+ @compat = false
46
+
47
+ @counters_monitor = Monitor.new
48
+ # TODO: well organized counters
49
+ @num_errors = 0
50
+ @emit_count = 0
51
+ @emit_records = 0
52
+ # @write_count = 0
53
+ # @rollback_count = 0
54
+ end
55
+
56
+ def configure(conf)
57
+ super
58
+
59
+ @stores.each do |store|
60
+ store_conf = store.corresponding_config_element
61
+ type = store_conf['@type']
62
+ unless type
63
+ raise Fluent::ConfigError, "Missing '@type' parameter in <store> section"
64
+ end
65
+
66
+ log.debug "adding store", type: type
67
+
68
+ output = Fluent::Plugin.new_output(type)
69
+ if output.has_router?
70
+ output.router = router
71
+ end
72
+ output.configure(store_conf)
73
+ @outputs << output
74
+ end
75
+ end
76
+
77
+ # Child plugin's lifecycles are controlled by agent automatically.
78
+ # It calls `outputs` to traverse plugins, and invoke start/stop/*shutdown/close/terminate on these directly.
79
+ # * `start` of this plugin will be called after child plugins
80
+ # * `stop`, `*shutdown`, `close` and `terminate` of this plugin will be called before child plugins
81
+
82
+ def emit_sync(tag, es)
83
+ @counters_monitor.synchronize{ @emit_count += 1 }
84
+ begin
85
+ process(tag, es)
86
+ @counters_monitor.synchronize{ @emit_records += es.size }
87
+ rescue
88
+ @counters_monitor.synchronize{ @num_errors += 1 }
89
+ raise
90
+ end
91
+ end
92
+ alias :emit_events :emit_sync
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,59 @@
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/output'
18
+
19
+ module Fluent::Plugin
20
+ class BufferedNullOutput < Output
21
+ # This plugin is for tests of buffer plugins
22
+
23
+ Fluent::Plugin.register_output('buffered_null', self)
24
+
25
+ config_section :buffer do
26
+ config_set_default :chunk_keys, ['tag']
27
+ config_set_default :flush_at_shutdown, true
28
+ config_set_default :chunk_limit_size, 10 * 1024
29
+ end
30
+
31
+ attr_accessor :feed_proc, :delayed
32
+
33
+ def initialize
34
+ super
35
+ @delayed = false
36
+ @feed_proc = nil
37
+ end
38
+
39
+ def prefer_delayed_commit
40
+ @delayed
41
+ end
42
+
43
+ def write(chunk)
44
+ if @feed_proc
45
+ @feed_proc.call(chunk)
46
+ else
47
+ # ignore chunk.read
48
+ end
49
+ end
50
+
51
+ def try_write(chunk)
52
+ if @feed_proc
53
+ @feed_proc.call(chunk)
54
+ else
55
+ # ignore chunk.read
56
+ end
57
+ end
58
+ end
59
+ end
@@ -37,7 +37,7 @@ module Fluent
37
37
  conf.elements.select {|e|
38
38
  e.name == 'store'
39
39
  }.each {|e|
40
- type = e['@type'] || e['type']
40
+ type = e['@type']
41
41
  unless type
42
42
  raise ConfigError, "Missing 'type' parameter on <store> directive"
43
43
  end
@@ -51,15 +51,19 @@ module Fluent
51
51
  end
52
52
 
53
53
  def start
54
- @outputs.each {|o|
55
- o.start
56
- }
54
+ super
55
+
56
+ @outputs.each do |o|
57
+ o.start unless o.started?
58
+ end
57
59
  end
58
60
 
59
61
  def shutdown
60
- @outputs.each {|o|
61
- o.shutdown
62
- }
62
+ @outputs.each do |o|
63
+ o.shutdown unless o.shutdown?
64
+ end
65
+
66
+ super
63
67
  end
64
68
 
65
69
  def emit(tag, es, chain)
@@ -16,18 +16,16 @@
16
16
 
17
17
  require 'tempfile'
18
18
 
19
- require 'fluent/output'
19
+ require 'fluent/plugin/output'
20
20
  require 'fluent/config/error'
21
21
  require 'fluent/plugin/exec_util'
22
+ require 'fluent/mixin' # for TimeFormatter
22
23
 
23
- module Fluent
24
- class ExecOutput < TimeSlicedOutput
25
- Plugin.register_output('exec', self)
24
+ module Fluent::Plugin
25
+ class ExecOutput < Output
26
+ Fluent::Plugin.register_output('exec', self)
26
27
 
27
- def initialize
28
- super
29
- @localtime = false
30
- end
28
+ helpers :compat_parameters
31
29
 
32
30
  desc 'The command (program) to execute. The exec plugin passes the path of a TSV file as the last argumen'
33
31
  config_param :command, :string
@@ -42,11 +40,17 @@ module Fluent
42
40
  desc 'The format for event time used when the time_key parameter is specified. The default is UNIX time (integer).'
43
41
  config_param :time_format, :string, default: nil
44
42
  desc "The format used to map the incoming events to the program input. (#{ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
45
- config_param :format, default: :tsv do |val|
43
+ config_param :format, default: :tsv, skip_accessor: true do |val|
46
44
  f = ExecUtil::SUPPORTED_FORMAT[val]
47
45
  raise ConfigError, "Unsupported format '#{val}'" unless f
48
46
  f
49
47
  end
48
+ config_param :localtime, :bool, default: false
49
+ config_param :timezone, :string, default: nil
50
+
51
+ def compat_parameters_default_chunk_key
52
+ 'time'
53
+ end
50
54
 
51
55
  def configure(conf)
52
56
  super
@@ -54,7 +58,7 @@ module Fluent
54
58
  @formatter = case @format
55
59
  when :tsv
56
60
  if @keys.empty?
57
- raise ConfigError, "keys option is required on exec output for tsv format"
61
+ raise Fluent::ConfigError, "keys option is required on exec output for tsv format"
58
62
  end
59
63
  ExecUtil::TSVFormatter.new(@keys)
60
64
  when :json
@@ -65,7 +69,7 @@ module Fluent
65
69
 
66
70
  if @time_key
67
71
  if @time_format
68
- tf = TimeFormatter.new(@time_format, @localtime, @timezone)
72
+ tf = Fluent::TimeFormatter.new(@time_format, @localtime, @timezone)
69
73
  @time_format_proc = tf.method(:format)
70
74
  else
71
75
  @time_format_proc = Proc.new { |time| time.to_s }
@@ -114,9 +114,9 @@ module Fluent
114
114
 
115
115
  super
116
116
 
117
- if localtime = conf['localtime']
117
+ if conf['localtime']
118
118
  @localtime = true
119
- elsif utc = conf['utc']
119
+ elsif conf['utc']
120
120
  @localtime = false
121
121
  end
122
122
 
@@ -142,9 +142,15 @@ module Fluent
142
142
 
143
143
  if @out_time_key
144
144
  if f = @out_time_format
145
- @time_parse_proc = Proc.new {|str| Time.strptime(str, f).to_i }
145
+ @time_parse_proc =
146
+ begin
147
+ strptime = Strptime.new(f)
148
+ Proc.new { |str| Fluent::EventTime.from_time(strptime.exec(str)) }
149
+ rescue
150
+ Proc.new {|str| Fluent::EventTime.from_time(Time.strptime(str, f)) }
151
+ end
146
152
  else
147
- @time_parse_proc = Proc.new {|str| str.to_i }
153
+ @time_parse_proc = Proc.new {|str| Fluent::EventTime.from_time(Time.at(str.to_f)) }
148
154
  end
149
155
  elsif @out_time_format
150
156
  log.warn "out_time_format effects nothing when out_time_key is not specified: #{conf}"
@@ -214,21 +220,22 @@ module Fluent
214
220
  end
215
221
 
216
222
  def before_shutdown
217
- super
218
223
  log.debug "out_exec_filter#before_shutdown called"
219
224
  @children.each {|c|
220
225
  c.finished = true
221
226
  }
222
227
  sleep 0.5 # TODO wait time before killing child process
223
- end
224
228
 
225
- def shutdown
226
229
  super
230
+ end
227
231
 
232
+ def shutdown
228
233
  @children.reject! {|c|
229
234
  c.shutdown
230
235
  true
231
236
  }
237
+
238
+ super
232
239
  end
233
240
 
234
241
  def format_stream(tag, es)
@@ -284,7 +291,8 @@ module Fluent
284
291
 
285
292
  def kill_child(join_wait)
286
293
  begin
287
- Process.kill(:TERM, @pid)
294
+ signal = Fluent.windows? ? :KILL : :TERM
295
+ Process.kill(signal, @pid)
288
296
  rescue #Errno::ECHILD, Errno::ESRCH, Errno::EPERM
289
297
  # Errno::ESRCH 'No such process', ignore
290
298
  # child process killed by signal chained from fluentd process
@@ -346,7 +354,7 @@ module Fluent
346
354
  @log.error "exec_filter thread unexpectedly failed with an error.", command: @command, error: $!.to_s
347
355
  @log.warn_backtrace $!.backtrace
348
356
  ensure
349
- pid, stat = Process.waitpid2(@pid)
357
+ _pid, stat = Process.waitpid2(@pid)
350
358
  unless @finished
351
359
  @log.error "exec_filter process unexpectedly exited.", command: @command, ecode: stat.to_i
352
360
  unless @respawns == 0
@@ -376,7 +384,7 @@ module Fluent
376
384
  router.emit(tag, time, record)
377
385
  rescue
378
386
  if @suppress_error_log_interval == 0 || Time.now.to_i > @next_log_time
379
- log.error "exec_filter failed to emit", error: $!.to_s, error_class: $!.class.to_s, record: Yajl.dump(record)
387
+ log.error "exec_filter failed to emit", error: $!, record: Yajl.dump(record)
380
388
  log.warn_backtrace $!.backtrace
381
389
  @next_log_time = Time.now.to_i + @suppress_error_log_interval
382
390
  end
@@ -19,9 +19,12 @@ require 'zlib'
19
19
 
20
20
  require 'fluent/output'
21
21
  require 'fluent/config/error'
22
+ require 'fluent/system_config'
22
23
 
23
24
  module Fluent
24
25
  class FileOutput < TimeSlicedOutput
26
+ include SystemConfig::Mixin
27
+
25
28
  Plugin.register_output('file', self)
26
29
 
27
30
  SUPPORTED_COMPRESS = {
@@ -29,10 +32,13 @@ module Fluent
29
32
  'gzip' => :gz,
30
33
  }
31
34
 
35
+ FILE_PERMISSION = 0644
36
+ DIR_PERMISSION = 0755
37
+
32
38
  desc "The Path of the file."
33
39
  config_param :path, :string
34
40
  desc "The format of the file content. The default is out_file."
35
- config_param :format, :string, default: 'out_file'
41
+ config_param :format, :string, default: 'out_file', skip_accessor: true
36
42
  desc "The flushed chunk is appended to existence file or not."
37
43
  config_param :append, :bool, default: false
38
44
  desc "Compress flushed file."
@@ -46,6 +52,21 @@ module Fluent
46
52
  desc "Create symlink to temporary buffered file when buffer_type is file."
47
53
  config_param :symlink_path, :string, default: nil
48
54
 
55
+ module SymlinkBufferMixin
56
+ def symlink_path=(path)
57
+ @_symlink_path = path
58
+ end
59
+
60
+ def generate_chunk(metadata)
61
+ chunk = super
62
+ latest_chunk = metadata_list.sort_by(&:timekey).last
63
+ if chunk.metadata == latest_chunk
64
+ FileUtils.ln_sf(chunk.path, @_symlink_path)
65
+ end
66
+ chunk
67
+ end
68
+ end
69
+
49
70
  def initialize
50
71
  require 'zlib'
51
72
  require 'time'
@@ -81,7 +102,15 @@ module Fluent
81
102
  @formatter = Plugin.new_formatter(@format)
82
103
  @formatter.configure(conf)
83
104
 
84
- @buffer.symlink_path = @symlink_path if @symlink_path
105
+ if @symlink_path && @buffer.respond_to?(:path)
106
+ (class << @buffer; self; end).module_eval do
107
+ prepend SymlinkBufferMixin
108
+ end
109
+ @buffer.symlink_path = @symlink_path
110
+ end
111
+
112
+ @dir_perm = system_config.dir_permission || DIR_PERMISSION
113
+ @file_perm = system_config.file_permission || FILE_PERMISSION
85
114
  end
86
115
 
87
116
  def format(tag, time, record)
@@ -90,15 +119,15 @@ module Fluent
90
119
 
91
120
  def write(chunk)
92
121
  path = generate_path(chunk.key)
93
- FileUtils.mkdir_p File.dirname(path), mode: DEFAULT_DIR_PERMISSION
122
+ FileUtils.mkdir_p File.dirname(path), mode: @dir_perm
94
123
 
95
124
  case @compress
96
125
  when nil
97
- File.open(path, "a", DEFAULT_FILE_PERMISSION) {|f|
126
+ File.open(path, "ab", @file_perm) {|f|
98
127
  chunk.write_to(f)
99
128
  }
100
129
  when :gz
101
- File.open(path, "a", DEFAULT_FILE_PERMISSION) {|f|
130
+ File.open(path, "ab", @file_perm) {|f|
102
131
  gz = Zlib::GzipWriter.new(f)
103
132
  chunk.write_to(gz)
104
133
  gz.close