fluentd 1.7.4 → 1.8.0.rc1

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/example/out_forward_sd.conf +17 -0
  4. data/example/sd.yaml +8 -0
  5. data/lib/fluent/command/cat.rb +1 -2
  6. data/lib/fluent/compat/call_super_mixin.rb +9 -0
  7. data/lib/fluent/compat/exec_util.rb +1 -1
  8. data/lib/fluent/counter/base_socket.rb +2 -4
  9. data/lib/fluent/engine.rb +1 -8
  10. data/lib/fluent/event.rb +5 -7
  11. data/lib/fluent/msgpack_factory.rb +19 -2
  12. data/lib/fluent/plugin.rb +10 -1
  13. data/lib/fluent/plugin/buf_file.rb +9 -1
  14. data/lib/fluent/plugin/buf_file_single.rb +6 -0
  15. data/lib/fluent/plugin/buffer/file_chunk.rb +2 -3
  16. data/lib/fluent/plugin/buffer/file_single_chunk.rb +1 -2
  17. data/lib/fluent/plugin/formatter_csv.rb +22 -0
  18. data/lib/fluent/plugin/in_forward.rb +1 -1
  19. data/lib/fluent/plugin/in_tail.rb +6 -0
  20. data/lib/fluent/plugin/in_unix.rb +1 -1
  21. data/lib/fluent/plugin/out_forward.rb +77 -28
  22. data/lib/fluent/plugin/out_forward/ack_handler.rb +1 -1
  23. data/lib/fluent/plugin/out_forward/load_balancer.rb +5 -2
  24. data/lib/fluent/plugin/out_stream.rb +1 -1
  25. data/lib/fluent/plugin/parser.rb +1 -0
  26. data/lib/fluent/plugin/sd_file.rb +155 -0
  27. data/lib/fluent/plugin/sd_static.rb +58 -0
  28. data/lib/fluent/plugin/service_discovery.rb +80 -0
  29. data/lib/fluent/plugin_helper.rb +1 -0
  30. data/lib/fluent/plugin_helper/record_accessor.rb +10 -19
  31. data/lib/fluent/plugin_helper/service_discovery.rb +80 -0
  32. data/lib/fluent/plugin_helper/service_discovery/manager.rb +132 -0
  33. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  34. data/lib/fluent/plugin_id.rb +7 -0
  35. data/lib/fluent/supervisor.rb +9 -8
  36. data/lib/fluent/system_config.rb +0 -2
  37. data/lib/fluent/version.rb +1 -1
  38. data/test/config/test_system_config.rb +0 -1
  39. data/test/plugin/data/sd_file/config +11 -0
  40. data/test/plugin/data/sd_file/config.json +17 -0
  41. data/test/plugin/data/sd_file/config.yaml +11 -0
  42. data/test/plugin/data/sd_file/config.yml +11 -0
  43. data/test/plugin/data/sd_file/invalid_config.yml +7 -0
  44. data/test/plugin/out_forward/test_handshake_protocol.rb +2 -2
  45. data/test/plugin/out_forward/test_socket_cache.rb +2 -2
  46. data/test/plugin/test_formatter_csv.rb +9 -0
  47. data/test/plugin/test_in_forward.rb +9 -9
  48. data/test/plugin/test_in_unix.rb +5 -5
  49. data/test/plugin/test_out_forward.rb +45 -1
  50. data/test/plugin/test_out_stream.rb +3 -3
  51. data/test/plugin/test_sd_file.rb +211 -0
  52. data/test/plugin_helper/service_discovery/test_manager.rb +93 -0
  53. data/test/plugin_helper/service_discovery/test_round_robin_balancer.rb +21 -0
  54. data/test/plugin_helper/test_service_discovery.rb +72 -0
  55. data/test/test_event.rb +15 -15
  56. metadata +29 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b09f1cbc0b3f4be0bc2dedfc142a1f6f0ed195df071ec809c019987de83c0993
4
- data.tar.gz: bfdc00fe223cbbef68da3472d1d99518c3a52562dc10e2f720912f93d40cd8d3
3
+ metadata.gz: 4c1ecaaf9a3cd9d2ff59843b0c6fa388aa9afe180684b0cc0e51045f2509d2a4
4
+ data.tar.gz: 7c5a881eb1ed5b87b9aa3e74deb792a3d1fc57e85a26b900a10c15a2966d6762
5
5
  SHA512:
6
- metadata.gz: 1ac20a296903da6869d0cd28baafa4ec2e4ac001b96820f03417f7ec2913a5bf52641db630f9814f02b10ddafa993c5157e461dffae09688fba9cdcd704922e4
7
- data.tar.gz: 4bc9cce3c2083b0de6d256cd6ffaa07c57e9390de886491d5f0cbb35b181b9af2b3c3a48ab619b6cecc4f9355a7fb0b71ae87f403db0a49ba13198149770f92b
6
+ metadata.gz: a21f1004723f63ae0ae306e36446ee3324f0d1dce404780bd42e71b7a935a357806482f94c8381ec8e3220aa9d27756b80aa8e05acf7d4a3e59b11dfcedf9387
7
+ data.tar.gz: d1789835f28d427233aa489032fd389ad890dea347a3fa4bae7ec4e21bb7341395fbabddcd9008ef3bcd6ea7343a6a1a68e20cdda93f3959554df0d09474fc19
@@ -1,3 +1,29 @@
1
+ # Unreleased
2
+
3
+ ### New feature
4
+
5
+ * Add service discovery plugin and `out_forward` use it
6
+ https://github.com/fluent/fluentd/pull/2541
7
+
8
+ ### Enhancement
9
+
10
+ * formatter_csv: Support nested fields
11
+ https://github.com/fluent/fluentd/pull/2643
12
+ * record_accessor helper: Make code simple and bit faster
13
+ https://github.com/fluent/fluentd/pull/2660
14
+ * clean up internal classes / code
15
+ https://github.com/fluent/fluentd/pull/2647
16
+ https://github.com/fluent/fluentd/pull/2648
17
+ https://github.com/fluent/fluentd/pull/2653
18
+ https://github.com/fluent/fluentd/pull/2654
19
+ https://github.com/fluent/fluentd/pull/2657
20
+
21
+ ### Bug fixes
22
+
23
+ * suppress warning
24
+ https://github.com/fluent/fluentd/pull/2652
25
+
26
+
1
27
  # v1.7
2
28
 
3
29
  ## Release v1.7.4 - 2019/10/24
@@ -0,0 +1,17 @@
1
+ <source>
2
+ @type dummy
3
+ tag test
4
+ </source>
5
+
6
+ <match test>
7
+ @type forward
8
+
9
+ <service_discovery>
10
+ @type file
11
+ path "#{Dir.pwd}/example/sd.yaml"
12
+ </service_discovery>
13
+
14
+ <buffer>
15
+ flush_interval 1
16
+ </buffer>
17
+ </match>
@@ -0,0 +1,8 @@
1
+ - 'host': 127.0.0.1
2
+ 'port': 24224
3
+ 'weight': 1
4
+ 'name': server1
5
+ - 'host': 127.0.0.1
6
+ 'port': 24225
7
+ 'weight': 1
8
+ 'name': server2
@@ -315,7 +315,7 @@ when 'msgpack'
315
315
  require 'fluent/engine'
316
316
 
317
317
  begin
318
- u = Fluent::Engine.msgpack_factory.unpacker($stdin)
318
+ u = Fluent::MessagePackFactory.msgpack_unpacker($stdin)
319
319
  u.each {|record|
320
320
  w.write(record)
321
321
  }
@@ -340,4 +340,3 @@ else
340
340
  $stderr.puts "Unknown format '#{format}'"
341
341
  exit 1
342
342
  end
343
-
@@ -55,6 +55,15 @@ module Fluent
55
55
  end
56
56
  end
57
57
 
58
+ def stop
59
+ klass = self.class
60
+ @@_super_start.delete(klass)
61
+ @@_super_before_shutdown.delete(klass)
62
+ @@_super_shutdown.delete(klass)
63
+
64
+ super
65
+ end
66
+
58
67
  def shutdown
59
68
  super
60
69
  unless self.shutdown?
@@ -85,7 +85,7 @@ module Fluent
85
85
 
86
86
  class MessagePackParser < Parser
87
87
  def call(io)
88
- @u = Fluent::Engine.msgpack_factory.unpacker(io)
88
+ @u = Fluent::MessagePackFactory.msgpack_unpacker(io)
89
89
  begin
90
90
  @u.each(&@on_message)
91
91
  rescue EOFError
@@ -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
@@ -25,6 +25,7 @@ require 'fluent/plugin'
25
25
 
26
26
  module Fluent
27
27
  class EngineClass
28
+ # For compat. remove it in fluentd v2
28
29
  include Fluent::MessagePackFactory::Mixin
29
30
 
30
31
  def initialize
@@ -61,7 +62,6 @@ module Fluent
61
62
  def init(system_config)
62
63
  @system_config = system_config
63
64
 
