fluentd 1.7.4-x64-mingw32 → 1.8.0-x64-mingw32

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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -1
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG.md +70 -0
  5. data/MAINTAINERS.md +1 -0
  6. data/example/out_forward_sd.conf +17 -0
  7. data/example/sd.yaml +8 -0
  8. data/fluentd.gemspec +1 -1
  9. data/lib/fluent/agent.rb +3 -1
  10. data/lib/fluent/command/cat.rb +1 -2
  11. data/lib/fluent/command/fluentd.rb +16 -8
  12. data/lib/fluent/compat/call_super_mixin.rb +9 -0
  13. data/lib/fluent/compat/exec_util.rb +1 -1
  14. data/lib/fluent/config/configure_proxy.rb +4 -4
  15. data/lib/fluent/config/element.rb +28 -15
  16. data/lib/fluent/config/error.rb +6 -0
  17. data/lib/fluent/config/literal_parser.rb +24 -2
  18. data/lib/fluent/config/section.rb +43 -6
  19. data/lib/fluent/config/types.rb +98 -26
  20. data/lib/fluent/configurable.rb +2 -2
  21. data/lib/fluent/counter/base_socket.rb +2 -4
  22. data/lib/fluent/engine.rb +41 -122
  23. data/lib/fluent/event.rb +5 -7
  24. data/lib/fluent/fluent_log_event_router.rb +141 -0
  25. data/lib/fluent/msgpack_factory.rb +19 -2
  26. data/lib/fluent/plugin.rb +10 -1
  27. data/lib/fluent/plugin/base.rb +2 -2
  28. data/lib/fluent/plugin/buf_file.rb +11 -7
  29. data/lib/fluent/plugin/buf_file_single.rb +8 -5
  30. data/lib/fluent/plugin/buffer/chunk.rb +1 -1
  31. data/lib/fluent/plugin/buffer/file_chunk.rb +4 -6
  32. data/lib/fluent/plugin/buffer/file_single_chunk.rb +3 -5
  33. data/lib/fluent/plugin/formatter_csv.rb +23 -1
  34. data/lib/fluent/plugin/formatter_stdout.rb +1 -1
  35. data/lib/fluent/plugin/in_forward.rb +1 -1
  36. data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
  37. data/lib/fluent/plugin/in_tail.rb +6 -0
  38. data/lib/fluent/plugin/in_unix.rb +1 -1
  39. data/lib/fluent/plugin/out_forward.rb +77 -28
  40. data/lib/fluent/plugin/out_forward/ack_handler.rb +1 -1
  41. data/lib/fluent/plugin/out_forward/load_balancer.rb +5 -2
  42. data/lib/fluent/plugin/out_stream.rb +1 -1
  43. data/lib/fluent/plugin/output.rb +11 -3
  44. data/lib/fluent/plugin/parser.rb +1 -0
  45. data/lib/fluent/plugin/sd_file.rb +155 -0
  46. data/lib/fluent/plugin/sd_static.rb +58 -0
  47. data/lib/fluent/plugin/service_discovery.rb +80 -0
  48. data/lib/fluent/plugin_helper.rb +1 -0
  49. data/lib/fluent/plugin_helper/child_process.rb +3 -3
  50. data/lib/fluent/plugin_helper/compat_parameters.rb +11 -1
  51. data/lib/fluent/plugin_helper/extract.rb +1 -1
  52. data/lib/fluent/plugin_helper/inject.rb +1 -1
  53. data/lib/fluent/plugin_helper/record_accessor.rb +10 -19
  54. data/lib/fluent/plugin_helper/server.rb +8 -4
  55. data/lib/fluent/plugin_helper/service_discovery.rb +80 -0
  56. data/lib/fluent/plugin_helper/service_discovery/manager.rb +132 -0
  57. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  58. data/lib/fluent/plugin_id.rb +7 -0
  59. data/lib/fluent/root_agent.rb +7 -9
  60. data/lib/fluent/supervisor.rb +192 -211
  61. data/lib/fluent/system_config.rb +26 -52
  62. data/lib/fluent/test/driver/base_owned.rb +15 -2
  63. data/lib/fluent/time.rb +8 -6
  64. data/lib/fluent/version.rb +1 -1
  65. data/test/command/test_fluentd.rb +12 -7
  66. data/test/config/test_configurable.rb +154 -0
  67. data/test/config/test_element.rb +18 -0
  68. data/test/config/test_literal_parser.rb +4 -0
  69. data/test/config/test_system_config.rb +48 -91
  70. data/test/config/test_types.rb +293 -120
  71. data/test/counter/test_client.rb +8 -4
  72. data/test/plugin/data/sd_file/config +11 -0
  73. data/test/plugin/data/sd_file/config.json +17 -0
  74. data/test/plugin/data/sd_file/config.yaml +11 -0
  75. data/test/plugin/data/sd_file/config.yml +11 -0
  76. data/test/plugin/data/sd_file/invalid_config.yml +7 -0
  77. data/test/plugin/out_forward/test_handshake_protocol.rb +2 -2
  78. data/test/plugin/out_forward/test_load_balancer.rb +1 -1
  79. data/test/plugin/out_forward/test_socket_cache.rb +2 -2
  80. data/test/plugin/test_buf_file.rb +40 -0
  81. data/test/plugin/test_buf_file_single.rb +32 -0
  82. data/test/plugin/test_buffer_file_chunk.rb +0 -11
  83. data/test/plugin/test_buffer_file_single_chunk.rb +0 -10
  84. data/test/plugin/test_formatter_csv.rb +9 -0
  85. data/test/plugin/test_in_forward.rb +9 -9
  86. data/test/plugin/test_in_monitor_agent.rb +37 -10
  87. data/test/plugin/test_in_unix.rb +5 -5
  88. data/test/plugin/test_out_forward.rb +45 -1
  89. data/test/plugin/test_out_stdout.rb +36 -1
  90. data/test/plugin/test_out_stream.rb +3 -3
  91. data/test/plugin/test_output.rb +25 -1
  92. data/test/plugin/test_sd_file.rb +211 -0
  93. data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
  94. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
  95. data/test/plugin_helper/test_server.rb +13 -0
  96. data/test/plugin_helper/test_service_discovery.rb +72 -0
  97. data/test/test_event.rb +15 -15
  98. data/test/test_fluent_log_event_router.rb +99 -0
  99. data/test/test_logger_initializer.rb +26 -0
  100. data/test/test_supervisor.rb +30 -59
  101. metadata +43 -6
