fluentd 1.18.0 → 1.19.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +116 -0
  3. data/CHANGELOG.md +235 -12
  4. data/MAINTAINERS.md +8 -2
  5. data/README.md +3 -7
  6. data/Rakefile +2 -0
  7. data/SECURITY.md +5 -3
  8. data/lib/fluent/command/cap_ctl.rb +2 -2
  9. data/lib/fluent/command/fluentd.rb +6 -2
  10. data/lib/fluent/compat/formatter.rb +6 -0
  11. data/lib/fluent/compat/socket_util.rb +2 -2
  12. data/lib/fluent/config/configure_proxy.rb +1 -1
  13. data/lib/fluent/config/element.rb +2 -2
  14. data/lib/fluent/config/literal_parser.rb +3 -3
  15. data/lib/fluent/config/parser.rb +15 -3
  16. data/lib/fluent/config/section.rb +2 -2
  17. data/lib/fluent/config/types.rb +1 -1
  18. data/lib/fluent/config/v1_parser.rb +3 -3
  19. data/lib/fluent/counter/store.rb +1 -1
  20. data/lib/fluent/engine.rb +1 -1
  21. data/lib/fluent/env.rb +3 -2
  22. data/lib/fluent/event.rb +7 -6
  23. data/lib/fluent/log/console_adapter.rb +5 -7
  24. data/lib/fluent/log.rb +23 -0
  25. data/lib/fluent/plugin/bare_output.rb +0 -16
  26. data/lib/fluent/plugin/base.rb +2 -2
  27. data/lib/fluent/plugin/buf_file.rb +15 -1
  28. data/lib/fluent/plugin/buf_file_single.rb +15 -1
  29. data/lib/fluent/plugin/buffer/chunk.rb +74 -10
  30. data/lib/fluent/plugin/buffer/file_chunk.rb +9 -5
  31. data/lib/fluent/plugin/buffer/file_single_chunk.rb +3 -3
  32. data/lib/fluent/plugin/buffer/memory_chunk.rb +2 -2
  33. data/lib/fluent/plugin/buffer.rb +34 -6
  34. data/lib/fluent/plugin/compressable.rb +68 -22
  35. data/lib/fluent/plugin/filter.rb +0 -8
  36. data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
  37. data/lib/fluent/plugin/formatter_csv.rb +18 -4
  38. data/lib/fluent/plugin/formatter_json.rb +7 -4
  39. data/lib/fluent/plugin/formatter_out_file.rb +5 -2
  40. data/lib/fluent/plugin/in_forward.rb +9 -5
  41. data/lib/fluent/plugin/in_http.rb +9 -4
  42. data/lib/fluent/plugin/in_monitor_agent.rb +4 -8
  43. data/lib/fluent/plugin/in_tail/position_file.rb +1 -1
  44. data/lib/fluent/plugin/in_tail.rb +80 -57
  45. data/lib/fluent/plugin/in_tcp.rb +2 -2
  46. data/lib/fluent/plugin/in_udp.rb +1 -1
  47. data/lib/fluent/plugin/input.rb +0 -8
  48. data/lib/fluent/plugin/multi_output.rb +1 -17
  49. data/lib/fluent/plugin/out_exec_filter.rb +2 -2
  50. data/lib/fluent/plugin/out_file.rb +37 -30
  51. data/lib/fluent/plugin/out_forward/connection_manager.rb +2 -2
  52. data/lib/fluent/plugin/out_forward.rb +23 -13
  53. data/lib/fluent/plugin/out_http.rb +1 -1
  54. data/lib/fluent/plugin/out_secondary_file.rb +2 -2
  55. data/lib/fluent/plugin/out_stdout.rb +10 -3
  56. data/lib/fluent/plugin/out_stream.rb +3 -3
  57. data/lib/fluent/plugin/output.rb +24 -35
  58. data/lib/fluent/plugin/owned_by_mixin.rb +2 -2
  59. data/lib/fluent/plugin/parser.rb +3 -3
  60. data/lib/fluent/plugin/parser_json.rb +3 -3
  61. data/lib/fluent/plugin/sd_file.rb +2 -2
  62. data/lib/fluent/plugin/storage_local.rb +8 -4
  63. data/lib/fluent/plugin.rb +1 -1
  64. data/lib/fluent/plugin_helper/child_process.rb +2 -2
  65. data/lib/fluent/plugin_helper/http_server/request.rb +13 -2
  66. data/lib/fluent/plugin_helper/http_server/server.rb +4 -14
  67. data/lib/fluent/plugin_helper/http_server.rb +1 -8
  68. data/lib/fluent/plugin_helper/metrics.rb +7 -0
  69. data/lib/fluent/plugin_helper/server.rb +4 -1
  70. data/lib/fluent/plugin_helper/service_discovery.rb +1 -1
  71. data/lib/fluent/plugin_helper/socket_option.rb +2 -2
  72. data/lib/fluent/plugin_helper/storage.rb +1 -1
  73. data/lib/fluent/plugin_id.rb +3 -3
  74. data/lib/fluent/root_agent.rb +4 -3
  75. data/lib/fluent/static_config_analysis.rb +3 -2
  76. data/lib/fluent/supervisor.rb +51 -5
  77. data/lib/fluent/system_config.rb +13 -4
  78. data/lib/fluent/test/base.rb +1 -1
  79. data/lib/fluent/test/driver/base.rb +2 -2
  80. data/lib/fluent/test/filter_test.rb +2 -2
  81. data/lib/fluent/test/formatter_test.rb +1 -1
  82. data/lib/fluent/test/helpers.rb +4 -0
  83. data/lib/fluent/test/input_test.rb +2 -2
  84. data/lib/fluent/test/output_test.rb +4 -4
  85. data/lib/fluent/test/parser_test.rb +1 -1
  86. data/lib/fluent/tls.rb +24 -0
  87. data/lib/fluent/variable_store.rb +1 -1
  88. data/lib/fluent/version.rb +1 -1
  89. data/lib/fluent/winsvc.rb +38 -8
  90. metadata +85 -16
  91. data/lib/fluent/plugin_helper/http_server/compat/server.rb +0 -92
  92. data/lib/fluent/plugin_helper/http_server/compat/ssl_context_extractor.rb +0 -52
  93. data/lib/fluent/plugin_helper/http_server/compat/webrick_handler.rb +0 -58
