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
@@ -17,12 +17,6 @@
17
17
  require 'etc'
18
18
  require 'fcntl'
19
19
 
20
- begin
21
- require 'sigdump/setup'
22
- rescue Exception
23
- # ignore LoadError and others (related with signals): it may raise these errors in Windows
24
- end
25
-
26
20
  require 'fluent/config'
27
21
  require 'fluent/env'
28
22
  require 'fluent/engine'
@@ -30,25 +24,225 @@ require 'fluent/log'
30
24
  require 'fluent/plugin'
31
25
  require 'fluent/rpc'
32
26
  require 'fluent/system_config'
27
+ require 'serverengine'
28
+ require 'shellwords'
29
+
30
+ if Fluent.windows?
31
+ require 'windows/library'
32
+ require 'windows/system_info'
33
+ include Windows::Library
34
+ include Windows::SystemInfo
35
+ require 'win32/ipc'
36
+ require 'win32/event'
37
+ end
33
38
 
34
39
  module Fluent
35
- class Supervisor
36
- def self.get_etc_passwd(user)
37
- if user.to_i.to_s == user
38
- Etc.getpwuid(user.to_i)
39
- else
40
- Etc.getpwnam(user)
40
+ module ServerModule
41
+ def before_run
42
+ @start_time = Time.now
43
+
44
+ if config[:rpc_endpoint]
45
+ @rpc_endpoint = config[:rpc_endpoint]
46
+ @enable_get_dump = config[:enable_get_dump]
47
+ run_rpc_server
41
48
  end
49
+ install_supervisor_signal_handlers
50
+
51
+ socket_manager_path = ServerEngine::SocketManager::Server.generate_path
52
+ ServerEngine::SocketManager::Server.open(socket_manager_path)
53
+ ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = socket_manager_path.to_s
42
54
  end
43
55
 
44
- def self.get_etc_group(group)
45
- if group.to_i.to_s == group
46
- Etc.getgrgid(group.to_i)
47
- else
48
- Etc.getgrnam(group)
56
+ def after_run
57
+ if Time.now - @start_time < 1
58
+ $log.warn "process died within 1 second. exit."
59
+ end
60
+
61
+ stop_rpc_server if @rpc_endpoint
62
+ end
63
+
64
+ def run_rpc_server
65
+ @rpc_server = RPC::Server.new(@rpc_endpoint, $log)
66
+
67
+ # built-in RPC for signals
68
+ @rpc_server.mount_proc('/api/processes.interruptWorkers') { |req, res|
69
+ $log.debug "fluentd RPC got /api/processes.interruptWorkers request"
70
+ Process.kill :INT, $$
71
+ nil
72
+ }
73
+ @rpc_server.mount_proc('/api/processes.killWorkers') { |req, res|
74
+ $log.debug "fluentd RPC got /api/processes.killWorkers request"
75
+ Process.kill :TERM, $$
76
+ nil
77
+ }
78
+ @rpc_server.mount_proc('/api/plugins.flushBuffers') { |req, res|
79
+ $log.debug "fluentd RPC got /api/plugins.flushBuffers request"
80
+ unless Fluent.windows?
81
+ Process.kill :USR1, $$
82
+ end
83
+ nil
84
+ }
85
+ @rpc_server.mount_proc('/api/config.reload') { |req, res|
86
+ $log.debug "fluentd RPC got /api/config.reload request"
87
+ if Fluent.windows?
88
+ # restart worker with auto restarting by killing
89
+ kill_worker
90
+ else
91
+ Process.kill :HUP, $$
92
+ end
93
+ nil
94
+ }
95
+ @rpc_server.mount_proc('/api/config.dump') { |req, res|
96
+ $log.debug "fluentd RPC got /api/config.dump request"
97
+ $log.info "dump in-memory config"
98
+ supervisor_dump_config_handler
99
+ nil
100
+ }
101
+
102
+ @rpc_server.mount_proc('/api/config.getDump') { |req, res|
103
+ $log.debug "fluentd RPC got /api/config.dump request"
104
+ $log.info "get dump in-memory config via HTTP"
105
+ res.body = supervisor_get_dump_config_handler
106
+ [nil, nil, res]
107
+ } if @enable_get_dump
108
+
109
+ @rpc_server.start
110
+ end
111
+
112
+ def stop_rpc_server
113
+ @rpc_server.shutdown
114
+ end
115
+
116
+ def install_supervisor_signal_handlers
117
+ trap :USR1 do
118
+ $log.debug "fluentd supervisor process get SIGUSR1"
119
+ supervisor_sigusr1_handler
120
+ end unless Fluent.windows?
121
+ end
122
+
123
+ def supervisor_sigusr1_handler
124
+ if log = config[:logger_initializer]
125
+ log.reopen!
126
+ end
127
+
128
+ if pid = config[:worker_pid]
129
+ Process.kill(:USR1, pid)
130
+ # don't rescue Erro::ESRSH here (invalid status)
49
131
  end
