fluentd 1.5.0.rc1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7ba10a2d9e94456e95d304989cd7487771c3dc71
4
- data.tar.gz: ce09baf07ad2c3af4fdea5665c6c57a4387e433a
2
+ SHA256:
3
+ metadata.gz: 3e334a69c853a549b872123dd1b6232f04dfba60aea75c197b51940ad051e422
4
+ data.tar.gz: af6be10d887398a5a8efb08915cd5fec348da6fffde98199df39f7e9a9f6e803
5
5
  SHA512:
6
- metadata.gz: '084c5d106ce8f806f3d52798a7a45498155d5a78c87eefcb6ee0163a79d4cccab42dac9c4e86c90ba644975f06ca0359fc5afa8f65c273f00841312491f7efee'
7
- data.tar.gz: 166d9c9a41e3e6b9ae6b3881655be16348ab8d562e4890fe0d27202431a94f2fd37f203b928915b4272dc9da975c2932bb2c449fca69553227eec6f8d18df5db
6
+ metadata.gz: 6aec4c3726486c0fe5fd9734a33e3813f222578211bf1e71ffa102aebcc14af4ed3a99b789a12f4f38e9a3d95379c90363e8921c9557be03bda756cbfafb76c3
7
+ data.tar.gz: b161392482f816ad8cc4eaa45a55529ec13107ed8a1020a4e7ef45a18f2949580eab5cf833c1e4462e98118d7fd1f0a41e20537c9a2c57b55f423bb4857fd147
@@ -23,6 +23,8 @@ matrix:
23
23
  os: linux
24
24
  - rvm: ruby-head
25
25
  os: linux
26
+ - rvm: ruby-head
27
+ os: linux-ppc64le
26
28
  - rvm: 2.1.10
27
29
  os: osx
28
30
  osx_image: xcode8.3 # OSX 10.12
@@ -1,11 +1,15 @@
1
1
  # v1.5
2
2
 
3
- ## Pre release
3
+ ## Release v1.5.0 - 2019/05/18
4
4
 
5
5
  ### New feature
6
6
 
7
7
  * out_forward: Support keepalive feature
8
8
  https://github.com/fluent/fluentd/pull/2393
9
+ * in_http: Support TLS via server helper
10
+ https://github.com/fluent/fluentd/pull/2395
11
+ * in_syslog: Support TLS via server helper
12
+ https://github.com/fluent/fluentd/pull/2399
9
13
 
10
14
  ### Enhancement
11
15
 
@@ -17,11 +21,17 @@
17
21
  https://github.com/fluent/fluentd/pull/2381
18
22
  * command: Add deprecated message to show-plugin-config option
19
23
  https://github.com/fluent/fluentd/pull/2401
24
+ * storage_local: Ignore empty file. Call sync after write for XFS.
25
+ https://github.com/fluent/fluentd/pull/2409
20
26
 
21
27
  ### Bug fixes
22
28
 
23
29
  * out_forward: Don't use SO_LINGER on SSL/TLS WinSock
24
30
  https://github.com/fluent/fluentd/pull/2398
31
+ * server helper: Fix recursive lock issue in TLSServer
32
+ https://github.com/fluent/fluentd/pull/2341
33
+ * Fix typo
34
+ https://github.com/fluent/fluentd/pull/2369
25
35
 
26
36
  # v1.4
27
37
 
@@ -148,7 +148,7 @@ module Fluent
148
148
  def on_message(msg, addr)