@@ -38,7 +38,7 @@ module Fluent
38
38
  end
39
39
 
40
40
  s = @_storages[usage]
41
- if s && s.running
41
+ if s&.running
42
42
  return s.storage
43
43
  elsif s
44
44
  # storage is already created, but not loaded / started
@@ -30,7 +30,7 @@ module Fluent
30
30
  end
31
31
 
32
32
  def configure(conf)
33
- @_plugin_id_variable_store = Fluent::VariableStore.fetch_or_build(:pluing_id, default_value: Set.new)
33
+ @_plugin_id_variable_store = Fluent::VariableStore.fetch_or_build(:plugin_id, default_value: Set.new)
34
34
  @id = conf['@id']
35
35
  @_id_configured = !!@id # plugin id is explicitly configured by users (or not)
36
36
  if @id
@@ -57,13 +57,13 @@ module Fluent
57
57
  end
58
58
 
59
59
  def plugin_id_configured?
60
- if instance_variable_defined?("@_id_configured")
60
+ if instance_variable_defined?(:@_id_configured)
61
61
  @_id_configured
62
62
  end
63
63
  end
64
64
 
65
65
  def plugin_id
66
- if instance_variable_defined?("@id")
66
+ if instance_variable_defined?(:@id)
67
67
  @id || "object:#{object_id.to_s(16)}"
68
68
  else
69
69
  "object:#{object_id.to_s(16)}"
@@ -86,7 +86,7 @@ module Fluent
86
86
  @without_source = system_config.without_source || false
87
87
  @source_only_mode = SourceOnlyMode.new(system_config.with_source_only, start_in_parallel)
88
88
  @source_only_buffer_agent = nil
89
- @enable_input_metrics = system_config.enable_input_metrics || false
89
+ @enable_input_metrics = system_config.enable_input_metrics
90
90
 
91
91
  suppress_interval(system_config.emit_error_log_interval) unless system_config.emit_error_log_interval.nil?
92
92
  end
@@ -103,6 +103,7 @@ module Fluent
103
103
  used_worker_ids = []
104
104
  available_worker_ids = (0..Fluent::Engine.system_config.workers - 1).to_a
105
105
  # initialize <worker> elements
106
+ supported_directives = ['source', 'match', 'filter', 'label']
106
107
  conf.elements(name: 'worker').each do |e|