50
132
  end
51
133
 
134
+ def kill_worker
135
+ if pid = config[:worker_pid]
136
+ if Fluent.windows?
137
+ Process.kill :KILL, pid
138
+ else
139
+ Process.kill :INT, pid
140
+ end
141
+ end
142
+ end
143
+
144
+ def supervisor_dump_config_handler
145
+ $log.info config[:fluentd_conf].to_s
146
+ end
147
+
148
+ def supervisor_get_dump_config_handler
149
+ {conf: config[:fluentd_conf].to_s}
150
+ end
151
+ end
152
+
153
+ module WorkerModule
154
+ def spawn(process_manager)
155
+ main_cmd = config[:main_cmd]
156
+ @pm = process_manager.spawn(main_cmd)
157
+ end
158
+
159
+ def after_start
160
+ config[:worker_pid] = @pm.pid
161
+ end
162
+ end
163
+
164
+ class Supervisor
165
+ def self.load_config(path, params = {})
166
+
167
+ pre_loadtime = 0
168
+ pre_loadtime = params['pre_loadtime'].to_i if params['pre_loadtime']
169
+ pre_config_mtime = nil
170
+ pre_config_mtime = params['pre_config_mtime'] if params['pre_config_mtime']
171
+ config_mtime = File.mtime(path)
172
+
173
+ # reuse previous config if last load time is within 5 seconds and mtime of the config file is not changed
174
+ if Time.now - Time.at(pre_loadtime) < 5 and config_mtime == pre_config_mtime
175
+ return params['pre_conf']
176
+ end
177
+
178
+ config_fname = File.basename(path)
179
+ config_basedir = File.dirname(path)
180
+ config_data = File.read(path)
181
+ inline_config = params['inline_config']
182
+ if inline_config == '-'
183
+ config_data << "\n" << STDIN.read
184
+ elsif inline_config
185
+ config_data << "\n" << inline_config.gsub("\\n","\n")
186
+ end
187
+ fluentd_conf = Fluent::Config.parse(config_data, config_fname, config_basedir, params['use_v1_config'])
188
+ system_config = SystemConfig.create(fluentd_conf)
189
+
190
+ log_level = system_config.log_level || params['log_level']
191
+ suppress_repeated_stacktrace = system_config.suppress_repeated_stacktrace || params['suppress_repeated_stacktrace']
192
+ log_path = params['log_path']
193
+ chuser = params['chuser']
194
+ chgroup = params['chgroup']
195
+ rpc_endpoint = system_config.rpc_endpoint
196
+ enable_get_dump = system_config.enable_get_dump
197
+
198
+ log_opts = {suppress_repeated_stacktrace: suppress_repeated_stacktrace}
199
+ logger_initializer = Supervisor::LoggerInitializer.new(log_path, log_level, chuser, chgroup, log_opts)
200
+ # this #init sets initialized logger to $log
201
+ logger_initializer.init
202
+ logger = $log
203
+
204
+ daemonize = params.fetch('daemonize', false)
205
+ main_cmd = params['main_cmd']
206
+
207
+ se_config = {
208
+ worker_type: 'spawn',
209
+ workers: 1,
210
+ log_stdin: false,
211
+ log_stdout: false,
212
+ log_stderr: false,
213
+ enable_heartbeat: true,
214
+ auto_heartbeat: false,
215
+ logger: logger,
216
+ log: logger.out,
217
+ log_path: log_path,
218
+ log_level: log_level,
219
+ logger_initializer: logger_initializer,
220
+ chuser: chuser,
221
+ chgroup: chgroup,
222
+ suppress_repeated_stacktrace: suppress_repeated_stacktrace,
223
+ daemonize: daemonize,
224
+ rpc_endpoint: rpc_endpoint,
225
+ enable_get_dump: enable_get_dump,
226
+ windows_daemon_cmdline: [ServerEngine.ruby_bin_path,
227
+ File.join(File.dirname(__FILE__), 'daemon.rb'),
228
+ ServerModule.name,
229
+ WorkerModule.name,
230
+ path,
231
+ JSON.dump(params)],
232
+ fluentd_conf: fluentd_conf,
233
+ main_cmd: main_cmd,
234
+ }
235
+ pre_params = params.dup
236
+ params['pre_loadtime'] = Time.now.to_i
237
+ params['pre_config_mtime'] = config_mtime
238
+ params['pre_conf'] = se_config
239
+ # prevent pre_conf from being too big by reloading many times.
240
+ pre_params['pre_conf'] = nil
241
+ params['pre_conf'][:windows_daemon_cmdline][5] = JSON.dump(pre_params)
242
+
243
+ return se_config
244
+ end
245
+
52
246
  class LoggerInitializer