@@ -20,7 +20,9 @@ require 'fluent/config/error'
20
20
 
21
21
  module Fluent
22
22
  module Config
23
- def self.size_value(str)
23
+ def self.size_value(str, opts = {}, name = nil)
24
+ return nil if str.nil?
25
+
24
26
  case str.to_s
25
27
  when /([0-9]+)k/i
26
28
  $~[1].to_i * 1024
@@ -31,11 +33,13 @@ module Fluent
31
33
  when /([0-9]+)t/i
32
34
  $~[1].to_i * (1024 ** 4)
33
35
  else
34
- str.to_i
36
+ INTEGER_TYPE.call(str, opts, name)
35
37
  end
36
38
  end
37
39
 
38
- def self.time_value(str)
40
+ def self.time_value(str, opts = {}, name = nil)
41
+ return nil if str.nil?
42
+
39
43
  case str.to_s
40
44
  when /([0-9]+)s/
41
45
  $~[1].to_i
@@ -46,12 +50,13 @@ module Fluent
46
50
  when /([0-9]+)d/
47
51
  $~[1].to_i * 24 * 60 * 60
48
52
  else
49
- str.to_f
53
+ FLOAT_TYPE.call(str, opts, name)
50
54
  end
51
55
  end
52
56
 
53
- def self.bool_value(str)
57
+ def self.bool_value(str, opts = {}, name = nil)
54
58
  return nil if str.nil?