149
149
  @parser.parse(msg) { |time, record|
150
150
  unless time && record
151
- log.warn "pattern not match: #{msg.inspect}"
151
+ log.warn "pattern not matched: #{msg.inspect}"
152
152
  return
153
153
  end
154
154
 
@@ -82,7 +82,7 @@ module Fluent::Plugin
82
82
  return t, r
83
83
  else
84
84
  if @emit_invalid_record_to_error
85
- router.emit_error_event(tag, time, record, Fluent::Plugin::Parser::ParserError.new("pattern not match with data '#{raw_value}'"))
85
+ router.emit_error_event(tag, time, record, Fluent::Plugin::Parser::ParserError.new("pattern not matched with data '#{raw_value}'"))
86
86
  end
87
87
  if @reserve_data
88
88
  t = time
@@ -36,9 +36,7 @@ module Fluent::Plugin
36
36
  class HttpInput < Input
37
37
  Fluent::Plugin.register_input('http', self)
38
38
 
39
- # TODO: update this plugin implementation to use server plugin helper, after adding keepalive feature on it
40
-
41
- helpers :parser, :compat_parameters, :event_loop
39
+ helpers :parser, :compat_parameters, :event_loop, :server
42
40
 
43
41
  EMPTY_GIF_IMAGE = "GIF89a\u0001\u0000\u0001\u0000\x80\xFF\u0000\xFF\xFF\xFF\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;".force_encoding("UTF-8")
44
42
 
@@ -130,28 +128,15 @@ module Fluent::Plugin
130
128
 
131
129
  log.debug "listening http", bind: @bind, port: @port
132
130
 
133
- socket_manager_path = ENV['SERVERENGINE_SOCKETMANAGER_PATH']
134
- if Fluent.windows?
135
- socket_manager_path = socket_manager_path.to_i
136
- end
137
- client = ServerEngine::SocketManager::Client.new(socket_manager_path)
138
- lsock = client.listen_tcp(@bind, @port)
139
-
140
131
  @km = KeepaliveManager.new(@keepalive_timeout)
141
- @lsock = Coolio::TCPServer.new(
142
- lsock, nil, Handler, @km, method(:on_request),
143
- @body_size_limit, @format_name, log,
144
- @cors_allow_origins
145
- )
146
- @lsock.listen(@backlog) unless @backlog.nil?
147
132
  event_loop_attach(@km)
148
- event_loop_attach(@lsock)
149
133
 
134
+ server_create_connection(:in_http, @port, bind: @bind, backlog: @backlog, &method(:on_server_connect))
150
135
  @float_time_parser = Fluent::NumericTimeParser.new(:float)
151
136
  end
152
137
 
153
138
  def close
154
- @lsock.close
139
+ server_wait_until_stop
155
140
  super
156
141
  end
157
142
 
@@ -240,6 +225,22 @@ module Fluent::Plugin
240
225
 
241
226
  private
242
227
 
228
+ def on_server_connect(conn)
229
+ handler = Handler.new(conn, @km, method(:on_request), @body_size_limit, @format_name, log, @cors_allow_origins)
230
+
231
+ conn.on(:data) do |data|
232
+ handler.on_read(data)
233
+ end
234
+
235
+ conn.on(:write_complete) do |_|
236
+ handler.on_write_complete
237
+ end
238
+
239
+ conn.on(:close) do |_|
240
+ handler.on_close
241
+ end
242
+ end
243
+
243
244
  def parse_params_default(params)
244
245
  if msgpack = params['msgpack']
245
246
  @parser_msgpack.parse(msgpack) do |_time, record|
@@ -265,11 +266,11 @@ module Fluent::Plugin
265
266
  end
266
267
  end
267
268
 
268
- class Handler < Coolio::Socket
269
+ class Handler
269
270
  attr_reader :content_type
270
271
 
271
272
  def initialize(io, km, callback, body_size_limit, format_name, log, cors_allow_origins)
272
- super(io)
273
+ @io = io
273
274
  @km = km
274
275
  @callback = callback
275
276
  @body_size_limit = body_size_limit
@@ -280,7 +281,8 @@ module Fluent::Plugin
280
281
  @idle = 0
281
282
  @km.add(self)
282
283
 
283
- @remote_port, @remote_addr = *Socket.unpack_sockaddr_in(io.getpeername) rescue nil
284
+ @remote_port, @remote_addr = io.remote_port, io.remote_addr
285
+ @parser = Http::Parser.new(self)
284
286
  end
285
287
 
286
288
  def step_idle
@@ -291,17 +293,13 @@ module Fluent::Plugin
291
293
  @km.delete(self)
292
294
  end
293
295
 
294
- def on_connect
295
- @parser = Http::Parser.new(self)
296
- end
297
-
298
296
  def on_read(data)
299
297
  @idle = 0
300
298
  @parser << data
301
299
  rescue
302
300
  @log.warn "unexpected error", error: $!.to_s
303
301
  @log.warn_backtrace
304
- close
302
+ @io.close
305
303
  end
306
304
 
307
305
  def on_message_begin
@@ -477,8 +475,12 @@ module Fluent::Plugin
477
475
  end
478
476
  end
479
477
 
478
+ def close
479
+ @io.close
480
+ end
481
+
480
482
  def on_write_complete
481
- close if @next_close
483
+ @io.close if @next_close
482
484
  end
483
485
 
484
486
  def send_response_and_close(code, header, body)
@@ -499,9 +501,9 @@ module Fluent::Plugin
499
501
  data << "#{k}: #{v}\r\n"
500
502
  }
