fluentd 0.12.43 → 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 (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
data/lib/fluent/agent.rb CHANGED
@@ -15,7 +15,6 @@
15
15
  #
16
16
 
17
17
  require 'fluent/configurable'
18
- require 'fluent/engine'
19
18
  require 'fluent/plugin'
20
19
  require 'fluent/output'
21
20
 
@@ -29,16 +28,23 @@ module Fluent
29
28
  class Agent
30
29
  include Configurable
31
30
 
32
- def initialize(opts = {})
31
+ def initialize(log:)
33
32
  super()
34
33
 
35
34
  @context = nil
36
35
  @outputs = []
37
36
  @filters = []
38
- @started_outputs = []
39
- @started_filters = []
40
37
 
41
- @log = Engine.log
38
+ @lifecycle_control_list = nil
39
+ # lifecycle_control_list is the list of plugins in this agent, and ordered
40
+ # from plugins which DOES emit, then DOESN'T emit
41
+ # (input -> output w/ router -> filter -> output w/o router)
42
+ # for start: use this order DESC
43
+ # (because plugins which appears later in configurations will receive events from plugins which appears ealier)
44
+ # for stop/before_shutdown/shutdown/after_shutdown/close/terminate: use this order ASC
45
+ @lifecycle_cache = nil
46
+
47
+ @log = log
42
48
  @event_router = EventRouter.new(NoMatchMatch.new(log), self)
43
49
  @error_collector = nil
44
50
  end
@@ -54,10 +60,9 @@ module Fluent
54
60
  super
55
61
 
56
62
  # initialize <match> and <filter> elements
57
- conf.elements.select { |e| e.name == 'filter' || e.name == 'match' }.each { |e|
63
+ conf.elements('filter', 'match').each { |e|
58
64
  pattern = e.arg.empty? ? '**' : e.arg
59
- type = e['@type'] || e['type']
60
- raise ConfigError, "Missing '@type' parameter on <#{e.name}> directive" unless type
65
+ type = e['@type']
61
66
  if e.name == 'filter'
62
67
  add_filter(type, pattern, e)
63
68
  else
@@ -66,70 +71,67 @@ module Fluent
66
71
  }
67
72
  end
68
73
 
69
- def start
70
- @outputs.each { |o|
71
- o.start
72
- @started_outputs << o
73
- }
74
+ def lifecycle_control_list
75
+ return @lifecycle_control_list if @lifecycle_control_list
74
76
 
75
- @filters.each { |f|
76
- f.start
77
- @started_filters << f
77
+ lifecycle_control_list = {
78
+ input: [],
79
+ output_with_router: [],
80
+ filter: [],
81
+ output: [],
78
82
  }
79
- end
80
-
81
- def shutdown
82
- @started_filters.map { |f|
83
- Thread.new do
84
- begin
85
- log.info "shutting down filter#{@context.nil? ? '' : " in #{@context}"}", type: Plugin.lookup_name_from_class(f.class), plugin_id: f.plugin_id
86
- f.shutdown
87
- rescue => e
88
- log.warn "unexpected error while shutting down filter plugins", plugin: f.class, plugin_id: f.plugin_id, error_class: e.class, error: e
89
- log.warn_backtrace
90
- end
83
+ if self.respond_to?(:inputs)
84
+ inputs.each do |i|
85
+ lifecycle_control_list[:input] << i
86
+ end
87
+ end
88
+ recursive_output_traverse = ->(o) {
89
+ if o.has_router?
90
+ lifecycle_control_list[:output_with_router] << o
91
+ else
92
+ lifecycle_control_list[:output] << o
91
93
  end
92
- }.each { |t| t.join }
93
-
94
- # Output plugin as filter emits records at shutdown so emit problem still exist.
95
- # This problem will be resolved after actual filter mechanizm.
96
- @started_outputs.map { |o|
97
- Thread.new do
98
- begin
99
- log.info "shutting down output#{@context.nil? ? '' : " in #{@context}"}", type: Plugin.lookup_name_from_class(o.class), plugin_id: o.plugin_id
100
- o.shutdown
101
- rescue => e
102
- log.warn "unexpected error while shutting down output plugins", plugin: o.class, plugin_id: o.plugin_id, error_class: e.class, error: e
103
- log.warn_backtrace
94
+
95
+ if o.respond_to?(:outputs)
96
+ o.outputs.each do |store|
97
+ recursive_output_traverse.call(store)
104
98
  end
105
99
  end
106
- }.each { |t| t.join }
107
- end
100
+ }
101
+ outputs.each do |o|
102
+ recursive_output_traverse.call(o)
103
+ end
104
+ filters.each do |f|
105
+ lifecycle_control_list[:filter] << f
106
+ end
108
107
 
109
- def flush!
110
- flush_recursive(@outputs)
108
+ @lifecycle_control_list = lifecycle_control_list
111
109
  end
112
110
 
113
- def flush_recursive(array)
114
- array.each { |o|
115
- begin
116
- if o.is_a?(BufferedOutput)
117
- o.force_flush
118
- elsif o.is_a?(MultiOutput)
119
- flush_recursive(o.outputs)
120
- end
121
- rescue => e
122
- log.debug "error while force flushing", error_class: e.class, error: e
123
- log.debug_backtrace
111
+ def lifecycle(desc: false)
112
+ kind_list = if desc
113
+ [:output, :filter, :output_with_router]
114
+ else
115
+ [:output_with_router, :filter, :output]
116
+ end
117
+ kind_list.each do |kind|
118
+ list = if desc
119
+ lifecycle_control_list[kind].reverse
120
+ else
121
+ lifecycle_control_list[kind]
122
+ end
123
+ display_kind = (kind == :output_with_router ? :output : kind)
124
+ list.each do |instance|
125
+ yield instance, display_kind
124
126
  end
125
- }
127
+ end
126
128
  end
127
129
 
128
130
  def add_match(type, pattern, conf)
129
131
  log.info "adding match#{@context.nil? ? '' : " in #{@context}"}", pattern: pattern, type: type
130
132
 
131
133
  output = Plugin.new_output(type)
132
- output.router = @event_router
134
+ output.router = @event_router if output.respond_to?(:router=)
133
135
  output.configure(conf)
134
136
  @outputs << output
135
137
  @event_router.add_rule(pattern, output)
@@ -162,7 +164,7 @@ module Fluent
162
164
  @count = 0
163
165
  end
164
166
 
165
- def emit(tag, es, chain)
167
+ def emit_events(tag, es)
166
168
  # TODO use time instead of num of records
167
169
  c = (@count += 1)
168
170
  if c < 512
@@ -21,7 +21,7 @@ op = OptionParser.new
21
21
 
22
22
  op.banner += " <tag>"
23
23
 
24
- port = Fluent::DEFAULT_LISTEN_PORT
24
+ port = 24224
25
25
  host = '127.0.0.1'
26
26
  unix = false
27
27
  socket_path = Fluent::DEFAULT_SOCKET_PATH
@@ -62,13 +62,15 @@ end
62
62
 
63
63
  require 'fluent/log'
64
64
  require 'fluent/engine'
65
- require 'fluent/config'
66
65
  require 'fluent/system_config'
67
66
 
68
- $log = Fluent::Log.new(STDERR, Fluent::Log::LEVEL_TRACE)
69
- conf = Fluent::Config.parse('', 'fluent-debug.conf', '', true)
70
- system_conf = Fluent::SystemConfig.create(conf)
71
- Fluent::Engine.init(system_conf)
67
+ include Fluent::SystemConfig::Mixin
68
+
69
+ dl_opts = {}
70
+ dl_opts[:log_level] = ServerEngine::DaemonLogger::TRACE
71
+ logger = ServerEngine::DaemonLogger.new(STDERR, dl_opts)
72
+ $log = Fluent::Log.new(logger)
73
+ Fluent::Engine.init(system_config)
72
74
 
73
75
  DRb::DRbObject.class_eval do
74
76
  undef_method :methods
@@ -17,8 +17,12 @@
17
17
  require 'optparse'
18
18
 
19
19
  require 'fluent/supervisor'
20
+ require 'fluent/log'
21
+ require 'fluent/env'
20
22
  require 'fluent/version'
21
23
 
24
+ $fluentdargv = Marshal.load(Marshal.dump(ARGV))
25
+
22
26
  op = OptionParser.new
23
27
  op.version = Fluent::VERSION
24
28
 
@@ -72,7 +76,7 @@ op.on('-o', '--log PATH', "log file path") {|s|
72
76
  opts[:log_path] = s
73
77
  }
74
78
 
75
- op.on('-i', '--inline-config CONFIG_STRING', "inline config which is appended to the config file on-fly") {|s|
79
+ op.on('-i', '--inline-config CONFIG_STRING', "inline config which is appended to the config file on-the-fly") {|s|
76
80
  opts[:inline_config] = s
77
81
  }
78
82
 
@@ -121,6 +125,28 @@ op.on('-G', '--gem-path GEM_INSTALL_PATH', "Gemfile install path (default: $(dir
121
125
  opts[:gem_install_path] = s
122
126
  }
123
127
 
128
+ if Fluent.windows?
129
+ require 'windows/library'
130
+ include Windows::Library
131
+
132
+ op.on('-x', '--signame INTSIGNAME', "an object name which is used for Windows Service signal (Windows only)") {|s|
133
+ opts[:signame] = s
134
+ }
135
+
136
+ op.on('--reg-winsvc MODE', "install/uninstall as Windows Service. (i: install, u: uninstall) (Windows only)") {|s|
137
+ opts[:regwinsvc] = s
138
+ }
139
+
140
+ op.on('--[no-]reg-winsvc-auto-start', "Automatically start the Windows Service at boot. (only effective with '--reg-winsvc i') (Windows only)") {|s|
141
+ opts[:regwinsvcautostart] = s
142
+ }
143
+
144
+ op.on('--reg-winsvc-fluentdopt OPTION', "specify fluentd option paramters for Windows Service. (Windows only)") {|s|
145
+ opts[:fluentdopt] = s
146
+ }
147
+ end
148
+
149
+
124
150
  (class << self; self; end).module_eval do
125
151
  define_method(:usage) do |msg|
126
152
  puts op.to_s
@@ -170,4 +196,73 @@ if setup_path = opts[:setup_path]
170
196
  exit 0
171
197
  end
172
198
 
173
- Fluent::Supervisor.new(opts).start
199
+ early_exit = false
200
+ start_service = false
201
+ if winsvcinstmode = opts[:regwinsvc]
202
+ FLUENTD_WINSVC_NAME="fluentdwinsvc"
203
+ FLUENTD_WINSVC_DISPLAYNAME="Fluentd Windows Service"
204
+ FLUENTD_WINSVC_DESC="Fluentd is an event collector system."
205
+ require 'fileutils'
206
+ require "win32/service"
207
+ require "win32/registry"
208
+ include Win32
209
+
210
+ case winsvcinstmode
211
+ when 'i'
212
+ binary_path = File.join(File.dirname(__FILE__), "..")
213
+ ruby_path = "\0" * 256
214
+ GetModuleFileName.call(0,ruby_path,256)
215
+ ruby_path = ruby_path.rstrip.gsub(/\\/, '/')
216
+ start_type = Service::DEMAND_START
217
+ if opts[:regwinsvcautostart]
218
+ start_type = Service::AUTO_START
219
+ start_service = true
220
+ end
221
+
222
+ Service.create(
223
+ service_name: FLUENTD_WINSVC_NAME,
224
+ host: nil,
225
+ service_type: Service::WIN32_OWN_PROCESS,
226
+ description: FLUENTD_WINSVC_DESC,
227
+ start_type: start_type,
228
+ error_control: Service::ERROR_NORMAL,
229
+ binary_path_name: ruby_path+" -C "+binary_path+" winsvc.rb",
230
+ load_order_group: "",
231
+ dependencies: [""],
232
+ display_name: FLUENTD_WINSVC_DISPLAYNAME
233
+ )
234
+ when 'u'
235
+ if Service.status(FLUENTD_WINSVC_NAME).current_state != 'stopped'
236
+ begin
237
+ Service.stop(FLUENTD_WINSVC_NAME)
238
+ rescue => ex
239
+ puts "Warning: Failed to stop service: ", ex
240
+ end
241
+ end
242
+ Service.delete(FLUENTD_WINSVC_NAME)
243
+ else
244
+ # none
245
+ end
246
+ early_exit = true
247
+ end
248
+
249
+ if fluentdopt = opts[:fluentdopt]
250
+ Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services\\fluentdwinsvc", Win32::Registry::KEY_ALL_ACCESS) do |reg|
251
+ reg['fluentdopt', Win32::Registry::REG_SZ] = fluentdopt
252
+ end
253
+ early_exit = true
254
+ end
255
+
256
+ if start_service
257
+ Service.start(FLUENTD_WINSVC_NAME)
258
+ end
259
+
260
+ exit 0 if early_exit
261
+
262
+ require 'fluent/supervisor'
263
+ if opts[:supervise]
264
+ Fluent::Supervisor.new(opts).run_supervisor
265
+ else
266
+ Fluent::Supervisor.new(opts).run_worker
267
+ end
268
+
@@ -0,0 +1,67 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Fluent
18
+ module Compat
19
+ module CallSuperMixin
20
+ # This mixin is to prepend to 3rd party plugins of v0.12 APIs.
21
+ # In past, there were not strong rule to call super in #start, #before_shutdown and #shutdown.
22
+ # But v0.14 API requires to call super in these methods to setup/teardown plugin helpers and others.
23
+ # This mixin prepends method calls to call super forcedly if checker returns false (it shows Fluent::Plugin::Base#methods wasn't called)
24
+
25
+ def self.prepended(klass)
26
+ @@_super_start ||= {}
27
+ @@_super_before_shutdown ||= {}
28
+ @@_super_shutdown ||= {}
29
+
30
+ # ancestors[0]: this module
31
+ # ancestors[1]: prepended class (plugin itself)
32
+ method_search = ->(ancestors, method){
33
+ closest = ancestors[2, ancestors.size - 2].index{|m| m.method_defined?(method) }
34
+ ancestors[2 + closest].instance_method(method)
35
+ }
36
+ @@_super_start[klass] = method_search.call(klass.ancestors, :start) # this returns Fluent::Compat::*#start (or helpers on it)
37
+ @@_super_before_shutdown[klass] = method_search.call(klass.ancestors, :before_shutdown)
38
+ @@_super_shutdown[klass] = method_search.call(klass.ancestors, :shutdown)
39
+ end
40
+
41
+ def start
42
+ super
43
+ unless self.started?
44
+ @@_super_start[self.class].bind(self).call
45
+ # #super will reset logdev (especially in test), so this warn should be after calling it
46
+ log.warn "super was not called in #start: called it forcedly", plugin: self.class
47
+ end
48
+ end
49
+
50
+ def before_shutdown
51
+ super
52
+ unless self.before_shutdown?
53
+ log.warn "super was not called in #before_shutdown: calling it forcedly", plugin: self.class
54
+ @@_super_before_shutdown[self.class].bind(self).call
55
+ end
56
+ end
57
+
58
+ def shutdown
59
+ super
60
+ unless self.shutdown?
61
+ log.warn "super was not called in #shutdown: calling it forcedly", plugin: self.class
62
+ @@_super_shutdown[self.class].bind(self).call
63
+ end
64
+ end
65
+ end
66
+ end
67
+ 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'
18
+ require 'fluent/plugin/filter'
19
+ require 'fluent/compat/call_super_mixin'
20
+
21
+ module Fluent
22
+ module Compat
23
+ class Filter < Fluent::Plugin::Filter
24
+ # TODO: warn when deprecated
25
+
26
+ def initialize
27
+ super
28
+ unless self.class.ancestors.include?(Fluent::Compat::CallSuperMixin)
29
+ self.class.module_eval do
30
+ prepend Fluent::Compat::CallSuperMixin
31
+ end
32
+ end
33
+ end
34
+
35
+ # These definitions are to get instance methods of superclass of 3rd party plugins
36
+ # to make it sure to call super
37
+ def start
38
+ super
39
+ end
40
+
41
+ def before_shutdown
42
+ super
43
+ end
44
+
45
+ def shutdown
46
+ super
47
+ end
48
+ end
49
+ end
50
+ end