53
247
  def initialize(path, level, chuser, chgroup, opts)
54
248
  @path = path
@@ -62,15 +256,19 @@ module Fluent
62
256
  if @path && @path != "-"
63
257
  @io = File.open(@path, "a")
64
258
  if @chuser || @chgroup
65
- chuid = @chuser ? Supervisor.get_etc_passwd(@chuser).uid : nil
66
- chgid = @chgroup ? Supervisor.get_etc_group(@chgroup).gid : nil
259
+ chuid = @chuser ? ServerEngine::Daemon.get_etc_passwd(@chuser).uid : nil
260
+ chgid = @chgroup ? ServerEngine::Daemon.get_etc_group(@chgroup).gid : nil
67
261
  File.chown(chuid, chgid, @path)
68
262
  end
69
263
  else
70
264
  @io = STDOUT
71
265
  end
72
266
 
73
- $log = Fluent::Log.new(@io, @level, @opts)
267
+ dl_opts = {}
268
+ # subtract 1 to match serverengine daemon logger side logging severity.
269
+ dl_opts[:log_level] = @level - 1
270
+ logger = ServerEngine::DaemonLogger.new(@io, dl_opts)
271
+ $log = Fluent::Log.new(logger, @opts)
74
272
  $log.enable_color(false) if @path
75
273
  $log.enable_debug if @level <= Fluent::Log::LEVEL_DEBUG
76
274
  end
@@ -108,6 +306,8 @@ module Fluent
108
306
  without_source: false,
109
307
  use_v1_config: true,
110
308
  supervise: true,
309
+ signame: nil,
310
+ winsvcreg: nil,
111
311
  }
112
312
  end
113
313
 
@@ -131,53 +331,22 @@ module Fluent
131
331
  @suppress_interval = opt[:suppress_interval]
132
332
  @suppress_config_dump = opt[:suppress_config_dump]
133
333
  @without_source = opt[:without_source]
334
+ @signame = opt[:signame]
134
335
 
135
- log_opts = {suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace]}
336
+ @suppress_repeated_stacktrace = opt[:suppress_repeated_stacktrace]
337
+ log_opts = {suppress_repeated_stacktrace: @suppress_repeated_stacktrace}
136
338
  @log = LoggerInitializer.new(@log_path, @log_level, @chuser, @chgroup, log_opts)
137
339
  @finished = false
138
- @main_pid = nil
139
340
  end
140
341
 
141
- def start
342
+ def run_supervisor
142
343
  @log.init
143
344
  show_plugin_config if @show_plugin_config
144
345
  read_config
145
346
  set_system_config
146
347
 
147
348
  dry_run if @dry_run
148
- start_daemonize if @daemonize
149
- setup_rpc_server if @rpc_endpoint
150
- setup_rpc_get_dump if @enable_get_dump
151
-
152
- if @supervise
153
- install_supervisor_signal_handlers
154
- run_rpc_server if @rpc_endpoint
155
- until @finished
156
- supervise do
157
- change_privilege
158
- init_engine
159
- install_main_process_signal_handlers
160
- run_configure
161
- finish_daemonize if @daemonize
162
- run_engine
163
- exit 0
164
- end
165
- $log.error "fluentd main process died unexpectedly. restarting." unless @finished
166
- end
167
- else
168
- $log.info "starting fluentd-#{Fluent::VERSION} without supervision"
169
- run_rpc_server if @rpc_endpoint
170
- main_process do
171
- change_privilege
172
- init_engine
173
- install_main_process_signal_handlers
174
- run_configure
175
- finish_daemonize if @daemonize
176
- run_engine
177
- exit 0
178
- end
179
- end
180
- stop_rpc_server if @rpc_endpoint
349
+ supervise
181
350
  end