501
503
  data << "\r\n"
502
- write data
504
+ @io.write(data)
503
505
 
504
- write body
506
+ @io.write(body)
505
507
  end
506
508
 
507
509
  def send_response_nobody(code, header)
@@ -510,7 +512,7 @@ module Fluent::Plugin
510
512
  data << "#{k}: #{v}\r\n"
511
513
  }
512
514
  data << "\r\n"
513
- write data
515
+ @io.write(data)
514
516
  end
515
517
 
516
518
  def include_cors_allow_origin
@@ -74,7 +74,7 @@ module Fluent::Plugin
74
74
  desc 'The prefix of the tag. The tag itself is generated by the tag prefix, facility level, and priority.'
75
75
  config_param :tag, :string
76
76
  desc 'The transport protocol used to receive logs.(udp, tcp)'
77
- config_param :protocol_type, :enum, list: [:tcp, :udp], default: :udp
77
+ config_param :protocol_type, :enum, list: [:tcp, :udp], default: nil, deprecated: "use transport directive"
78
78
  desc 'The message frame type.(traditional, octet_count)'
79
79
  config_param :frame_type, :enum, list: [:traditional, :octet_count], default: :traditional
80
80
 
@@ -107,6 +107,11 @@ module Fluent::Plugin
107
107
  config_param :with_priority, :bool, default: true
108
108
  end
109
109
 
110
+ # overwrite server plugin to change default to :udp
111
+ config_section :transport, required: false, multi: false, init: true, param_name: :transport_config do
112
+ config_argument :protocol, :enum, list: [:tcp, :udp, :tls], default: :udp
113
+ end
114
+
110
115
  def configure(conf)
111
116
  compat_parameters_convert(conf, :parser)
112
117
 
@@ -141,12 +146,13 @@ module Fluent::Plugin
141
146
  def start
142
147
  super
143
148
 
144
- log.info "listening syslog socket on #{@bind}:#{@port} with #{@protocol_type}"
145
- case @protocol_type
149
+ log.info "listening syslog socket on #{@bind}:#{@port} with #{@protocol_type || @transport_config.protocol}"
150
+ case @protocol_type || @transport_config.protocol
146
151
  when :udp then start_udp_server
147
152
  when :tcp then start_tcp_server
153
+ when :tls then start_tcp_server(tls: true)
148
154
  else
149
- raise "BUG: invalid protocol_type value:#{@protocol_type}"
155
+ raise "BUG: invalid transport value: #{@protocol_type || @transport_config.protocol}"
150
156
  end
151
157
  end
152
158
 
@@ -156,12 +162,12 @@ module Fluent::Plugin
156
162
  end
157
163
  end
158
164
 
159
- def start_tcp_server
165
+ def start_tcp_server(tls: false)
160
166
  octet_count_frame = @frame_type == :octet_count
161
167
 
162
168
  delimiter = octet_count_frame ? " " : @delimiter
163
169
  delimiter_size = delimiter.size
164
- server_create_connection(:in_syslog_tcp_server, @port, bind: @bind, resolve_name: @resolve_hostname) do |conn|
170
+ server_create_connection(tls ? :in_syslog_tls_server : :in_syslog_tcp_server, @port, bind: @bind, resolve_name: @resolve_hostname) do |conn|
165
171
  conn.data do |data|
166
172
  buffer = conn.buffer
167
173
  buffer << data
@@ -427,7 +427,7 @@ module Fluent::Plugin
427
427
  record[@path_key] ||= tail_watcher.path unless @path_key.nil?
428
428
  es.add(Fluent::EventTime.now, record)