107
108
  target_worker_id_str = e.arg
108
109
  if target_worker_id_str.empty?
@@ -131,7 +132,7 @@ module Fluent
131
132
  used_worker_ids << target_worker_id
132
133
 
133
134
  e.elements.each do |elem|
134
- unless ['source', 'match', 'filter', 'label'].include?(elem.name)
135
+ unless supported_directives.include?(elem.name)
135
136
  raise Fluent::ConfigError, "<worker> section cannot have <#{elem.name}> directive"
136
137
  end
137
138
  end
@@ -147,7 +148,7 @@ module Fluent
147
148
  end
148
149
 
149
150
  e.elements.each do |elem|
150
- unless ['source', 'match', 'filter', 'label'].include?(elem.name)
151
+ unless supported_directives.include?(elem.name)
151
152
  raise Fluent::ConfigError, "<worker> section cannot have <#{elem.name}> directive"
152
153
  end
153
154
  elem.set_target_worker_id(target_worker_id)
@@ -18,7 +18,7 @@ require 'fluent/config'
18
18
  require 'fluent/plugin'
19
19
 
20
20
  module Fluent
21
- # Static Analysis means analysing all plugins and Fluent::Element without invokeing Plugin#configure
21
+ # Static Analysis means analysing all plugins and Fluent::Element without invoking Plugin#configure
22
22
  class StaticConfigAnalysis
23
23
  module Elem
24
24
  Input = Struct.new(:plugin, :config)
@@ -72,6 +72,7 @@ module Fluent
72
72
  available_worker_ids = [*0...@workers]
73
73
 
74
74
  ret = []
75
+ supported_directives = %w[source match filter label]
75
76
  conf.elements(name: 'worker').each do |config|
76
77
  ids = parse_worker_id(config)
77
78
  ids.each do |id|
@@ -83,7 +84,7 @@ module Fluent
83
84
  end
84
85
 
85
86
  config.elements.each do |elem|
86
- unless %w[source match filter label].include?(elem.name)
87
+ unless supported_directives.include?(elem.name)
87
88
  raise Fluent::ConfigError, "<worker> section cannot have <#{elem.name}> directive"
88
89
  end
89
90
  end
@@ -17,6 +17,7 @@
17
17
  require 'fileutils'
18
18
  require 'open3'
19
19
  require 'pathname'
20
+ require 'find'
20
21
 
21
22
  require 'fluent/config'
22
23
  require 'fluent/counter'
@@ -587,7 +588,7 @@ module Fluent
587
588
  log_level: params['log_level'],
588
589
  chuser: params['chuser'],
589
590
  chgroup: params['chgroup'],
590
- chumask: params['chumask'],
591
+ chumask: params['chumask'].is_a?(Integer) ? params['chumask'] : params['chumask']&.to_i(8),
591
592
  daemonize: daemonize,
592
593
  rpc_endpoint: params['rpc_endpoint'],
593
594
  counter_server: params['counter_server'],
@@ -630,7 +631,7 @@ module Fluent
630
631
  ignore_repeated_log_interval: nil,
631
632
  without_source: nil,
632
633
  with_source_only: nil,
633
- enable_input_metrics: nil,
634
+ enable_input_metrics: true,
634
635
  enable_size_metrics: nil,
635
636
  use_v1_config: true,
636
637
  strict_config_value: nil,
@@ -721,6 +722,18 @@ module Fluent
721
722
  $log.error 'config error', file: @config_path, error: e
722
723
  $log.debug_backtrace
723
724
  exit!(1)
725
+ rescue ScriptError => e # LoadError, NotImplementedError, SyntaxError
726
+ if e.respond_to?(:path)
727
+ $log.error e.message, path: e.path, error: e
728
+ else
729
+ $log.error e.message, error: e
730
+ end
731
+ $log.debug_backtrace
732
+ exit!(1)
733
+ rescue => e
734
+ $log.error "unexpected error", error: e
735
+ $log.debug_backtrace
736
+ exit!(1)
724
737
  end
725
738
 
726
739
  if dry_run
@@ -754,7 +767,7 @@ module Fluent
754
767
 
755
768
  install_main_process_signal_handlers
756
769
 