182
351
 
183
352
  def options
@@ -189,14 +358,38 @@ module Fluent
189
358
  }
190
359
  end
191
360
 
361
+ def run_worker
362
+ begin
363
+ require 'sigdump/setup'
364
+ rescue Exception
365
+ # ignore LoadError and others (related with signals): it may raise these errors in Windows
366
+ end
367
+ @log.init
368
+ Process.setproctitle("worker:#{@process_name}") if @process_name
369
+
370
+ show_plugin_config if @show_plugin_config
371
+ read_config
372
+ set_system_config
373
+
374
+ install_main_process_signal_handlers
375
+
376
+ $log.info "starting fluentd-#{Fluent::VERSION} without supervision"
377
+
378
+ main_process do
379
+ change_privilege
380
+ init_engine
381
+ run_configure
382
+ run_engine
383
+ exit 0
384
+ end
385
+ end
386
+
192
387
  private
193
388
 
194
389
  def dry_run
195
390
  $log.info "starting fluentd-#{Fluent::VERSION} as dry run mode"
196
-
197
391
  change_privilege
198
392
  init_engine
199
- install_main_process_signal_handlers
200
393
  run_configure
201
394
  exit 0
202
395
  rescue => e
@@ -206,6 +399,8 @@ module Fluent
206
399
 
207
400
  def show_plugin_config
208
401
  $log.info "Show config for #{@show_plugin_config}"
402
+ @system_config = SystemConfig.new
403
+ init_engine
209
404
  name, type = @show_plugin_config.split(":")
210
405
  plugin = Plugin.__send__("new_#{name}", type)
211
406
  dumped_config = "\n"
@@ -227,136 +422,84 @@ module Fluent
227
422
  exit 1
228
423
  end
229
424
 
230
- def start_daemonize
231
- @wait_daemonize_pipe_r, @wait_daemonize_pipe_w = IO.pipe
232
-
233
- if fork
234
- # console process
235
- @wait_daemonize_pipe_w.close
236
- @wait_daemonize_pipe_w = nil
237
- wait_daemonize
238
- exit 0
239
- end
240
-
241
- # daemonize intermediate process
242
- @wait_daemonize_pipe_r.close
243
- @wait_daemonize_pipe_r = nil
244
-
245
- # in case the child process forked during run_configure
246
- @wait_daemonize_pipe_w.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
247
-
248
- Process.setsid
249
- exit!(0) if fork
250
- File.umask(0)
251
-
252
- # supervisor process
253
- @supervisor_pid = Process.pid
254
- end
425
+ def supervise
426
+ $log.info "starting fluentd-#{Fluent::VERSION}"
255
427
 
256
- def wait_daemonize
257
- supervisor_pid = @wait_daemonize_pipe_r.read
258
- if supervisor_pid.empty?
259
- # initialization failed
260
- exit! 1
428
+ if Fluent.windows?
429
+ fluentd_spawn_cmd = ServerEngine.ruby_bin_path + " -Eascii-8bit:ascii-8bit "
430
+ fluentd_spawn_cmd << ' "' + $0.gsub('"', '""') + '" '
431
+ $fluentdargv.each{|a|
432
+ fluentd_spawn_cmd << ('"' + a.gsub('"', '""') + '" ')
433
+ }
434
+ else
435
+ fluentd_spawn_cmd = ServerEngine.ruby_bin_path + " -Eascii-8bit:ascii-8bit "
436
+ fluentd_spawn_cmd << $0.shellescape + ' '
437
+ $fluentdargv.each{|a|
438
+ fluentd_spawn_cmd << (a.shellescape + " ")
439
+ }
261
440
  end
262
441
 