429
429
  end
430
- log.warn "pattern not match: #{line.inspect}"
430
+ log.warn "pattern not matched: #{line.inspect}"
431
431
  end
432
432
  }
433
433
  rescue => e
@@ -71,7 +71,7 @@ module Fluent::Plugin
71
71
 
72
72
  @parser.parse(msg) do |time, record|
73
73
  unless time && record
74
- log.warn "pattern not match", message: msg
74
+ log.warn "pattern not matched", message: msg
75
75
  next
76
76
  end
77
77
 
@@ -74,7 +74,7 @@ module Fluent::Plugin
74
74
  begin
75
75
  @parser.parse(data) do |time, record|
76
76
  unless time && record
77
- log.warn "pattern not match", data: data
77
+ log.warn "pattern not matched", data: data
78
78
  next
79
79
  end
80
80
 
@@ -87,7 +87,12 @@ module Fluent
87
87
  if File.exist?(@path)
88
88
  raise Fluent::ConfigError, "Plugin storage path '#{@path}' is not readable/writable" unless File.readable?(@path) && File.writable?(@path)
89
89
  begin
90
- data = Yajl::Parser.parse(open(@path, 'r:utf-8'){ |io| io.read })
90
+ data = open(@path, 'r:utf-8') { |io| io.read }
91
+ if data.empty?
92
+ log.warn "detect empty plugin storage file during startup. Ignored: #{@path}"
93
+ return
94
+ end
95
+ data = Yajl::Parser.parse(data)
91
96
  raise Fluent::ConfigError, "Invalid contents (not object) in plugin storage file: '#{@path}'" unless data.is_a?(Hash)
92
97
  rescue => e
93
98
  log.error "failed to read data from plugin storage file", path: @path, error: e
@@ -128,7 +133,7 @@ module Fluent
128
133
  tmp_path = @path + '.tmp'
129
134
  begin
130
135
  json_string = Yajl::Encoder.encode(@store, pretty: @pretty_print)
131
- open(tmp_path, 'w:utf-8', @mode){ |io| io.write json_string }
136
+ open(tmp_path, 'w:utf-8', @mode) { |io| io.write json_string; io.fsync }
132
137
  File.rename(tmp_path, @path)
133
138
  rescue => e
134
139
  log.error "failed to save data for plugin storage to file", path: @path, tmp: tmp_path, error: e
@@ -751,8 +751,15 @@ module Fluent
751
751
  # Consider write_nonblock with {exception: false} when IO::WaitWritable error happens frequently.
752
752
  written_bytes = @_handler_socket.write_nonblock(@_handler_write_buffer)
753
753
  @_handler_write_buffer.slice!(0, written_bytes)
754
- super
755
754
  end
755
+
756
+ # No need to call `super` in a synchronized context because TLSServer doesn't use the inner buffer(::IO::Buffer) of Coolio::IO.
757
+ # Instead of using Coolio::IO's inner buffer, TLSServer has own buffer(`@_handler_write_buffer`). See also TLSServer#write.
758
+ # Actually, the only reason calling `super` here is call Coolio::IO#disable_write_watcher.
759
+ # If `super` is called in a synchronized context, it could cause a mutex recursive locking since Coolio::IO#on_write_complete
760
+ # eventually calls TLSServer#close which try to get a lock.
761
+ super
762
+
756
763
  close if @close_after_write_complete
757
764
  rescue IO::WaitWritable, IO::WaitReadable
758
765
  return
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.5.0.rc1'
19
+ VERSION = '1.5.0'
20
20
 
21
21
  end
@@ -680,7 +680,7 @@ class ParserFilterTest < Test::Unit::TestCase
680
680
 
681
681
  def test_call_emit_error_event_when_pattern_is_mismached
682
682
  flexmock(@d.instance.router).should_receive(:emit_error_event).
683
- with(String, Integer, Hash, ParserError.new("pattern not match with data '#{INVALID_MESSAGE}'")).once
683
+ with(String, Integer, Hash, ParserError.new("pattern not matched with data '#{INVALID_MESSAGE}'")).once
684
684
  @d.run do
685
685
  @d.feed(@tag, Fluent::EventTime.now.to_i, {'message' => INVALID_MESSAGE})
