@@ -25,12 +25,19 @@ module Fluent::Plugin
2525 class ForwardInput < Input
2626 Fluent ::Plugin . register_input ( 'forward' , self )
2727
28+
2829 # See the wiki page below for protocol specification
2930 # https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v1
3031
3132 helpers :server
3233
3334 LISTEN_PORT = 24224
35+ OPTION_ACK = 'ack' . freeze
36+ OPTION_CHUNK = 'chunk' . freeze
37+ OPTION_COMPRESSED = 'compressed' . freeze
38+ OPTION_FLUENT_SIGNAL = 'fluent_signal' . freeze
39+ OPTION_SIZE = 'size' . freeze
40+ OPTION_TEXT = 'text' . freeze
3441
3542 desc 'The port to listen to.'
3643 config_param :port , :integer , default : LISTEN_PORT
@@ -275,8 +282,8 @@ def read_messages(conn, &block)
275282 end
276283
277284 def response ( option )
278- if option && option [ 'chunk' ]
279- return { 'ack' => option [ 'chunk' ] }
285+ if option && option [ OPTION_CHUNK ]
286+ return { OPTION_ACK => option [ OPTION_CHUNK ] }
280287 end
281288 nil
282289 end
@@ -310,34 +317,27 @@ def on_message(msg, chunk_size, conn)
310317 when String
311318 # PackedForward
312319 option = msg [ 2 ] || { }
313- size = option [ 'size' ] || 0
320+ size = option [ OPTION_SIZE ] || 0
321+ compressed = option [ OPTION_COMPRESSED ]
314322
315- if option [ ' compressed' ] && option [ ' compressed' ] != 'text'
316- es = Fluent ::CompressedMessagePackEventStream . new ( entries , nil , size . to_i , compress : option [ ' compressed' ] . to_sym , decompression_size_limit : @decompression_size_limit )
323+ if compressed && compressed != OPTION_TEXT
324+ es = Fluent ::CompressedMessagePackEventStream . new ( entries , nil , size . to_i , compress : compressed . to_sym , decompression_size_limit : @decompression_size_limit )
317325 else
318326 es = Fluent ::MessagePackEventStream . new ( entries , nil , size . to_i )
319327 end
320- es = check_and_skip_invalid_event ( tag , es , conn . remote_host ) if @skip_invalid_event
328+ if @skip_invalid_event
329+ es = normalize_event_stream ( tag , es , conn . remote_host )
330+ elsif option [ OPTION_FLUENT_SIGNAL ] == 0
331+ es = Fluent ::MetadataTimeEventStream . new ( es )
332+ end
321333 if @enable_field_injection
322334 es = add_source_info ( es , conn )
323335 end
324336 router . emit_stream ( tag , es )
325337
326338 when Array
327339 # Forward
328- es = if @skip_invalid_event
329- check_and_skip_invalid_event ( tag , entries , conn . remote_host )
330- else
331- es = Fluent ::MultiEventStream . new
332- entries . each { |e |
333- record = e [ 1 ]
334- next if record . nil?
335- time = e [ 0 ]
336- time = Fluent ::EventTime . now if time . nil? || time . to_i == 0 # `to_i == 0` for empty EventTime
337- es . add ( time , record )
338- }
339- es
340- end
340+ es = normalize_event_stream ( tag , entries , conn . remote_host )
341341 if @enable_field_injection
342342 es = add_source_info ( es , conn )
343343 end
@@ -346,7 +346,7 @@ def on_message(msg, chunk_size, conn)
346346
347347 else
348348 # Message
349- time = msg [ 1 ]
349+ time = extract_event_time ( msg [ 1 ] )
350350 record = msg [ 2 ]
351351 if @skip_invalid_event && invalid_event? ( tag , time , record )
352352 log . warn "got invalid event and drop it:" , host : conn . remote_host , tag : tag , time : time , record : record
@@ -367,21 +367,29 @@ def on_message(msg, chunk_size, conn)
367367 end
368368
369369 def invalid_event? ( tag , time , record )
370+ time = extract_event_time ( time )
370371 !( ( time . is_a? ( Integer ) || time . is_a? ( ::Fluent ::EventTime ) ) && record . is_a? ( Hash ) && tag . is_a? ( String ) )
371372 end
372373
373- def check_and_skip_invalid_event ( tag , es , remote_host )
374+ def normalize_event_stream ( tag , es , remote_host )
374375 new_es = Fluent ::MultiEventStream . new
375376 es . each { |time , record |
376- if invalid_event? ( tag , time , record )
377+ time = extract_event_time ( time )
378+ if @skip_invalid_event && invalid_event? ( tag , time , record )
377379 log . warn "skip invalid event:" , host : remote_host , tag : tag , time : time , record : record
378380 next
379381 end
382+ next if record . nil?
383+ time = Fluent ::EventTime . now if time . nil? || time . to_i == 0 # `to_i == 0` for empty EventTime
380384 new_es . add ( time , record )
381385 }
382386 new_es
383387 end
384388
389+ def extract_event_time ( time )
390+ time . is_a? ( Array ) ? time [ 0 ] : time
391+ end
392+
385393 def add_source_info ( es , conn )
386394 new_es = Fluent ::MultiEventStream . new
387395 if @source_address_key && @source_hostname_key
0 commit comments