64
- suppress_interval(system_config.emit_error_log_interval) unless system_config.emit_error_log_interval.nil?
65
65
  @suppress_config_dump = system_config.suppress_config_dump unless system_config.suppress_config_dump.nil?
66
66
  @without_source = system_config.without_source unless system_config.without_source.nil?
67
67
 
@@ -69,8 +69,6 @@ module Fluent
69
69
 
70
70
  @root_agent = RootAgent.new(log: log, system_config: @system_config)
71
71
 
72
- MessagePackFactory.init
73
-
74
72
  self
75
73
  end
76
74
 
@@ -78,11 +76,6 @@ module Fluent
78
76
  $log
79
77
  end
80
78
 
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
79
  def parse_config(io, fname, basepath = Dir.pwd, v1_config = false)
87
80
  if fname =~ /\.rb$/
88
81
  require 'fluent/config/dsl'
@@ -20,7 +20,6 @@ require 'fluent/plugin/compressable'
20
20
  module Fluent
21
21
  class EventStream
22
22
  include Enumerable
23
- include MessagePackFactory::Mixin
24
23
  include Fluent::Plugin::Compressable
25
24
 
26
25
  # dup does deep copy for event stream
@@ -56,7 +55,7 @@ module Fluent
56
55
 
57
56
  def to_msgpack_stream(time_int: false, packer: nil)
58
57
  return to_msgpack_stream_forced_integer(packer: packer) if time_int
59
- out = packer || msgpack_packer
58
+ out = packer || Fluent::MessagePackFactory.msgpack_packer
60
59
  each {|time,record|
61
60
  out.write([time,record])
62
61
  }
@@ -69,7 +68,7 @@ module Fluent
69
68
  end
70
69
 
71
70
  def to_msgpack_stream_forced_integer(packer: nil)
72
- out = packer || msgpack_packer
71
+ out = packer || Fluent::MessagePackFactory.msgpack_packer
73
72
  each {|time,record|
74
73
  out.write([time.to_i,record])
75
74
  }
@@ -238,7 +237,7 @@ module Fluent
238
237
  return if @unpacked_times && @unpacked_records
239
238
  @unpacked_times = []
240
239
  @unpacked_records = []
241
- (unpacker || msgpack_unpacker).feed_each(@data) do |time, record|
240
+ (unpacker || Fluent::MessagePackFactory.msgpack_unpacker).feed_each(@data) do |time, record|
242
241
  @unpacked_times << time
243
242
  @unpacked_records << record
244
243
  end
@@ -262,7 +261,7 @@ module Fluent
262
261
  else
263
262
  @unpacked_times = []
264
263
  @unpacked_records = []
265
- (unpacker || msgpack_unpacker).feed_each(@data) do |time, record|
264
+ (unpacker || Fluent::MessagePackFactory.msgpack_unpacker).feed_each(@data) do |time, record|
266
265
  @unpacked_times << time
267
266
  @unpacked_records << record
268
267
  block.call(time, record)
@@ -319,12 +318,11 @@ module Fluent
319
318
  end
320
319
 
321
320
  module ChunkMessagePackEventStreamer
322
- include MessagePackFactory::Mixin
323
321
  # chunk.extend(ChunkEventStreamer)
324
322
  # => chunk.each{|time, record| ... }
325
323
  def each(unpacker: nil, &block)
326
324
  open do |io|
327
- (unpacker || msgpack_unpacker(io)).each(&block)
325
+ (unpacker || Fluent::MessagePackFactory.msgpack_unpacker(io)).each(&block)
328
326
  end
329
327
  nil
330
328
  end
@@ -23,15 +23,24 @@ module Fluent
23
23
 
24
24
  module Mixin
25
25
  def msgpack_factory
26
+ if $log
27
+ $log.warn('Deprecated method: this method is going to be deleted. Use Fluent::MessagePackFactory.engine_factory')
28
+ end
26
29
  MessagePackFactory.engine_factory
27
30
  end
28
31
 
29
32
  def msgpack_packer(*args)
30
- msgpack_factory.packer(*args)
33
+ if $log
34
+ $log.warn('Deprecated method: this method is going to be deleted. Use Fluent::MessagePackFactory.msgpack_packer')
35
+ end
36
+ MessagePackFactory.msgpack_packer(*args)
31
37
  end
32
38
 
33
39
  def msgpack_unpacker(*args)
34
- msgpack_factory.unpacker(*args)
40
+ if $log
41
+ $log.warn('Deprecated method: this method is going to be deleted. Use Fluent::MessagePackFactory.msgpack_unpacker')
42
+ end
43
+ MessagePackFactory.msgpack_unpacker(*args)
35
44
  end