757
- # This is the only log messsage for @standalone_worker
770
+ # This is the only log message for @standalone_worker
758
771
  $log.info "starting fluentd-#{Fluent::VERSION} without supervision", pid: Process.pid, ruby: RUBY_VERSION if @standalone_worker
759
772
 
760
773
  main_process do
@@ -794,6 +807,10 @@ module Fluent
794
807
 
795
808
  $log.info :supervisor, 'parsing config file is succeeded', path: @config_path
796
809
 
810
+ build_additional_configurations do |additional_conf|
811
+ @conf += additional_conf
812
+ end
813
+
797
814
  @libs.each do |lib|
798
815
  require lib
799
816
  end
@@ -891,11 +908,12 @@ module Fluent
891
908
  ignore_repeated_log_interval: system_config.ignore_repeated_log_interval,
892
909
  ignore_same_log_interval: system_config.ignore_same_log_interval,
893
910
  )
911
+ $log.force_stacktrace_level(system_config.log.forced_stacktrace_level) if system_config.force_stacktrace_level?
894
912
  $log.enable_color(false) if actual_log_path
895
913
  $log.enable_debug if system_config.log_level <= Fluent::Log::LEVEL_DEBUG
896
914
 
897
915
  $log.info "init #{process_type} logger",
898
- path: actual_log_path,
916
+ path: actual_log_path,
899
917
  rotate_age: @log_rotate_age,
900
918
  rotate_size: @log_rotate_size
901
919
  end
@@ -924,6 +942,7 @@ module Fluent
924
942
  'inline_config' => @inline_config,
925
943
  'chuser' => @chuser,
926
944
  'chgroup' => @chgroup,
945
+ 'chumask' => @chumask,
927
946
  'fluentd_conf_path' => @config_path,
928
947
  'fluentd_conf' => @conf.to_s,
929
948
  'use_v1_config' => @use_v1_config,
@@ -1077,6 +1096,10 @@ module Fluent
1077
1096
  type: @config_file_type,
1078
1097
  )
1079
1098
 
1099
+ build_additional_configurations do |additional_conf|
1100
+ conf += additional_conf
1101
+ end
1102
+
1080
1103
  Fluent::VariableStore.try_to_reset do
1081
1104
  Fluent::Engine.reload_config(conf)
1082
1105
  end
@@ -1168,7 +1191,7 @@ module Fluent
1168
1191
  def build_system_config(conf)
1169
1192
  system_config = SystemConfig.create(conf, @cl_opt[:strict_config_value])
1170
1193
  # Prefer the options explicitly specified in the command line
1171
- #
1194
+ #
1172
1195
  # TODO: There is a bug that `system_config.log.rotate_age/rotate_size` are
1173
1196
  # not merged with the command line options since they are not in
1174
1197
  # `SYSTEM_CONFIG_PARAMETERS`.
@@ -1183,6 +1206,29 @@ module Fluent
1183
1206
  system_config
1184
1207
  end
1185
1208
 
1209
+ def build_additional_configurations
1210
+ if @system_config.config_include_dir&.empty?
1211
+ $log.info :supervisor, 'configuration include directory is disabled'
1212
+ return
1213
+ end
1214
+ begin
1215
+ supported_suffixes = [".conf", ".yaml", ".yml"]
1216
+ Find.find(@system_config.config_include_dir) do |path|
1217
+ next if File.directory?(path)
1218
+ next unless supported_suffixes.include?(File.extname(path))
1219
+ # NOTE: both types of normal config (.conf) and YAML will be loaded.
1220
+ # Thus, it does not care whether @config_path is .conf or .yml.
1221
+ $log.info :supervisor, 'loading additional configuration file', path: path
1222
+ yield Fluent::Config.build(config_path: path,
1223
+ encoding: @conf_encoding,
1224
+ use_v1_config: @use_v1_config,
1225
+ type: :guess)
1226
+ end
1227
+ rescue Errno::ENOENT
1228
+ $log.info :supervisor, 'inaccessible include directory was specified', path: @system_config.config_include_dir
1229
+ end
1230
+ end
1231
+
1186
1232
  RUBY_ENCODING_OPTIONS_REGEX = %r{\A(-E|--encoding=|--internal-encoding=|--external-encoding=)}.freeze
1187
1233
 
1188
1234
  def build_spawn_command
@@ -16,6 +16,7 @@
16
16
 
17
17
  require 'fluent/configurable'
18
18
  require 'fluent/config/element'
