1616
1717require 'fluent/plugin/base'
1818require 'fluent/plugin/owned_by_mixin'
19+ require 'fluent/plugin_id'
20+ require 'fluent/plugin_helper'
1921require 'fluent/unique_id'
2022require 'fluent/ext_monitor_require'
2123
@@ -24,7 +26,9 @@ module Plugin
2426 class Buffer < Base
2527 include OwnedByMixin
2628 include UniqueId ::Mixin
29+ include PluginId
2730 include MonitorMixin
31+ include PluginHelper ::Mixin # for metrics
2832
2933 class BufferError < StandardError ; end
3034 class BufferOverflowError < BufferError ; end
@@ -39,6 +43,8 @@ class BufferChunkOverflowError < BufferError; end # A record size is larger than
3943
4044 configured_in :buffer
4145
46+ helpers_internal :metrics
47+
4248 # TODO: system total buffer limit size in bytes by SystemConfig
4349
4450 config_param :chunk_limit_size , :size , default : DEFAULT_CHUNK_LIMIT_SIZE
@@ -153,8 +159,11 @@ def hash
153159 end
154160 end
155161
162+ # for metrics
163+ attr_reader :stage_size_metrics , :stage_length_metrics , :queue_size_metrics , :queue_length_metrics
164+ attr_reader :available_buffer_space_ratios_metrics , :total_queued_size_metrics
165+ attr_reader :newest_timekey_metrics , :oldest_timekey_metrics
156166 # for tests
157- attr_accessor :stage_size , :queue_size
158167 attr_reader :stage , :queue , :dequeued , :queued_num
159168
160169 def initialize
@@ -171,12 +180,35 @@ def initialize
171180 @queued_num = { } # metadata => int (number of queued chunks)
172181 @dequeued_num = { } # metadata => int (number of dequeued chunks)
173182
174- @stage_size = @queue_size = 0
183+ @stage_length_metrics = nil
184+ @stage_size_metrics = nil
185+ @queue_length_metrics = nil
186+ @queue_size_metrics = nil
187+ @available_buffer_space_ratios_metrics = nil
188+ @total_queued_size_metrics = nil
189+ @newest_timekey_metrics = nil
190+ @oldest_timekey_metrics = nil
175191 @timekeys = Hash . new ( 0 )
176192 @enable_update_timekeys = false
177193 @mutex = Mutex . new
178194 end
179195
196+ def stage_size
197+ @stage_size_metrics . get
198+ end
199+
200+ def stage_size = ( value )
201+ @stage_size_metrics . set ( value )
202+ end
203+
204+ def queue_size
205+ @queue_size_metrics . get
206+ end
207+
208+ def queue_size = ( value )
209+ @queue_size_metrics . set ( value )
210+ end
211+
180212 def persistent?
181213 false
182214 end
@@ -187,6 +219,28 @@ def configure(conf)
187219 unless @queue_limit_length . nil?
188220 @total_limit_size = @chunk_limit_size * @queue_limit_length
189221 end
222+ @stage_length_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "stage_length" ,
223+ help_text : 'Length of stage buffers' , prefer_gauge : true )
224+ @stage_length_metrics . set ( 0 )
225+ @stage_size_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "stage_byte_size" ,
226+ help_text : 'Total size of stage buffers' , prefer_gauge : true )
227+ @stage_size_metrics . set ( 0 ) # Ensure zero.
228+ @queue_length_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "queue_length" ,
229+ help_text : 'Length of queue buffers' , prefer_gauge : true )
230+ @queue_length_metrics . set ( 0 )
231+ @queue_size_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "queue_byte_size" ,
232+ help_text : 'Total size of queue buffers' , prefer_gauge : true )
233+ @queue_size_metrics . set ( 0 ) # Ensure zero.
234+ @available_buffer_space_ratios_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "available_buffer_space_ratios" ,
235+ help_text : 'Ratio of available space in buffer' , prefer_gauge : true )
236+ @available_buffer_space_ratios_metrics . set ( 100 ) # Default is 100%.
237+ @total_queued_size_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "total_queued_size" ,
238+ help_text : 'Total size of stage and queue buffers' , prefer_gauge : true )
239+ @total_queued_size_metrics . set ( 0 )
240+ @newest_timekey_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "newest_timekey" ,
241+ help_text : 'Newest timekey in buffer' , prefer_gauge : true )
242+ @oldest_timekey_metrics = metrics_create ( namespace : "fluentd" , subsystem : "buffer" , name : "oldest_timekey" ,
243+ help_text : 'Oldest timekey in buffer' , prefer_gauge : true )
190244 end
191245
192246 def enable_update_timekeys
@@ -198,15 +252,15 @@ def start
198252
199253 @stage , @queue = resume
200254 @stage . each_pair do |metadata , chunk |
201- @stage_size += chunk . bytesize
255+ @stage_size_metrics . add ( chunk . bytesize )
202256 end
203257 @queue . each do |chunk |
204258 @queued_num [ chunk . metadata ] ||= 0
205259 @queued_num [ chunk . metadata ] += 1
206- @queue_size += chunk . bytesize
260+ @queue_size_metrics . add ( chunk . bytesize )
207261 end
208262 update_timekeys
209- log . debug "buffer started" , instance : self . object_id , stage_size : @stage_size , queue_size : @queue_size
263+ log . debug "buffer started" , instance : self . object_id , stage_size : @stage_size_metrics . get , queue_size : @queue_size_metrics . get
210264 end
211265
212266 def close
@@ -228,17 +282,19 @@ def close
228282 def terminate
229283 super
230284 @dequeued = @stage = @queue = @queued_num = nil
231- @stage_size = @queue_size = 0
285+ @stage_length_metrics = @stage_size_metrics = @queue_length_metrics = @queue_size_metrics = nil
286+ @available_buffer_space_ratios_metrics = @total_queued_size_metrics = nil
287+ @newest_timekey_metrics = @oldest_timekey_metrics = nil
232288 @timekeys . clear
233289 end
234290
235291 def storable?
236- @total_limit_size > @stage_size + @queue_size
292+ @total_limit_size > @stage_size_metrics . get + @queue_size_metrics . get
237293 end
238294
239295 ## TODO: for back pressure feature
240296 # def used?(ratio)
241- # @total_limit_size * ratio > @stage_size + @queue_size
297+ # @total_limit_size * ratio > @stage_size_metrics.get + @queue_size_metrics.get
242298 # end
243299
244300 def resume
@@ -344,7 +400,7 @@ def write(metadata_and_data, format: nil, size: nil, enqueue: false)
344400 #
345401 staged_bytesizes_by_chunk . each do |chunk , bytesize |
346402 chunk . synchronize do
347- synchronize { @stage_size += bytesize }
403+ synchronize { @stage_size_metrics . add ( bytesize ) }
348404 log . on_trace { log . trace { "chunk #{ chunk . path } size_added: #{ bytesize } new_size: #{ chunk . bytesize } " } }
349405 end
350406 end
@@ -361,7 +417,7 @@ def write(metadata_and_data, format: nil, size: nil, enqueue: false)
361417 u . metadata . seq = 0
362418 synchronize {
363419 @stage [ m ] = u . staged!
364- @stage_size += u . bytesize
420+ @stage_size_metrics . add ( u . bytesize )
365421 }
366422 end
367423 end
@@ -428,8 +484,8 @@ def enqueue_chunk(metadata)
428484 chunk . enqueued!
429485 end
430486 bytesize = chunk . bytesize
431- @stage_size -= bytesize
432- @queue_size += bytesize
487+ @stage_size_metrics . sub ( bytesize )
488+ @queue_size_metrics . add ( bytesize )
433489 end
434490 end
435491 nil
@@ -446,7 +502,7 @@ def enqueue_unstaged_chunk(chunk)
446502 @queued_num [ metadata ] = @queued_num . fetch ( metadata , 0 ) + 1
447503 chunk . enqueued!
448504 end
449- @queue_size += chunk . bytesize
505+ @queue_size_metrics . add ( chunk . bytesize )
450506 end
451507 end
452508
@@ -531,7 +587,7 @@ def purge_chunk(chunk_id)
531587 begin
532588 bytesize = chunk . bytesize
533589 chunk . purge
534- @queue_size -= bytesize
590+ @queue_size_metrics . sub ( bytesize )
535591 rescue => e
536592 log . error "failed to purge buffer chunk" , chunk_id : dump_unique_id_hex ( chunk_id ) , error_class : e . class , error : e
537593 log . error_backtrace
@@ -562,7 +618,7 @@ def clear_queue!
562618 log . error_backtrace
563619 end
564620 end
565- @queue_size = 0
621+ @queue_size_metrics . set ( 0 )
566622 end
567623 end
568624
@@ -765,23 +821,29 @@ def write_step_by_step(metadata, data, format, splits_count, &block)
765821 ]
766822
767823 def statistics
768- stage_size , queue_size = @stage_size , @queue_size
824+ stage_size , queue_size = @stage_size_metrics . get , @queue_size_metrics . get
769825 buffer_space = 1.0 - ( ( stage_size + queue_size * 1.0 ) / @total_limit_size )
826+ @stage_length_metrics . set ( @stage . size )
827+ @queue_length_metrics . set ( @queue . size )
828+ @available_buffer_space_ratios_metrics . set ( buffer_space * 100 )
829+ @total_queued_size_metrics . set ( stage_size + queue_size )
770830 stats = {
771- 'stage_length' => @stage . size ,
831+ 'stage_length' => @stage_length_metrics . get ,
772832 'stage_byte_size' => stage_size ,
773- 'queue_length' => @queue . size ,
833+ 'queue_length' => @queue_length_metrics . get ,
774834 'queue_byte_size' => queue_size ,
775- 'available_buffer_space_ratios' => ( buffer_space * 100 ) . round ( 1 ) ,
776- 'total_queued_size' => stage_size + queue_size ,
835+ 'available_buffer_space_ratios' => @available_buffer_space_ratios_metrics . get . round ( 1 ) ,
836+ 'total_queued_size' => @total_queued_size_metrics . get ,
777837 }
778838
779839 tkeys = timekeys
780840 if ( m = tkeys . min )
781- stats [ 'oldest_timekey' ] = m
841+ @oldest_timekey_metrics . set ( m )
842+ stats [ 'oldest_timekey' ] = @oldest_timekey_metrics . get
782843 end
783844 if ( m = tkeys . max )
784- stats [ 'newest_timekey' ] = m
845+ @newest_timekey_metrics . set ( m )
846+ stats [ 'newest_timekey' ] = @newest_timekey_metrics . get
785847 end
786848
787849 { 'buffer' => stats }
0 commit comments