36
45
  end
37
46
 
@@ -39,6 +48,14 @@ module Fluent
39
48
  @@engine_factory || factory
40
49
  end
41
50
 
51
+ def self.msgpack_packer(*args)
52
+ engine_factory.packer(*args)
53
+ end
54
+
55
+ def self.msgpack_unpacker(*args)
56
+ engine_factory.unpacker(*args)
57
+ end
58
+
42
59
  def self.factory
43
60
  factory = MessagePack::Factory.new
44
61
  factory.register_type(Fluent::EventTime::TYPE, Fluent::EventTime)
@@ -35,8 +35,9 @@ module Fluent
35
35
  PARSER_REGISTRY = Registry.new(:parser, 'fluent/plugin/parser_', dir_search_prefix: 'parser_')
36
36
  FORMATTER_REGISTRY = Registry.new(:formatter, 'fluent/plugin/formatter_', dir_search_prefix: 'formatter_')
37
37
  STORAGE_REGISTRY = Registry.new(:storage, 'fluent/plugin/storage_', dir_search_prefix: 'storage_')
38
+ SD_REGISTRY = Registry.new(:sd, 'fluent/plugin/sd_', dir_search_prefix: 'sd_')
38
39
 
39
- REGISTRIES = [INPUT_REGISTRY, OUTPUT_REGISTRY, FILTER_REGISTRY, BUFFER_REGISTRY, PARSER_REGISTRY, FORMATTER_REGISTRY, STORAGE_REGISTRY]
40
+ REGISTRIES = [INPUT_REGISTRY, OUTPUT_REGISTRY, FILTER_REGISTRY, BUFFER_REGISTRY, PARSER_REGISTRY, FORMATTER_REGISTRY, STORAGE_REGISTRY, SD_REGISTRY]
40
41
 
41
42
  def self.register_input(type, klass)
42
43
  register_impl('input', INPUT_REGISTRY, type, klass)
@@ -54,6 +55,10 @@ module Fluent
54
55
  register_impl('buffer', BUFFER_REGISTRY, type, klass)
55
56
  end
56
57
 
58
+ def self.register_sd(type, klass)
59
+ register_impl('sd', SD_REGISTRY, type, klass)
60
+ end
61
+
57
62
  def self.register_parser(type, klass_or_proc)
58
63
  if klass_or_proc.is_a?(Regexp)
59
64
  # This usage is not recommended for new API
@@ -112,6 +117,10 @@ module Fluent
112
117
  new_impl('buffer', BUFFER_REGISTRY, type, parent)
113
118
  end
114
119
 
120
+ def self.new_sd(type, parent: nil)
121
+ new_impl('sd', SD_REGISTRY, type, parent)
122
+ end
123
+
115
124
  def self.new_parser(type, parent: nil)
116
125
  if type[0] == '/' && type[-1] == '/'
117
126
  # This usage is not recommended for new API... create RegexpParser directly
@@ -50,6 +50,7 @@ module Fluent
50
50
  @symlink_path = nil
51
51
  @multi_workers_available = false
52
52
  @additional_resume_path = nil
53
+ @buffer_path = nil
53
54
  end
54
55
 
55
56
  def configure(conf)
@@ -73,7 +74,8 @@ module Fluent
73
74
  raise ConfigError, "Other '#{type_using_this_path}' plugin already use same buffer path: type = #{type_of_owner}, buffer path = #{@path}"
74
75
  end
75
76
 
76
- @@buffer_paths[@path] = type_of_owner
77
+ @buffer_path = @path
78
+ @@buffer_paths[@buffer_path] = type_of_owner
77
79
 
78
80
  specified_directory_exists = File.exist?(@path) && File.directory?(@path)
79
81
  unexisting_path_for_directory = !File.exist?(@path) && !@path.include?('.*')
@@ -122,6 +124,12 @@ module Fluent
122
124
  super
123
125
  end
124
126
 
127
+ def stop
128
+ @@buffer_paths.delete(@buffer_path)
129
+
130
+ super
131
+ end
132
+
125
133
  def persistent?
126
134
  true
127
135
  end
@@ -144,6 +144,12 @@ module Fluent
144
144
  super
145
145
  end
146
146
 
147
+ def stop
148
+ @@buffer_paths.delete(@path)
149
+
150
+ super
151
+ end
152
+
147
153
  def persistent?
148
154
  true
149
155
  end
@@ -38,7 +38,6 @@ module Fluent
38
38
  # path_suffix: path suffix string, like '.log' (or any other user specified)