19
+ require 'fluent/env'
19
20
 
20
21
  module Fluent
21
22
  class SystemConfig
@@ -28,7 +29,8 @@ module Fluent
28
29
  :without_source, :with_source_only, :rpc_endpoint, :enable_get_dump, :process_name,
29
30
  :file_permission, :dir_permission, :counter_server, :counter_client,
30
31
  :strict_config_value, :enable_msgpack_time_support, :disable_shared_socket,
31
- :metrics, :enable_input_metrics, :enable_size_metrics, :enable_jit, :source_only_buffer
32
+ :metrics, :enable_input_metrics, :enable_size_metrics, :enable_jit, :source_only_buffer,
33
+ :config_include_dir
32
34
  ]
33
35
 
34
36
  config_param :workers, :integer, default: 1
@@ -49,7 +51,7 @@ module Fluent
49
51
  config_param :strict_config_value, :bool, default: nil
50
52
  config_param :enable_msgpack_time_support, :bool, default: nil
51
53
  config_param :disable_shared_socket, :bool, default: nil
52
- config_param :enable_input_metrics, :bool, default: nil
54
+ config_param :enable_input_metrics, :bool, default: true
53
55
  config_param :enable_size_metrics, :bool, default: nil
54
56
  config_param :enable_jit, :bool, default: false
55
57
  config_param :file_permission, default: nil do |v|
@@ -58,6 +60,7 @@ module Fluent
58
60
  config_param :dir_permission, default: nil do |v|
59
61
  v.to_i(8)
60
62
  end
63
+ config_param :config_include_dir, default: Fluent::DEFAULT_CONFIG_INCLUDE_DIR
61
64
  config_section :log, required: false, init: true, multi: false do
62
65
  config_param :path, :string, default: nil
63
66
  config_param :format, :enum, list: [:text, :json], default: :text
@@ -76,6 +79,7 @@ module Fluent
76
79
  end
77
80
  end
78
81
  config_param :rotate_size, :size, default: nil
82
+ config_param :forced_stacktrace_level, :enum, list: [:none, :trace, :debug, :info, :warn, :error, :fatal], default: :none
79
83
  end
80
84
 
81
85
  config_section :counter_server, multi: false do
@@ -115,6 +119,10 @@ module Fluent
115
119
  config_param :compress, :enum, list: [:text, :gzip], default: nil
116
120
  end
117
121
 
122
+ def force_stacktrace_level?
123
+ @log.forced_stacktrace_level != :none
124
+ end
125
+
118
126
  def self.create(conf, strict_config_value=false)
119
127
  systems = conf.elements(name: 'system')
120
128
  return SystemConfig.new if systems.empty?
@@ -159,6 +167,7 @@ module Fluent
159
167
  end
160
168
 
161
169
  @log_level = Log.str_to_level(@log_level.to_s) if @log_level
170
+ @log[:forced_stacktrace_level] = Log.str_to_level(@log.forced_stacktrace_level.to_s) if force_stacktrace_level?
162
171
  end
163
172
 
164
173
  def dup
@@ -183,13 +192,13 @@ module Fluent
183
192
  unless defined?($_system_config)
184
193
  $_system_config = nil
185
194
  end
186
- (instance_variable_defined?("@_system_config") && @_system_config) ||
195
+ (instance_variable_defined?(:@_system_config) && @_system_config) ||
187
196
  $_system_config || Fluent::Engine.system_config
188
197
  end
189
198
 
190
199
  def system_config_override(opts={})
191
200
  require 'fluent/engine'
192
- if !instance_variable_defined?("@_system_config") || @_system_config.nil?
201
+ if !instance_variable_defined?(:@_system_config) || @_system_config.nil?
193
202
  @_system_config = (defined?($_system_config) && $_system_config ? $_system_config : Fluent::Engine.system_config).dup
194
203
  end
195
204
  opts.each_pair do |key, value|
@@ -32,7 +32,7 @@ module Fluent
32
32
  # klass.dup is worse because its ancestors does NOT include original class name
33
33
  klass_name = klass.name
34
34
  klass = Class.new(klass)
35
- klass.define_singleton_method("name") { klass_name }
35
+ klass.define_singleton_method(:name) { klass_name }
36
36
  klass.module_eval(&block)
37
37
  end
38
38
  @instance = klass.new