263
- @wait_daemonize_pipe_r.close
264
- @wait_daemonize_pipe_r = nil
265
-
266
- # write pid file
267
- File.open(@daemonize, "w") {|f|
268
- f.write supervisor_pid
442
+ fluentd_spawn_cmd << ("--no-supervisor")
443
+ $log.info "spawn command to main: " + fluentd_spawn_cmd
444
+
445
+ params = {}
446
+ params['main_cmd'] = fluentd_spawn_cmd
447
+ params['daemonize'] = @daemonize
448
+ params['inline_config'] = @inline_config
449
+ params['log_path'] = @log_path
450
+ params['log_level'] = @log_level
451
+ params['chuser'] = @chuser
452
+ params['chgroup'] = @chgroup
453
+ params['use_v1_config'] = @use_v1_config
454
+ params['suppress_repeated_stacktrace'] = @suppress_repeated_stacktrace
455
+
456
+ se = ServerEngine.create(ServerModule, WorkerModule){
457
+ Fluent::Supervisor.load_config(@config_path, params)
269
458
  }
459
+ se.run
270
460
  end
271
461
 
272
- def finish_daemonize
273
- if @wait_daemonize_pipe_w
274
- STDIN.reopen("/dev/null")
275
- STDOUT.reopen("/dev/null", "w")
276
- STDERR.reopen("/dev/null", "w")
277
- @wait_daemonize_pipe_w.write @supervisor_pid.to_s
278
- @wait_daemonize_pipe_w.close
279
- @wait_daemonize_pipe_w = nil
280
- end
281
- end
282
-
283
- def setup_rpc_server
284
- @rpc_server = RPC::Server.new(@rpc_endpoint, $log)
285
-
286
- # built-in RPC for signals
287
- @rpc_server.mount_proc('/api/processes.interruptWorkers') { |req, res|
288
- $log.debug "fluentd RPC got /api/processes.interruptWorkers request"
289
- supervisor_sigint_handler
290
- nil
291
- }
292
- @rpc_server.mount_proc('/api/processes.killWorkers') { |req, res|
293
- $log.debug "fluentd RPC got /api/processes.killWorkers request"
294
- supervisor_sigterm_handler
295
- nil
296
- }
297
- @rpc_server.mount_proc('/api/plugins.flushBuffers') { |req, res|
298
- $log.debug "fluentd RPC got /api/plugins.flushBuffers request"
299
- supervisor_sigusr1_handler
300
- nil
301
- }
302
- @rpc_server.mount_proc('/api/config.reload') { |req, res|
303
- $log.debug "fluentd RPC got /api/config.reload request"
304
- $log.info "restarting"
305
- supervisor_sighup_handler
306
- nil
307
- }
308
- @rpc_server.mount_proc('/api/config.dump') { |req, res|
309
- $log.debug "fluentd RPC got /api/config.dump request"
310
- $log.info "dump in-memory config"
311
- supervisor_dump_config_handler
312
- nil
313
- }
314
- end
315
-
316
- def setup_rpc_get_dump
317
- @rpc_server.mount_proc('/api/config.getDump') { |req, res|
318
- $log.debug "fluentd RPC got /api/config.dump request"
319
- $log.info "get dump in-memory config via HTTP"
320
- res.body = supervisor_get_dump_config_handler
321
- [nil, nil, res]
322
- }
323
- end
324
-
325
- def run_rpc_server
326
- @rpc_server.start
327
- end
328
-
329
- def stop_rpc_server
330
- @rpc_server.shutdown
331
- end
332
-
333
- def supervise(&block)
334
- start_time = Time.now
462
+ def install_main_process_signal_handlers
463
+ # Fluentd worker process (worker of ServerEngine) don't use code in serverengine to set signal handlers,
464
+ # because it does almost nothing.
465
+ # This method is the only method to set signal handlers in Fluentd worker process.
335
466
 
336
- Process.setproctitle("supervisor:#{@process_name}") if @process_name
337
- $log.info "starting fluentd-#{Fluent::VERSION}"
338
- @main_pid = fork do
339
- main_process(&block)
467
+ # When user use Ctrl + C not SIGINT, SIGINT is sent to all process in same process group.
468
+ # ServerEngine server process will send SIGTERM to child(spawned) processes by that SIGINT, so
469
+ # worker process SHOULD NOT do anything with SIGINT, SHOULD just ignore.
470
+ trap :INT do
471
+ $log.debug "fluentd main process get SIGINT"
340
472
  end
341
473
 
342
- if @daemonize && @wait_daemonize_pipe_w
343
- STDIN.reopen("/dev/null")
344
- STDOUT.reopen("/dev/null", "w")
345
- STDERR.reopen("/dev/null", "w")
346
- @wait_daemonize_pipe_w.close
347
- @wait_daemonize_pipe_w = nil
474
+ trap :TERM do
475
+ $log.debug "fluentd main process get SIGTERM"
476
+ unless @finished
477
+ @finished = true
478
+ $log.debug "getting start to shutdown main process"
479
+ Fluent::Engine.stop
480
+ end
348
481
  end
349
482
 
350
- Process.waitpid(@main_pid)
351
- @main_pid = nil
352
- ecode = $?.to_i
483
+ trap :USR1 do
484
+ flush_buffer
485
+ end unless Fluent.windows?
486
+ end
353
487
 
354
- $log.info "process finished", code: ecode
488
+ def flush_buffer
489
+ $log.debug "fluentd main process get SIGUSR1"
490
+ $log.info "force flushing buffered events"
491
+ @log.reopen!
355
492
 
356
- if !@finished && Time.now - start_time < 1
357
- $log.warn "process died within 1 second. exit."
358
- exit ecode
359
- end
493
+ # Creating new thread due to mutex can't lock
494
+ # in main thread during trap context
495
+ Thread.new {
496
+ begin
497
+ Fluent::Engine.flush!
498
+ $log.debug "flushing thread: flushed"
499
+ rescue Exception => e
500
+ $log.warn "flushing thread error: #{e}"
501
+ end
502
+ }.run
360
503
  end
361
504
 
362
505
  def main_process(&block)
@@ -364,12 +507,14 @@ module Fluent
364
507
 
365
508
  begin
366
509
  block.call
367
-
368
510
  rescue Fluent::ConfigError
369
511
  $log.error "config error", file: @config_path, error: $!.to_s
370
512
  $log.debug_backtrace
371
513
  unless @log.stdout?
372
- console = Fluent::Log.new(STDOUT, @log_level).enable_debug
514
+ logger = ServerEngine::DaemonLogger.new(STDOUT)
515
+ log = Fluent::Log.new(logger)
516
+ log.level = @log_level
517
+ console = log.enable_debug
373
518
  console.error "config error", file: @config_path, error: $!.to_s
374
519
  console.debug_backtrace
375
520
  end
@@ -378,7 +523,10 @@ module Fluent
378
523
  $log.error "unexpected error", error: $!.to_s
379
524
  $log.error_backtrace
380
525
  unless @log.stdout?
381
- console = Fluent::Log.new(STDOUT, @log_level).enable_debug
526
+ logger = ServerEngine::DaemonLogger.new(STDOUT)
527
+ log = Fluent::Log.new(logger)
528
+ log.level = @log_level
529
+ console = log.enable_debug
382
530
  console.error "unexpected error", error: $!.to_s
383
531
  console.error_backtrace
384
532
  end
@@ -387,86 +535,6 @@ module Fluent
387
535
  exit! 1
388
536
  end
389
537
 
390
- def install_supervisor_signal_handlers
391
- trap :INT do
392
- $log.debug "fluentd supervisor process get SIGINT"
393
- supervisor_sigint_handler
394
- end
395
-
396
- trap :TERM do
397
- $log.debug "fluentd supervisor process get SIGTERM"
398
- supervisor_sigterm_handler
399
- end
400
-
401
- trap :HUP do
402
- $log.debug "fluentd supervisor process get SIGHUP"
403
- $log.info "restarting"
404
- supervisor_sighup_handler
405
- end
406
-
407
- trap :USR1 do
408
- $log.debug "fluentd supervisor process get SIGUSR1"
409
- supervisor_sigusr1_handler
410
- end
411
- end
412
-
413
- def supervisor_sigint_handler
414
- @finished = true
415
- if pid = @main_pid
416
- # kill processes only still exists
417
- unless Process.waitpid(pid, Process::WNOHANG)
418
- begin
419
- Process.kill(:INT, pid)
420
- rescue Errno::ESRCH
421
- # ignore processes already died
422
- end
423
- end
424
- end
425
- end
426
-
427
- def supervisor_sigterm_handler
428
- @finished = true
429
- if pid = @main_pid
430
- # kill processes only still exists
431
- unless Process.waitpid(pid, Process::WNOHANG)
432
- begin
433
- Process.kill(:TERM, pid)
434
- rescue Errno::ESRCH
435
- # ignore processes already died
436
- end
437
- end
438
- end
439
- end
440
-
441
- def supervisor_sighup_handler
442
- # Creating new thread due to mutex can't lock
443
- # in main thread during trap context
444
- Thread.new {
445
- read_config
446
- set_system_config
447
- if pid = @main_pid
448
- Process.kill(:TERM, pid)
449
- # don't resuce Erro::ESRSH here (invalid status)
450
- end
451
- }.run
452
- end
453
-
454
- def supervisor_sigusr1_handler
455
- @log.reopen!
456
- if pid = @main_pid
457
- Process.kill(:USR1, pid)
458
- # don't resuce Erro::ESRSH here (invalid status)
459
- end
460
- end
461
-
462
- def supervisor_dump_config_handler
463
- $log.info @conf.to_s
464
- end
465
-
466
- def supervisor_get_dump_config_handler
467
- {conf: @conf.to_s}
468
- end
469
-
470
538
  def read_config
471
539
  $log.info "reading config file", path: @config_path
472
540
  @config_fname = File.basename(@config_path)
@@ -485,25 +553,8 @@ module Fluent
485
553
  @system_config.apply(self)
486
554
  end
487
555
 
488
- def run_configure
489
- Fluent::Engine.run_configure(@conf)
490
- end
491
-
492
556
  def change_privilege
493
- if @chgroup
494
- etc_group = Supervisor.get_etc_group(@chgroup)
495
- Process::GID.change_privilege(etc_group.gid)
496
- end
497
-
498
- if @chuser
499
- etc_pw = Supervisor.get_etc_passwd(@chuser)
500
- user_groups = [etc_pw.gid]
501
- Etc.setgrent
502
- Etc.group { |gr| user_groups << gr.gid if gr.mem.include?(etc_pw.name) } # emulate 'id -G'
503
-
504
- Process.groups = Process.groups | user_groups
505
- Process::UID.change_privilege(etc_pw.uid)
506
- end
557
+ ServerEngine::Daemon.change_privilege(@chuser, @chgroup)
507
558
  end
508
559
 
509
560
  def init_engine
@@ -516,54 +567,13 @@ module Fluent
516
567
  @plugin_dirs.each {|dir|
517
568
  if Dir.exist?(dir)
518
569
  dir = File.expand_path(dir)
519
- Fluent::Engine.load_plugin_dir(dir)
570
+ Fluent::Engine.add_plugin_dir(dir)
520
571
  end
521
572
  }
522
573
  end
523
574
 
524
- def install_main_process_signal_handlers
525
- # Strictly speaking, these signal handling is not thread safe.
526
- # But enough safe to limit twice call of Fluent::Engine.stop.
527
-
528
- trap :INT do
529
- $log.debug "fluentd main process get SIGINT"
530
- unless @finished
531
- @finished = true
532
- $log.debug "getting start to shutdown main process"
533
- Fluent::Engine.stop
534
- end
535
- end
536
-
537
- trap :TERM do
538
- $log.debug "fluentd main process get SIGTERM"
539
- unless @finished
540
- @finished = true
541
- $log.debug "getting start to shutdown main process"
542
- Fluent::Engine.stop
543
- end
544
- end
545
-
546
- trap :HUP do
547
- # TODO
548
- $log.debug "fluentd main process get SIGHUP"
549
- end
550
-
551
- trap :USR1 do
552
- $log.debug "fluentd main process get SIGUSR1"
553
- $log.info "force flushing buffered events"
554
- @log.reopen!
555
-
556
- # Creating new thread due to mutex can't lock
557
- # in main thread during trap context
558
- Thread.new {
559
- begin
560
- Fluent::Engine.flush!
561
- $log.debug "flushing thread: flushed"
562
- rescue Exception => e
563
- $log.warn "flushing thread error: #{e}"
564
- end
565
- }.run
566
- end
575
+ def run_configure
576
+ Fluent::Engine.run_configure(@conf)
567
577
  end
568
578
 
569
579
  def run_engine