686
686
  end
@@ -55,6 +55,35 @@ EOS
55
55
  end
56
56
  end
57
57
 
58
+ data('Use protocol_type' => ['protocol_type tcp', :tcp, :udp],
59
+ 'Use transport' => ["<transport tcp>\n </transport>", nil, :tcp],
60
+ 'Use transport and protocol' => ["protocol_type udp\n<transport tcp>\n </transport>", :udp, :tcp])
61
+ def test_configure_protocol(param)
62
+ conf, proto_type, transport_proto_type = *param
63
+ d = create_driver([CONFIG, conf].join("\n"))
64
+
65
+ assert_equal(d.instance.protocol_type, proto_type)
66
+ assert_equal(d.instance.transport_config.protocol, transport_proto_type)
67
+ end
68
+
69
+ # For backward compat
70
+ def test_respect_protocol_type_than_transport
71
+ d = create_driver([CONFIG, "<transport tcp> \n</transport>", "protocol_type udp"].join("\n"))
72
+ tests = create_test_case
73
+
74
+ d.run(expect_emits: 2) do
75
+ u = UDPSocket.new
76
+ u.connect('127.0.0.1', PORT)
77
+ tests.each {|test|
78
+ u.send(test['msg'], 0)
79
+ }
80
+ end
81
+
82
+ assert(d.events.size > 0)
83
+ compare_test_result(d.events, tests)
84
+ end
85
+
86
+
58
87
  data(
59
88
  ipv4: ['127.0.0.1', CONFIG, ::Socket::AF_INET],
60
89
  ipv6: ['::1', IPv6_CONFIG, ::Socket::AF_INET6],
@@ -119,7 +148,7 @@ EOS
119
148
  end
120
149
 
121
150
  def test_msg_size_with_tcp
122
- d = create_driver([CONFIG, 'protocol_type tcp'].join("\n"))
151
+ d = create_driver([CONFIG, "<transport tcp> \n</transport>"].join("\n"))
123
152
  tests = create_test_case
124
153
 
125
154
  d.run(expect_emits: 2) do
@@ -135,7 +164,7 @@ EOS
135
164
  end
136
165
 
137
166
  def test_msg_size_with_same_tcp_connection
138
- d = create_driver([CONFIG, 'protocol_type tcp'].join("\n"))
167
+ d = create_driver([CONFIG, "<transport tcp> \n</transport>"].join("\n"))
139
168
  tests = create_test_case
140
169
 
141
170
  d.run(expect_emits: 2) do
@@ -289,7 +318,7 @@ EOS
289
318
 
290
319
  sub_test_case 'octet counting frame' do
291
320
  def test_msg_size_with_tcp
292
- d = create_driver([CONFIG, 'protocol_type tcp', 'frame_type octet_count'].join("\n"))
321
+ d = create_driver([CONFIG, "<transport tcp> \n</transport>", 'frame_type octet_count'].join("\n"))
293
322
  tests = create_test_case
294
323
 
295
324
  d.run(expect_emits: 2) do
@@ -305,7 +334,7 @@ EOS
305
334
  end
306
335
 
307
336
  def test_msg_size_with_same_tcp_connection
308
- d = create_driver([CONFIG, 'protocol_type tcp', 'frame_type octet_count'].join("\n"))
337
+ d = create_driver([CONFIG, "<transport tcp> \n</transport>", 'frame_type octet_count'].join("\n"))
309
338
  tests = create_test_case
310
339
 
311
340
  d.run(expect_emits: 2) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0.rc1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-09 00:00:00.000000000 Z
11
+ date: 2019-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -772,12 +772,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
772
772
  version: '2.1'
773
773
  required_rubygems_version: !ruby/object:Gem::Requirement
774
774
  requirements:
775
- - - ">"
775
+ - - ">="
776
776
  - !ruby/object:Gem::Version
777
- version: 1.3.1
777
+ version: '0'
778
778
  requirements: []
779
- rubyforge_project:
780
- rubygems_version: 2.6.14.1
779
+ rubygems_version: 3.0.3
781
780
  signing_key:
782
781
  specification_version: 4
783
782
  summary: Fluentd event collector