59
+
55
60
  case str.to_s
56
61
  when 'true', 'yes'
57
62
  true
@@ -64,14 +69,17 @@ module Fluent
64
69
  # parser should pass empty string in this case but changing behaviour may break existing environment so keep parser behaviour. Just ignore comment value in boolean handling for now.
65
70
  if str.respond_to?('start_with?') && str.start_with?('#')
66
71
  true
72
+ elsif opts[:strict]
73
+ raise Fluent::ConfigError, "#{name}: invalid bool value: #{str}"
67
74
  else
68
75
  nil
69
76
  end
70
77
  end
71
78
  end
72
79
 
73
- def self.regexp_value(str)
80
+ def self.regexp_value(str, opts = {}, name = nil)
74
81
  return nil unless str
82
+
75
83
  return Regexp.compile(str) unless str.start_with?("/")
76
84
  right_slash_position = str.rindex("/")
77
85
  if right_slash_position < str.size - 3
@@ -84,12 +92,21 @@ module Fluent
84
92
  Regexp.compile(str[1...right_slash_position], option)
85
93
  end
86
94
 
87
- STRING_TYPE = Proc.new { |val, opts|
95
+ def self.string_value(val, opts = {}, name = nil)
96
+ return nil if val.nil?
97
+
88
98
  v = val.to_s
89
99
  v = v.frozen? ? v.dup : v # config_param can't assume incoming string is mutable
90
100
  v.force_encoding(Encoding::UTF_8)
101
+ end
102
+
103
+ STRING_TYPE = Proc.new { |val, opts = {}, name = nil|
104
+ Config.string_value(val, opts, name)
91
105
  }
92
- ENUM_TYPE = Proc.new { |val, opts|
106
+
107
+ def self.enum_value(val, opts = {}, name = nil)
108
+ return nil if val.nil?
109
+
93
110
  s = val.to_sym
94
111
  list = opts[:list]
95
112
  raise "Plugin BUG: config type 'enum' requires :list of symbols" unless list.is_a?(Array) && list.all?{|v| v.is_a? Symbol }
@@ -97,33 +114,77 @@ module Fluent
97
114
  raise ConfigError, "valid options are #{list.join(',')} but got #{val}"
98
115
  end
99
116
  s
117
+ end
118
+
119
+ ENUM_TYPE = Proc.new { |val, opts = {}, name = nil|
120
+ Config.enum_value(val, opts, name)
121
+ }
122
+
123
+ INTEGER_TYPE = Proc.new { |val, opts = {}, name = nil|
124
+ if val.nil?
125
+ nil
126
+ elsif opts[:strict]
127
+ begin
128
+ Integer(val)
129
+ rescue ArgumentError, TypeError => e
130
+ raise ConfigError, "#{name}: #{e.message}"
131
+ end
132
+ else
133
+ val.to_i
134
+ end
100
135
  }
101
- INTEGER_TYPE = Proc.new { |val, opts| val.to_i }
102
- FLOAT_TYPE = Proc.new { |val, opts| val.to_f }
103
- SIZE_TYPE = Proc.new { |val, opts| Config.size_value(val) }
104
- BOOL_TYPE = Proc.new { |val, opts| Config.bool_value(val) }
105
- TIME_TYPE = Proc.new { |val, opts| Config.time_value(val) }
106
- REGEXP_TYPE = Proc.new { |val, opts| Config.regexp_value(val) }
107
-
108
- REFORMAT_VALUE = ->(type, value) {
136
+
137
+ FLOAT_TYPE = Proc.new { |val, opts = {}, name = nil|
138
+ if val.nil?
139
+ nil
140
+ elsif opts[:strict]
141
+ begin
142
+ Float(val)
143
+ rescue ArgumentError, TypeError => e
144
+ raise ConfigError, "#{name}: #{e.message}"
145
+ end
146
+ else
147
+ val.to_f
148
+ end
149
+ }
150
+
151
+ SIZE_TYPE = Proc.new { |val, opts = {}, name = nil|
152
+ Config.size_value(val, opts, name)
153
+ }
154
+
155
+ BOOL_TYPE = Proc.new { |val, opts = {}, name = nil|
156
+ Config.bool_value(val, opts, name)
157
+ }
158
+
159
+ TIME_TYPE = Proc.new { |val, opts = {}, name = nil|
160
+ Config.time_value(val, opts, name)
161
+ }
162
+
163
+ REGEXP_TYPE = Proc.new { |val, opts = {}, name = nil|
164
+ Config.regexp_value(val, opts, name)
165
+ }
166
+
167
+ REFORMAT_VALUE = ->(type, value, opts = {}, name = nil) {
109
168
  if value.nil?
110
169
  value
111
170
  else
112
171
  case type
113
172
  when :string then value.to_s.force_encoding(Encoding::UTF_8)
114
- when :integer then value.to_i
115
- when :float then value.to_f
116
- when :size then Config.size_value(value)
117
- when :bool then Config.bool_value(value)
118
- when :time then Config.time_value(value)
119
- when :regexp then Config.regexp_value(value)
173
+ when :integer then INTEGER_TYPE.call(value, opts, name)
174
+ when :float then FLOAT_TYPE.call(value, opts, name)
175
+ when :size then Config.size_value(value, opts, name)
176
+ when :bool then Config.bool_value(value, opts, name)
177
+ when :time then Config.time_value(value, opts, name)
178
+ when :regexp then Config.regexp_value(value, opts, name)
120
179
  else
121
180
  raise "unknown type in REFORMAT: #{type}"
122
181
  end
123
182
  end
124
183
  }
125
184
 
126
- HASH_TYPE = Proc.new { |val, opts|
185
+ def self.hash_value(val, opts = {}, name = nil)
186
+ return nil if val.nil?
187
+
127
188
  param = if val.is_a?(String)
128
189
  val.start_with?('{') ? JSON.load(val) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
129
190
  else
@@ -138,12 +199,19 @@ module Fluent
138
199
  newparam = {}
139
200
  param.each_pair do |key, value|
140
201
  new_key = opts[:symbolize_keys] ? key.to_sym : key
141
- newparam[new_key] = opts[:value_type] ? REFORMAT_VALUE.call(opts[:value_type], value) : value
202
+ newparam[new_key] = opts[:value_type] ? REFORMAT_VALUE.call(opts[:value_type], value, opts, new_key) : value
142
203
  end
143
204
  newparam
144
205
  end
206
+ end
207
+
208
+ HASH_TYPE = Proc.new { |val, opts = {}, name = nil|
209
+ Config.hash_value(val, opts, name)
145
210
  }
146
- ARRAY_TYPE = Proc.new { |val, opts|
211
+
212
+ def self.array_value(val, opts = {}, name = nil)
213
+ return nil if val.nil?
214
+
147
215
  param = if val.is_a?(String)
148
216
  val.start_with?('[') ? JSON.load(val) : val.strip.split(/\s*,\s*/)
149
217
  else
@@ -153,10 +221,14 @@ module Fluent
153
221
  raise ConfigError, "array required but got #{val.inspect}"
154
222
  end
155
223
  if opts[:value_type]
156
- param.map{|v| REFORMAT_VALUE.call(opts[:value_type], v) }
224
+ param.map{|v| REFORMAT_VALUE.call(opts[:value_type], v, opts, nil) }
157
225
  else
158
226
  param
159
227
  end
228
+ end
229
+
230
+ ARRAY_TYPE = Proc.new { |val, opts = {}, name = nil|
231
+ Config.array_value(val, opts, name)
160
232
  }
161
233
  end
162
234
  end
@@ -74,7 +74,7 @@ module Fluent
74
74
  Fluent::Config::SectionGenerator.generate(proxy, conf, nil, nil)
75
75
  end
76
76
 
77
- def configure(conf)
77
+ def configure(conf, strict_config_value=false)
78
78
  @config = conf
79
79
 
80
80
  logger = if self.respond_to?(:log)
@@ -91,7 +91,7 @@ module Fluent
91
91
 
92
92
  # In the nested section, can't get plugin class through proxies so get plugin class here
93
93
  plugin_class = Fluent::Plugin.lookup_type_from_class(proxy.name.to_s)
94
- root = Fluent::Config::SectionGenerator.generate(proxy, conf, logger, plugin_class)
94
+ root = Fluent::Config::SectionGenerator.generate(proxy, conf, logger, plugin_class, [], strict_config_value)
95
95
  @config_root_section = root
96
96
 
97
97
  root.instance_eval{ @params.keys }.each do |param_name|
@@ -20,14 +20,12 @@ require 'fluent/msgpack_factory'
20
20
  module Fluent
21
21
  module Counter
22
22
  class BaseSocket < Coolio::TCPSocket
23
- include Fluent::MessagePackFactory::Mixin
24
-
25
23
  def packed_write(data)
26
24
  write pack(data)
27
25
  end
28
26
 
29
27
  def on_read(data)
30
- msgpack_unpacker.feed_each(data) do |d|
28
+ Fluent::MessagePackFactory.msgpack_unpacker.feed_each(data) do |d|
31
29
  on_message d
32
30
  end
33
31
  end
@@ -39,7 +37,7 @@ module Fluent
39
37
  private
40
38
 
41
39
  def pack(data)
42
- msgpack_packer.pack(data)
40
+ Fluent::MessagePackFactory.msgpack_packer.pack(data)
43
41
  end
44
42
  end
45
43
  end
@@ -22,46 +22,36 @@ require 'fluent/root_agent'
22
22
  require 'fluent/time'
23
23
  require 'fluent/system_config'
24
24
  require 'fluent/plugin'
25
+ require 'fluent/fluent_log_event_router'
25
26
 
26
27
  module Fluent
27
28
  class EngineClass
29
+ # For compat. remove it in fluentd v2
28
30
  include Fluent::MessagePackFactory::Mixin
29
31
 
30
32
  def initialize
31
33
  @root_agent = nil
32
- @default_loop = nil
33
34
  @engine_stopped = false
34
35
  @_worker_id = nil
35
36
 
36
- @log_event_router = nil
37
- @log_emit_thread = nil
38
- @log_event_loop_stop = false
39
- @log_event_loop_graceful_stop = false
40
- @log_event_queue = []
41
37
  @log_event_verbose = false
42
-
43
38
  @suppress_config_dump = false
39
+ @without_source = false
44
40
 
41
+ @fluent_log_event_router = nil
45
42
  @system_config = SystemConfig.new
46
43
 
47
- @dry_run_mode = false
44
+ @supervisor_mode = false
48
45
  end
49
46
 
50
47
  MAINLOOP_SLEEP_INTERVAL = 0.3
51
48
 
52
- MATCH_CACHE_SIZE = 1024
53
- LOG_EMIT_INTERVAL = 0.1
54
-
55
- attr_reader :root_agent
56
- attr_reader :matches, :sources
57
- attr_reader :system_config
49
+ attr_reader :root_agent, :system_config, :supervisor_mode
58
50
 
59
- attr_accessor :dry_run_mode
60
-
61
- def init(system_config)
51
+ def init(system_config, supervisor_mode: false)
62
52
  @system_config = system_config
53
+ @supervisor_mode = supervisor_mode
63
54
 
64
- suppress_interval(system_config.emit_error_log_interval) unless system_config.emit_error_log_interval.nil?
65
55
  @suppress_config_dump = system_config.suppress_config_dump unless system_config.suppress_config_dump.nil?
66
56
  @without_source = system_config.without_source unless system_config.without_source.nil?
67
57
 
@@ -69,8 +59,6 @@ module Fluent
69
59
 
70
60
  @root_agent = RootAgent.new(log: log, system_config: @system_config)
71
61
 
72
- MessagePackFactory.init
73
-
74
62
  self
75
63
  end
76
64
 
@@ -78,11 +66,6 @@ module Fluent
78
66
  $log
79
67
  end
80
68
 
81
- def suppress_interval(interval_time)
82
- @suppress_emit_error_log_interval = interval_time
83
- @next_emit_error_log_time = Time.now.to_i
84
- end
85
-
86
69
  def parse_config(io, fname, basepath = Dir.pwd, v1_config = false)
87
70
  if fname =~ /\.rb$/
88
71
  require 'fluent/config/dsl'
@@ -92,80 +75,47 @@ module Fluent
92
75
  end
93
76
  end
94
77
 
95
- def run_configure(conf)
78
+ def run_configure(conf, dry_run: false)
96
79
  configure(conf)
97
- conf.check_not_fetched { |key, e|
80
+ conf.check_not_fetched do |key, e|
98
81
  parent_name, plugin_name = e.unused_in
99
- if parent_name
100
- message = if plugin_name
101
- "section <#{e.name}> is not used in <#{parent_name}> of #{plugin_name} plugin"
102
- else
103
- "section <#{e.name}> is not used in <#{parent_name}>"
104
- end
105
- if e.for_every_workers?
106
- $log.warn :worker0, message
107
- elsif e.for_this_worker?
108
- $log.warn message
109
- end
110
- next
111
- end
112
- unless e.name == 'system'
113
- unless @without_source && e.name == 'source'
114
- message = "parameter '#{key}' in #{e.to_s.strip} is not used."
115
- if e.for_every_workers?
116
- $log.warn :worker0, message
117
- elsif e.for_this_worker?
118
- $log.warn message
119
- end
120
- end
82
+ message = if parent_name && plugin_name
83
+ "section <#{e.name}> is not used in <#{parent_name}> of #{plugin_name} plugin"
84
+ elsif parent_name
85
+ "section <#{e.name}> is not used in <#{parent_name}>"
86
+ elsif e.name != 'system' && !(@without_source && e.name == 'source')
87
+ "parameter '#{key}' in #{e.to_s.strip} is not used."
88
+ else
89
+ nil
90
+ end
91
+ next if message.nil?
92
+
93
+ if dry_run && @supervisor_mode
94
+ $log.warn :supervisor, message
95
+ elsif e.for_every_workers?
96
+ $log.warn :worker0, message
97
+ elsif e.for_this_worker?
98
+ $log.warn message
121
99
  end
122
- }
100
+ end
123
101
  end
124
102
 
125
103
  def configure(conf)
126
- # plugins / configuration dumps
127
- Gem::Specification.find_all.select{|x| x.name =~ /^fluent(d|-(plugin|mixin)-.*)$/}.each do |spec|
128
- $log.info :worker0, "gem '#{spec.name}' version '#{spec.version}'"
129
- end
130
-
131
104
  @root_agent.configure(conf)
132
105
 
133
- begin
134
- log_event_agent = @root_agent.find_label(Fluent::Log::LOG_EVENT_LABEL)
135
- log_event_router = log_event_agent.event_router
106
+ @fluent_log_event_router = FluentLogEventRouter.build(@root_agent)
136
107
 
137
- # suppress mismatched tags only for <label @FLUENT_LOG> label.
138
- # it's not suppressed in default event router for non-log-event events
139
- log_event_router.suppress_missing_match!
140
-
141
- @log_event_router = log_event_router
142
-
143
- unmatched_tags = Fluent::Log.event_tags.select{|t| !@log_event_router.match?(t) }
144
- unless unmatched_tags.empty?
145
- $log.warn "match for some tags of log events are not defined (to be ignored)", tags: unmatched_tags
146
- end
147
- rescue ArgumentError # ArgumentError "#{label_name} label not found"
148
- # use default event router if <label @FLUENT_LOG> is missing in configuration
149
- log_event_router = @root_agent.event_router
150
-
151
- if Fluent::Log.event_tags.any?{|t| log_event_router.match?(t) }
152
- @log_event_router = log_event_router
153
-
154
- unmatched_tags = Fluent::Log.event_tags.select{|t| !@log_event_router.match?(t) }
155
- unless unmatched_tags.empty?
156
- $log.warn "match for some tags of log events are not defined (to be ignored)", tags: unmatched_tags
157
- end
158
- end
108
+ if @fluent_log_event_router.emittable?
109
+ $log.enable_event(true)
159
110
  end
160
111
 
161
- $log.enable_event(true) if @log_event_router
162
-
163
112
  unless @suppress_config_dump
164
113
  $log.info :supervisor, "using configuration file: #{conf.to_s.rstrip}"
165
114
  end
166
115
  end
167
116
 
168
117
  def add_plugin_dir(dir)
118
+ $log.warn('Deprecated method: this method is going to be deleted. Use Fluent::Plugin.add_plugin_dir')
169
119
  Plugin.add_plugin_dir(dir)
170
120
  end
171
121
 
@@ -190,39 +140,12 @@ module Fluent
190
140
  Fluent::EventTime.now
191
141
  end
192
142
 
193
- def log_event_loop
194
- $log.disable_events(Thread.current)
195
-
196
- while sleep(LOG_EMIT_INTERVAL)
197
- break if @log_event_loop_stop
198
- break if @log_event_loop_graceful_stop && @log_event_queue.empty?
199
- next if @log_event_queue.empty?
200
-
201
- # NOTE: thead-safe of slice! depends on GVL
202
- events = @log_event_queue.slice!(0..-1)
203
- next if events.empty?
204
-
205
- events.each {|tag,time,record|
206
- begin
207
- @log_event_router.emit(tag, time, record)
208
- rescue => e
209
- # This $log.error doesn't emit log events, because of `$log.disable_events(Thread.current)` above
210
- $log.error "failed to emit fluentd's log event", tag: tag, event: record, error: e
211
- end
212
- }
213
- end
214
- end
215
-
216
143
  def run
217
144
  begin
218
145
  $log.info "starting fluentd worker", pid: Process.pid, ppid: Process.ppid, worker: worker_id
219
146
  start
220
147
 
221
- if @log_event_router
222
- $log.enable_event(true)
223
- @log_emit_thread = Thread.new(&method(:log_event_loop))
224
- @log_emit_thread.abort_on_exception = true
225
- end
148
+ @fluent_log_event_router.start
226
149
 
227
150
  $log.info "fluentd worker is now running", worker: worker_id
228
151
  sleep MAINLOOP_SLEEP_INTERVAL until @engine_stopped
@@ -236,19 +159,12 @@ module Fluent
236
159
 
237
160
  unless @log_event_verbose
238
161
  $log.enable_event(false)
239
- if @log_emit_thread
240
- # to make sure to emit all log events into router, before shutting down
241
- @log_event_loop_graceful_stop = true
242
- @log_emit_thread.join
243
- @log_emit_thread = nil
244
- end
162
+ @fluent_log_event_router.graceful_stop
245
163
  end
246
164
  $log.info "shutting down fluentd worker", worker: worker_id
247
165
  shutdown
248
- if @log_emit_thread
249
- @log_event_loop_stop = true
250
- @log_emit_thread.join
251
- end
166
+
167
+ @fluent_log_event_router.stop
252
168
  end
253
169
 
254
170
  def stop
@@ -257,11 +173,14 @@ module Fluent
257
173
  end
258
174
 
259
175
  def push_log_event(tag, time, record)
260
- return if @log_emit_thread.nil?
261
- @log_event_queue.push([tag, time, record])
176
+ @fluent_log_event_router.emit_event([tag, time, record])
262
177
  end
263
178
 
264
179
  def worker_id
180
+ if @supervisor_mode
181
+ return -1
182
+ end
183
+
265
184
  return @_worker_id if @_worker_id
266
185
  # if ENV doesn't have SERVERENGINE_WORKER_ID, it is a worker under --no-supervisor or in tests
267
186
  # so it's (almost) a single worker, worker_id=0