@@ -185,7 +185,7 @@ module Fluent
185
185
  end
186
186
  end
187
187
 
188
- def run_actual(timeout: DEFAULT_TIMEOUT, &block)
188
+ def run_actual(timeout: DEFAULT_TIMEOUT)
189
189
  if @instance.respond_to?(:_threads)
190
190
  sleep 0.1 until @instance._threads.values.all?(&:alive?)
191
191
  end
@@ -201,7 +201,7 @@ module Fluent
201
201
  return_value = nil
202
202
  begin
203
203
  Timeout.timeout(timeout * 2) do |sec|
204
- return_value = block.call if block_given?
204
+ return_value = yield if block_given?
205
205
  end
206
206
  rescue Timeout::Error
207
207
  raise TestTimedOut, "Test case timed out with hard limit."
@@ -59,9 +59,9 @@ module Fluent
59
59
  alias_method :emits, :filtered_as_array # emits is for consistent with other drivers
60
60
 
61
61
  # Almost filters don't use threads so default is 0. It reduces test time.
62
- def run(num_waits = 0, &block)
62
+ def run(num_waits = 0)
63
63
  super(num_waits) {
64
- block.call if block
64
+ yield if block_given?
65
65
 
66
66
  @events.each { |tag, es|
67
67
  processed = @instance.filter_stream(tag, es)
@@ -28,7 +28,7 @@ module Fluent
28
28
  # klass.dup is worse because its ancestors does NOT include original class name
29
29
  klass_name = klass_or_str.name
30
30
  klass_or_str = Class.new(klass_or_str)
31
- klass_or_str.define_singleton_method("name") { klass_name }
31
+ klass_or_str.define_singleton_method(:name) { klass_name }
32
32
  klass_or_str.module_eval(&block)
33
33
  end
34
34
  @instance = klass_or_str.new
@@ -50,6 +50,10 @@ EOT
50
50
  end
51
51
  end
52
52
 
53
+ def event_time_without_nsec(str=nil, format: nil)
54
+ Fluent::EventTime.new(event_time(str, format: format))
55
+ end
56
+
53
57
  def with_timezone(tz)
54
58
  oldtz, ENV['TZ'] = ENV['TZ'], tz
55
59
  yield
@@ -109,7 +109,7 @@ module Fluent
109
109
  end
110
110
  end
111
111
 
112
- def run(num_waits = 10, &block)
112
+ def run(num_waits = 10)
113
113
  m = method(:emit_stream)
114
114
  unless Engine.singleton_class.ancestors.include?(EmitStreamWrapper)
115
115
  Engine.singleton_class.prepend EmitStreamWrapper
@@ -121,7 +121,7 @@ module Fluent
121
121
  instance.router.emit_stream_callee = m
122
122
 
123
123
  super(num_waits) {
124
- block.call if block
124
+ yield if block_given?
125
125
 
126
126
  if @expected_emits_length || @expects || @run_post_conditions
127
127
  # counters for emits and emit_streams
@@ -71,10 +71,10 @@ module Fluent
71
71
  (@expected_buffer ||= '') << str
72
72
  end
73
73
 
74
- def run(num_waits = 10, &block)
74
+ def run(num_waits = 10)
75
75
  result = nil
76
76
  super(num_waits) {
77
- block.call if block
77
+ yield if block_given?
78
78
 
79
79
  es = ArrayEventStream.new(@entries)
80
80
  buffer = @instance.format_stream(@tag, es)
@@ -119,10 +119,10 @@ module Fluent
119
119
  (@expected_buffer ||= '') << str
120
120
  end
121
121
 
122
- def run(&block)
122
+ def run
123
123
  result = []
124
124
  super {
125
- block.call if block
125
+ yield if block_given?
126
126
 
127
127
  buffer = ''
128
128
  lines = {}
@@ -27,7 +27,7 @@ module Fluent
27
27
  # klass.dup is worse because its ancestors does NOT include original class name
28
28
  klass_name = klass_or_str.name
29
29
  klass_or_str = Class.new(klass_or_str)
30
- klass_or_str.define_singleton_method("name") { klass_name }
30
+ klass_or_str.define_singleton_method(:name) { klass_name }
31
31
  klass_or_str.module_eval(&block)
32
32
  end
33
33
  case klass_or_str.instance_method(:initialize).arity
data/lib/fluent/tls.rb CHANGED
@@ -76,6 +76,30 @@ module Fluent
76
76
  ctx
77
77
  end
78
78
  module_function :set_version_to_context
79
+
80
+ def set_version_to_options(opt, version, min_version, max_version)
81
+ if MIN_MAX_AVAILABLE
82
+ case
83
+ when min_version.nil? && max_version.nil?
84
+ min_version = METHODS_MAP[version] || version
85
+ max_version = METHODS_MAP[version] || version
86
+ when min_version.nil? && max_version
87
+ raise Fluent::ConfigError, "When you set max_version, must set min_version together"
88
+ when min_version && max_version.nil?
89
+ raise Fluent::ConfigError, "When you set min_version, must set max_version together"
90
+ else
91
+ min_version = METHODS_MAP[min_version] || min_version
92
+ max_version = METHODS_MAP[max_version] || max_version
93
+ end
94
+ opt[:min_version] = min_version
95
+ opt[:max_version] = max_version
96
+ else
97
+ opt[:ssl_version] = METHODS_MAP[version] || version
98
+ end
99
+
100
+ opt
101
+ end
102
+ module_function :set_version_to_options
79
103
  end
80
104
  end
81
105
 
@@ -15,7 +15,7 @@
15
15
  #
16
16
 
17
17
  module Fluent
18
- # VariableStore provides all pluigns with the way to shared variable without using class variable
18
+ # VariableStore provides all plugins with the way to shared variable without using class variable
19
19
  # it's for safe reloading mechanism
20
20
  class VariableStore
21
21
  @data = {}
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.18.0'
19
+ VERSION = '1.19.0'
20
20
 
21
21
  end
data/lib/fluent/winsvc.rb CHANGED
@@ -32,7 +32,7 @@ begin
32
32
  op.parse(ARGV)
33
33
  if opts[:service_name] == nil
34
34
  raise "Error: No Windows Service name set. Use '--service-name'"
35
- end
35
+ end
36
36
 
37
37
  def read_fluentdopt(service_name)
38
38
  Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services\\#{service_name}") do |reg|
@@ -48,25 +48,32 @@ begin
48
48
  end
49
49
 
50
50
  class FluentdService < Daemon
51
+ ERROR_WAIT_NO_CHILDREN = 128
52
+
51
53
  @pid = 0
52
54
  @service_name = ''
53
55
 
54
56
  def initialize(service_name)
55
57
  @service_name = service_name
56
58
  end
57
-
59
+
58
60
  def service_main
59
61
  @pid = service_main_start(@service_name)
60
- while running?
61
- sleep 10
62
+ begin
63
+ loop do
64
+ sleep 5
65
+ break unless running?
66
+ raise Errno::ECHILD if Process.waitpid(@pid, Process::WNOHANG)
67
+ end
68
+ rescue Errno::ECHILD
69
+ @pid = 0
70
+ SetEvent(@@hStopEvent)
71
+ SetTheServiceStatus.call(SERVICE_STOPPED, ERROR_WAIT_NO_CHILDREN, 0, 0)
62
72
  end
63
73
  end
64
74
 
65
75
  def service_stop
66
- set_event(@service_name)
67
- if @pid > 0
68
- Process.waitpid(@pid)
69
- end
76
+ wait_supervisor_finished if @pid > 0
70
77
  end
71
78
 
72
79
  def service_paramchange
@@ -91,6 +98,29 @@ begin
91
98
  ev.set
92
99
  ev.close
93
100
  end
101
+
102
+ def repeat_set_event_several_times_until_success(event_name)
103
+ retries = 0
104
+ max_retries = 10
105
+ delay_sec = 3
106
+
107
+ begin
108
+ set_event(event_name)
109
+ rescue Errno::ENOENT
110
+ # This error occurs when the supervisor process has not yet created the event.
111
+ # If STOP is immediately executed, this state will occur.
112
+ # Retry `set_event' to wait for the initialization of the supervisor.
113
+ retries += 1
114
+ raise if max_retries < retries
115
+ sleep(delay_sec)
116
+ retry
117
+ end
118
+ end
119
+
120
+ def wait_supervisor_finished
121
+ repeat_set_event_several_times_until_success(@service_name)
122
+ Process.waitpid(@pid)
123
+ end
94
124
  end
95
125
 
96
126
  FluentdService.new(opts[:service_name]).mainloop