From 48e249d346d35048f2561da10758584a25f04c7d Mon Sep 17 00:00:00 2001 From: kubotat Date: Tue, 10 Oct 2023 19:00:12 +0000 Subject: [PATCH] add discard_kafka_delivery_failed_regex to nullify specific delivery failed events by regexp Signed-off-by: kubotat --- lib/fluent/plugin/out_rdkafka2.rb | 36 +++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/fluent/plugin/out_rdkafka2.rb b/lib/fluent/plugin/out_rdkafka2.rb index b02a959..0fc18e7 100644 --- a/lib/fluent/plugin/out_rdkafka2.rb +++ b/lib/fluent/plugin/out_rdkafka2.rb @@ -65,6 +65,8 @@ class Fluent::Rdkafka2Output < Output config_param :topic_key, :string, :default => 'topic', :desc => "Field for kafka topic" config_param :default_topic, :string, :default => nil, :desc => "Default output topic when record doesn't have topic field" + config_param :use_default_for_unknown_topic, :bool, :default => false, :desc => "If true, default_topic is used when topic not found" + config_param :use_default_for_unknown_partition_error, :bool, :default => false, :desc => "If true, default_topic is used when received unknown_partition error" config_param :message_key_key, :string, :default => 'message_key', :desc => "Field for kafka message key" config_param :default_message_key, :string, :default => nil config_param :partition_key, :string, :default => 'partition', :desc => "Field for kafka partition" @@ -234,6 +236,9 @@ def add(level, message = nil) @rdkafka = Rdkafka::Config.new(config) if @default_topic.nil? + if @use_default_for_unknown_topic || @use_default_for_unknown_partition_error + raise Fluent::ConfigError, "default_topic must be set when use_default_for_unknown_topic or use_default_for_unknown_partition_error is true" + end if @chunk_keys.include?(@topic_key) && !@chunk_key_tag log.warn "Use '#{@topic_key}' field of event record for topic but no fallback. Recommend to set default_topic or set 'tag' in buffer chunk keys like " end @@ -471,17 +476,25 @@ def write(chunk) def enqueue_with_retry(producer, topic, record_buf, message_key, partition, headers, time) attempt = 0 + actual_topic = topic + loop do begin @enqueue_rate.raise_if_limit_exceeded(record_buf.bytesize) if @enqueue_rate - return producer.produce(topic: topic, payload: record_buf, key: message_key, partition: partition, headers: headers, timestamp: @use_event_time ? Time.at(time) : nil) + return producer.produce(topic: actual_topic, payload: record_buf, key: message_key, partition: partition, headers: headers, timestamp: @use_event_time ? Time.at(time) : nil) rescue EnqueueRate::LimitExceeded => e @enqueue_rate.revert if @enqueue_rate duration = e.next_retry_clock - Fluent::Clock.now sleep(duration) if duration > 0.0 rescue Exception => e @enqueue_rate.revert if @enqueue_rate - if e.respond_to?(:code) && e.code == :queue_full + + if !e.respond_to?(:code) + raise e + end + + case e.code + when :queue_full if attempt <= @max_enqueue_retries log.warn "Failed to enqueue message; attempting retry #{attempt} of #{@max_enqueue_retries} after #{@enqueue_retry_backoff}s" sleep @enqueue_retry_backoff @@ -489,6 +502,25 @@ def enqueue_with_retry(producer, topic, record_buf, message_key, partition, head else raise "Failed to enqueue message although tried retry #{@max_enqueue_retries} times" end + # https://github.com/confluentinc/librdkafka/blob/c282ba2423b2694052393c8edb0399a5ef471b3f/src/rdkafka.h#LL309C9-L309C41 + # RD_KAFKA_RESP_ERR__UNKNOWN_TOPIC + when :unknown_topic + if @use_default_for_unknown_topic && actual_topic != @default_topic + log.debug "'#{actual_topic}' topic not found. Retry with '#{@default_topic}' topic" + actual_topic = @default_topic + retry + end + raise e + # https://github.com/confluentinc/librdkafka/blob/c282ba2423b2694052393c8edb0399a5ef471b3f/src/rdkafka.h#L305 + # RD_KAFKA_RESP_ERR__UNKNOWN_PARTITION + when :unknown_partition + if @use_default_for_unknown_partition_error && actual_topic != @default_topic + log.debug "failed writing to topic '#{actual_topic}' with error '#{e.to_s}'. Writing message to topic '#{@default_topic}'" + actual_topic = @default_topic + retry + end + + raise e else raise e end