39
39
 
40
40
  include SystemConfig::Mixin
41
- include MessagePackFactory::Mixin
42
41
 
43
42
  FILE_PERMISSION = 0644
44
43
 
@@ -221,7 +220,7 @@ module Fluent
221
220
 
222
221
  unless data
223
222
  # old type of restore
224
- data = msgpack_unpacker(symbolize_keys: true).feed(bindata).read rescue {}
223
+ data = Fluent::MessagePackFactory.msgpack_unpacker(symbolize_keys: true).feed(bindata).read rescue {}
225
224
  end
226
225
 
227
226
  now = Fluent::Clock.real_now
@@ -403,7 +402,7 @@ module Fluent
403
402
  if chunk.slice(0, 2) == BUFFER_HEADER
404
403
  size = chunk.slice(2, 4).unpack('N').first
405
404
  if size
406
- return msgpack_unpacker(symbolize_keys: true).feed(chunk.slice(6, size)).read rescue nil
405
+ return Fluent::MessagePackFactory.msgpack_unpacker(symbolize_keys: true).feed(chunk.slice(6, size)).read rescue nil
407
406
  end
408
407
  end
409
408
 
@@ -30,7 +30,6 @@ module Fluent
30
30
  ## state: b/q - 'b'(on stage), 'q'(enqueued)
31
31
 
32
32
  include SystemConfig::Mixin
33
- include MessagePackFactory::Mixin
34
33
 
35
34
  PATH_EXT = 'buf'
36
35
  PATH_SUFFIX = ".#{PATH_EXT}"
@@ -216,7 +215,7 @@ module Fluent
216
215
  count = 0
217
216
  File.open(@path, 'rb') { |f|
218
217
  if chunk_format == :msgpack
219
- msgpack_unpacker(f).each { |d| count += 1 }
218
+ Fluent::MessagePackFactory.msgpack_unpacker(f).each { |d| count += 1 }
220
219
  else
221
220
  f.each_line { |l| count += 1 }
222
221
  end
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fluent/plugin_helper'
17
18
  require 'fluent/plugin/formatter'
18
19
  require 'csv'
19
20
 
@@ -22,6 +23,9 @@ module Fluent
22
23
  class CsvFormatter < Formatter
23
24
  Plugin.register_formatter('csv', self)
24
25
 
26
+ include PluginHelper::Mixin
27
+ helpers :record_accessor
28
+
25
29
  config_param :delimiter, default: ',' do |val|
26
30
  ['\t', 'TAB'].include?(val) ? "\t" : val
27
31
  end
@@ -37,6 +41,14 @@ module Fluent
37
41
  @fields = fields.select{|f| !f.empty? }
38
42
  raise ConfigError, "empty value is specified in fields parameter" if @fields.empty?
39
43
 
44
+ if @fields.any? { |f| record_accessor_nested?(f) }
45
+ @accessors = @fields.map { |f| record_accessor_create(f) }
46
+ mformat = method(:format_with_nested_fields)
47
+ singleton_class.module_eval do
48
+ define_method(:format, mformat)
49
+ end
50
+ end
51
+
40
52
  @generate_opts = {col_sep: @delimiter, force_quotes: @force_quotes, headers: @fields,
41
53
  row_sep: @add_newline ? :auto : "".force_encoding(Encoding::ASCII_8BIT)}
42
54
  # Cache CSV object per thread to avoid internal state sharing
@@ -51,6 +63,16 @@ module Fluent
51
63
  csv.truncate(0)
52
64
  line
53
65
  end
66
+
67
+ def format_with_nested_fields(tag, time, record)
68
+ csv = (@cache[Thread.current] ||= CSV.new("".force_encoding(Encoding::ASCII_8BIT), @generate_opts))
69
+ values = @accessors.map { |a| a.call(record) }
70
+ line = (csv << values).string.dup
71
+ # Need manual cleanup because CSV writer doesn't provide such method.
72
+ csv.rewind
73
+ csv.truncate(0)
74
+ line
75
+ end
54
76
  end
55
77
  end
56
78
  end
@@ -256,7 +256,7 @@ module Fluent::Plugin
256
256
  serializer = :to_json.to_proc
257
257
  feeder = ->(d){ parser << d }
258
258
  else # msgpack
259
- parser = Fluent::Engine.msgpack_factory.unpacker
259
+ parser = Fluent::MessagePackFactory.msgpack_unpacker
260
260
  serializer = :to_msgpack.to_proc
261
261
  feeder = ->(d){
262
262
  parser.feed_each(d){|obj|