ruby-kafka 0.7.10 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ require "kafka/fetch_operation"
4
4
 
5
5
  module Kafka
6
6
  class Fetcher
7
- attr_reader :queue
7
+ attr_reader :queue, :max_wait_time
8
8
 
9
9
  def initialize(cluster:, logger:, instrumenter:, max_queue_size:, group:)
10
10
  @cluster = cluster
@@ -17,6 +17,9 @@ module Kafka
17
17
  @commands = Queue.new
18
18
  @next_offsets = Hash.new { |h, k| h[k] = {} }
19
19
 
20
+ # We are only running when someone calls start.
21
+ @running = false
22
+
20
23
  # Long poll until at least this many bytes can be fetched.
21
24
  @min_bytes = 1
22
25
 
@@ -110,7 +113,7 @@ module Kafka
110
113
  elsif @queue.size < @max_queue_size
111
114
  step
112
115
  else
113
- @logger.warn "Reached max fetcher queue size (#{@max_queue_size}), sleeping 1s"
116
+ @logger.info "Reached max fetcher queue size (#{@max_queue_size}), sleeping 1s"
114
117
  sleep 1
115
118
  end
116
119
  ensure
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kafka
4
+ # Holds a list of interceptors that implement `call`
5
+ # and wraps calls to a chain of custom interceptors.
6
+ class Interceptors
7
+ def initialize(interceptors:, logger:)
8
+ @interceptors = interceptors || []
9
+ @logger = TaggedLogger.new(logger)
10
+ end
11
+
12
+ # This method is called when the client produces a message or once the batches are fetched.
13
+ # The message returned from the first call is passed to the second interceptor call, and so on in an
14
+ # interceptor chain. This method does not throw exceptions.
15
+ #
16
+ # @param intercepted [Kafka::PendingMessage || Kafka::FetchedBatch] the produced message or
17
+ # fetched batch.
18
+ #
19
+ # @return [Kafka::PendingMessage || Kafka::FetchedBatch] the intercepted message or batch
20
+ # returned by the last interceptor.
21
+ def call(intercepted)
22
+ @interceptors.each do |interceptor|
23
+ begin
24
+ intercepted = interceptor.call(intercepted)
25
+ rescue Exception => e
26
+ @logger.warn "Error executing interceptor for topic: #{intercepted.topic} partition: #{intercepted.partition}: #{e.message}\n#{e.backtrace.join("\n")}"
27
+ end
28
+ end
29
+
30
+ intercepted
31
+ end
32
+ end
33
+ end
@@ -50,9 +50,20 @@ module Kafka
50
50
  # @param offset [Integer] the offset of the message that should be marked as processed.
51
51
  # @return [nil]
52
52
  def mark_as_processed(topic, partition, offset)
53
- @uncommitted_offsets += 1
53
+ unless @group.assigned_to?(topic, partition)
54
+ @logger.debug "Not marking #{topic}/#{partition}:#{offset} as processed for partition not assigned to this consumer."
55
+ return
56
+ end
54
57
  @processed_offsets[topic] ||= {}
55
58
 
59
+ last_processed_offset = @processed_offsets[topic][partition] || -1
60
+ if last_processed_offset > offset + 1
61
+ @logger.debug "Not overwriting newer offset #{topic}/#{partition}:#{last_processed_offset - 1} with older #{offset}"
62
+ return
63
+ end
64
+
65
+ @uncommitted_offsets += 1
66
+
56
67
  # The committed offset should always be the offset of the next message that the
57
68
  # application will read, thus adding one to the last message processed.
58
69
  @processed_offsets[topic][partition] = offset + 1
@@ -19,7 +19,7 @@ module Kafka
19
19
  # @param message [Kafka::PendingMessage] the message that should be assigned
20
20
  # a partition.
21
21
  # @return [Integer] the partition number.
22
- def self.partition_for_key(partition_count, message)
22
+ def call(partition_count, message)
23
23
  raise ArgumentError if partition_count == 0
24
24
 
25
25
  # If no explicit partition key is specified we use the message key instead.
@@ -7,6 +7,7 @@ require "kafka/produce_operation"
7
7
  require "kafka/pending_message_queue"
8
8
  require "kafka/pending_message"
9
9
  require "kafka/compressor"
10
+ require "kafka/interceptors"
10
11
 
11
12
  module Kafka
12
13
  # Allows sending messages to a Kafka cluster.
@@ -129,7 +130,9 @@ module Kafka
129
130
  class Producer
130
131
  class AbortTransaction < StandardError; end
131
132
 
132
- def initialize(cluster:, transaction_manager:, logger:, instrumenter:, compressor:, ack_timeout:, required_acks:, max_retries:, retry_backoff:, max_buffer_size:, max_buffer_bytesize:)
133
+ def initialize(cluster:, transaction_manager:, logger:, instrumenter:, compressor:, ack_timeout:,
134
+ required_acks:, max_retries:, retry_backoff:, max_buffer_size:,
135
+ max_buffer_bytesize:, partitioner:, interceptors: [])
133
136
  @cluster = cluster
134
137
  @transaction_manager = transaction_manager
135
138
  @logger = TaggedLogger.new(logger)
@@ -141,6 +144,8 @@ module Kafka
141
144
  @max_buffer_size = max_buffer_size
142
145
  @max_buffer_bytesize = max_buffer_bytesize
143
146
  @compressor = compressor
147
+ @partitioner = partitioner
148
+ @interceptors = Interceptors.new(interceptors: interceptors, logger: logger)
144
149
 
145
150
  # The set of topics that are produced to.
146
151
  @target_topics = Set.new
@@ -188,15 +193,18 @@ module Kafka
188
193
  # @raise [BufferOverflow] if the maximum buffer size has been reached.
189
194
  # @return [nil]
190
195
  def produce(value, key: nil, headers: {}, topic:, partition: nil, partition_key: nil, create_time: Time.now)
191
- message = PendingMessage.new(
196
+ # We want to fail fast if `topic` isn't a String
197
+ topic = topic.to_str
198
+
199
+ message = @interceptors.call(PendingMessage.new(
192
200
  value: value && value.to_s,
193
201
  key: key && key.to_s,
194
202
  headers: headers,
195
- topic: topic.to_s,
203
+ topic: topic,
196
204
  partition: partition && Integer(partition),
197
205
  partition_key: partition_key && partition_key.to_s,
198
206
  create_time: create_time
199
- )
207
+ ))
200
208
 
201
209
  if buffer_size >= @max_buffer_size
202
210
  buffer_overflow topic,
@@ -452,7 +460,7 @@ module Kafka
452
460
 
453
461
  if partition.nil?
454
462
  partition_count = @cluster.partitions_for(message.topic).count
455
- partition = Partitioner.partition_for_key(partition_count, message)
463
+ partition = @partitioner.call(partition_count, message)
456
464
  end
457
465
 
458
466
  @buffer.write(
@@ -42,11 +42,11 @@ module Kafka
42
42
  class ConnectionSubscriber < ActiveSupport::Subscriber
43
43
  def initialize
44
44
  super
45
- @api_calls = Prometheus.registry.counter(:api_calls, 'Total calls')
46
- @api_latency = Prometheus.registry.histogram(:api_latency, 'Latency', {}, LATENCY_BUCKETS)
47
- @api_request_size = Prometheus.registry.histogram(:api_request_size, 'Request size', {}, SIZE_BUCKETS)
48
- @api_response_size = Prometheus.registry.histogram(:api_response_size, 'Response size', {}, SIZE_BUCKETS)
49
- @api_errors = Prometheus.registry.counter(:api_errors, 'Errors')
45
+ @api_calls = Prometheus.registry.counter(:api_calls, docstring: 'Total calls', labels: [:client, :api, :broker])
46
+ @api_latency = Prometheus.registry.histogram(:api_latency, docstring: 'Latency', buckets: LATENCY_BUCKETS, labels: [:client, :api, :broker])
47
+ @api_request_size = Prometheus.registry.histogram(:api_request_size, docstring: 'Request size', buckets: SIZE_BUCKETS, labels: [:client, :api, :broker])
48
+ @api_response_size = Prometheus.registry.histogram(:api_response_size, docstring: 'Response size', buckets: SIZE_BUCKETS, labels: [:client, :api, :broker])
49
+ @api_errors = Prometheus.registry.counter(:api_errors, docstring: 'Errors', labels: [:client, :api, :broker])
50
50
  end
51
51
 
52
52
  def request(event)
@@ -58,34 +58,34 @@ module Kafka
58
58
  request_size = event.payload.fetch(:request_size, 0)
59
59
  response_size = event.payload.fetch(:response_size, 0)
60
60
 
61
- @api_calls.increment(key)
62
- @api_latency.observe(key, event.duration)
63
- @api_request_size.observe(key, request_size)
64
- @api_response_size.observe(key, response_size)
65
- @api_errors.increment(key) if event.payload.key?(:exception)
61
+ @api_calls.increment(labels: key)
62
+ @api_latency.observe(event.duration, labels: key)
63
+ @api_request_size.observe(request_size, labels: key)
64
+ @api_response_size.observe(response_size, labels: key)
65
+ @api_errors.increment(labels: key) if event.payload.key?(:exception)
66
66
  end
67
67
  end
68
68
 
69
69
  class ConsumerSubscriber < ActiveSupport::Subscriber
70
70
  def initialize
71
71
  super
72
- @process_messages = Prometheus.registry.counter(:consumer_process_messages, 'Total messages')
73
- @process_message_errors = Prometheus.registry.counter(:consumer_process_message_errors, 'Total errors')
72
+ @process_messages = Prometheus.registry.counter(:consumer_process_messages, docstring: 'Total messages', labels: [:client, :group_id, :topic, :partition])
73
+ @process_message_errors = Prometheus.registry.counter(:consumer_process_message_errors, docstring: 'Total errors', labels: [:client, :group_id, :topic, :partition])
74
74
  @process_message_latency =
75
- Prometheus.registry.histogram(:consumer_process_message_latency, 'Latency', {}, LATENCY_BUCKETS)
76
- @offset_lag = Prometheus.registry.gauge(:consumer_offset_lag, 'Offset lag')
77
- @time_lag = Prometheus.registry.gauge(:consumer_time_lag, 'Time lag of message')
78
- @process_batch_errors = Prometheus.registry.counter(:consumer_process_batch_errors, 'Total errors in batch')
75
+ Prometheus.registry.histogram(:consumer_process_message_latency, docstring: 'Latency', buckets: LATENCY_BUCKETS, labels: [:client, :group_id, :topic, :partition])
76
+ @offset_lag = Prometheus.registry.gauge(:consumer_offset_lag, docstring: 'Offset lag', labels: [:client, :group_id, :topic, :partition])
77
+ @time_lag = Prometheus.registry.gauge(:consumer_time_lag, docstring: 'Time lag of message', labels: [:client, :group_id, :topic, :partition])
78
+ @process_batch_errors = Prometheus.registry.counter(:consumer_process_batch_errors, docstring: 'Total errors in batch', labels: [:client, :group_id, :topic, :partition])
79
79
  @process_batch_latency =
80
- Prometheus.registry.histogram(:consumer_process_batch_latency, 'Latency in batch', {}, LATENCY_BUCKETS)
81
- @batch_size = Prometheus.registry.histogram(:consumer_batch_size, 'Size of batch', {}, SIZE_BUCKETS)
82
- @join_group = Prometheus.registry.histogram(:consumer_join_group, 'Time to join group', {}, DELAY_BUCKETS)
83
- @join_group_errors = Prometheus.registry.counter(:consumer_join_group_errors, 'Total error in joining group')
84
- @sync_group = Prometheus.registry.histogram(:consumer_sync_group, 'Time to sync group', {}, DELAY_BUCKETS)
85
- @sync_group_errors = Prometheus.registry.counter(:consumer_sync_group_errors, 'Total error in syncing group')
86
- @leave_group = Prometheus.registry.histogram(:consumer_leave_group, 'Time to leave group', {}, DELAY_BUCKETS)
87
- @leave_group_errors = Prometheus.registry.counter(:consumer_leave_group_errors, 'Total error in leaving group')
88
- @pause_duration = Prometheus.registry.gauge(:consumer_pause_duration, 'Pause duration')
80
+ Prometheus.registry.histogram(:consumer_process_batch_latency, docstring: 'Latency in batch', buckets: LATENCY_BUCKETS, labels: [:client, :group_id, :topic, :partition])
81
+ @batch_size = Prometheus.registry.histogram(:consumer_batch_size, docstring: 'Size of batch', buckets: SIZE_BUCKETS, labels: [:client, :group_id, :topic, :partition])
82
+ @join_group = Prometheus.registry.histogram(:consumer_join_group, docstring: 'Time to join group', buckets: DELAY_BUCKETS, labels: [:client, :group_id])
83
+ @join_group_errors = Prometheus.registry.counter(:consumer_join_group_errors, docstring: 'Total error in joining group', labels: [:client, :group_id])
84
+ @sync_group = Prometheus.registry.histogram(:consumer_sync_group, docstring: 'Time to sync group', buckets: DELAY_BUCKETS, labels: [:client, :group_id])
85
+ @sync_group_errors = Prometheus.registry.counter(:consumer_sync_group_errors, docstring: 'Total error in syncing group', labels: [:client, :group_id])
86
+ @leave_group = Prometheus.registry.histogram(:consumer_leave_group, docstring: 'Time to leave group', buckets: DELAY_BUCKETS, labels: [:client, :group_id])
87
+ @leave_group_errors = Prometheus.registry.counter(:consumer_leave_group_errors, docstring: 'Total error in leaving group', labels: [:client, :group_id])
88
+ @pause_duration = Prometheus.registry.gauge(:consumer_pause_duration, docstring: 'Pause duration', labels: [:client, :group_id, :topic, :partition])
89
89
  end
90
90
 
91
91
  def process_message(event)
@@ -102,18 +102,18 @@ module Kafka
102
102
  time_lag = create_time && ((Time.now - create_time) * 1000).to_i
103
103
 
104
104
  if event.payload.key?(:exception)
105
- @process_message_errors.increment(key)
105
+ @process_message_errors.increment(labels: key)
106
106
  else
107
- @process_message_latency.observe(key, event.duration)
108
- @process_messages.increment(key)
107
+ @process_message_latency.observe(event.duration, labels: key)
108
+ @process_messages.increment(labels: key)
109
109
  end
110
110
 
111
- @offset_lag.set(key, offset_lag)
111
+ @offset_lag.set(offset_lag, labels: key)
112
112
 
113
113
  # Not all messages have timestamps.
114
114
  return unless time_lag
115
115
 
116
- @time_lag.set(key, time_lag)
116
+ @time_lag.set(time_lag, labels: key)
117
117
  end
118
118
 
119
119
  def process_batch(event)
@@ -126,10 +126,10 @@ module Kafka
126
126
  message_count = event.payload.fetch(:message_count)
127
127
 
128
128
  if event.payload.key?(:exception)
129
- @process_batch_errors.increment(key)
129
+ @process_batch_errors.increment(labels: key)
130
130
  else
131
- @process_batch_latency.observe(key, event.duration)
132
- @process_messages.increment(key, message_count)
131
+ @process_batch_latency.observe(event.duration, labels: key)
132
+ @process_messages.increment(by: message_count, labels: key)
133
133
  end
134
134
  end
135
135
 
@@ -143,29 +143,29 @@ module Kafka
143
143
  offset_lag = event.payload.fetch(:offset_lag)
144
144
  batch_size = event.payload.fetch(:message_count)
145
145
 
146
- @batch_size.observe(key, batch_size)
147
- @offset_lag.set(key, offset_lag)
146
+ @batch_size.observe(batch_size, labels: key)
147
+ @offset_lag.set(offset_lag, labels: key)
148
148
  end
149
149
 
150
150
  def join_group(event)
151
151
  key = { client: event.payload.fetch(:client_id), group_id: event.payload.fetch(:group_id) }
152
- @join_group.observe(key, event.duration)
152
+ @join_group.observe(event.duration, labels: key)
153
153
 
154
- @join_group_errors.increment(key) if event.payload.key?(:exception)
154
+ @join_group_errors.increment(labels: key) if event.payload.key?(:exception)
155
155
  end
156
156
 
157
157
  def sync_group(event)
158
158
  key = { client: event.payload.fetch(:client_id), group_id: event.payload.fetch(:group_id) }
159
- @sync_group.observe(key, event.duration)
159
+ @sync_group.observe(event.duration, labels: key)
160
160
 
161
- @sync_group_errors.increment(key) if event.payload.key?(:exception)
161
+ @sync_group_errors.increment(labels: key) if event.payload.key?(:exception)
162
162
  end
163
163
 
164
164
  def leave_group(event)
165
165
  key = { client: event.payload.fetch(:client_id), group_id: event.payload.fetch(:group_id) }
166
- @leave_group.observe(key, event.duration)
166
+ @leave_group.observe(event.duration, labels: key)
167
167
 
168
- @leave_group_errors.increment(key) if event.payload.key?(:exception)
168
+ @leave_group_errors.increment(labels: key) if event.payload.key?(:exception)
169
169
  end
170
170
 
171
171
  def pause_status(event)
@@ -177,28 +177,28 @@ module Kafka
177
177
  }
178
178
 
179
179
  duration = event.payload.fetch(:duration)
180
- @pause_duration.set(key, duration)
180
+ @pause_duration.set(duration, labels: key)
181
181
  end
182
182
  end
183
183
 
184
184
  class ProducerSubscriber < ActiveSupport::Subscriber
185
185
  def initialize
186
186
  super
187
- @produce_messages = Prometheus.registry.counter(:producer_produced_messages, 'Produced messages total')
187
+ @produce_messages = Prometheus.registry.counter(:producer_produced_messages, docstring: 'Produced messages total', labels: [:client, :topic])
188
188
  @produce_message_size =
189
- Prometheus.registry.histogram(:producer_message_size, 'Message size', {}, SIZE_BUCKETS)
190
- @buffer_size = Prometheus.registry.histogram(:producer_buffer_size, 'Buffer size', {}, SIZE_BUCKETS)
191
- @buffer_fill_ratio = Prometheus.registry.histogram(:producer_buffer_fill_ratio, 'Buffer fill ratio')
192
- @buffer_fill_percentage = Prometheus.registry.histogram(:producer_buffer_fill_percentage, 'Buffer fill percentage')
193
- @produce_errors = Prometheus.registry.counter(:producer_produce_errors, 'Produce errors')
194
- @deliver_errors = Prometheus.registry.counter(:producer_deliver_errors, 'Deliver error')
189
+ Prometheus.registry.histogram(:producer_message_size, docstring: 'Message size', buckets: SIZE_BUCKETS, labels: [:client, :topic])
190
+ @buffer_size = Prometheus.registry.histogram(:producer_buffer_size, docstring: 'Buffer size', buckets: SIZE_BUCKETS, labels: [:client])
191
+ @buffer_fill_ratio = Prometheus.registry.histogram(:producer_buffer_fill_ratio, docstring: 'Buffer fill ratio', labels: [:client])
192
+ @buffer_fill_percentage = Prometheus.registry.histogram(:producer_buffer_fill_percentage, docstring: 'Buffer fill percentage', labels: [:client])
193
+ @produce_errors = Prometheus.registry.counter(:producer_produce_errors, docstring: 'Produce errors', labels: [:client, :topic])
194
+ @deliver_errors = Prometheus.registry.counter(:producer_deliver_errors, docstring: 'Deliver error', labels: [:client])
195
195
  @deliver_latency =
196
- Prometheus.registry.histogram(:producer_deliver_latency, 'Delivery latency', {}, LATENCY_BUCKETS)
197
- @deliver_messages = Prometheus.registry.counter(:producer_deliver_messages, 'Total count of delivered messages')
198
- @deliver_attempts = Prometheus.registry.histogram(:producer_deliver_attempts, 'Delivery attempts')
199
- @ack_messages = Prometheus.registry.counter(:producer_ack_messages, 'Ack')
200
- @ack_delay = Prometheus.registry.histogram(:producer_ack_delay, 'Ack delay', {}, LATENCY_BUCKETS)
201
- @ack_errors = Prometheus.registry.counter(:producer_ack_errors, 'Ack errors')
196
+ Prometheus.registry.histogram(:producer_deliver_latency, docstring: 'Delivery latency', buckets: LATENCY_BUCKETS, labels: [:client])
197
+ @deliver_messages = Prometheus.registry.counter(:producer_deliver_messages, docstring: 'Total count of delivered messages', labels: [:client])
198
+ @deliver_attempts = Prometheus.registry.histogram(:producer_deliver_attempts, docstring: 'Delivery attempts', labels: [:client])
199
+ @ack_messages = Prometheus.registry.counter(:producer_ack_messages, docstring: 'Ack', labels: [:client, :topic])
200
+ @ack_delay = Prometheus.registry.histogram(:producer_ack_delay, docstring: 'Ack delay', buckets: LATENCY_BUCKETS, labels: [:client, :topic])
201
+ @ack_errors = Prometheus.registry.counter(:producer_ack_errors, docstring: 'Ack errors', labels: [:client, :topic])
202
202
  end
203
203
 
204
204
  def produce_message(event)
@@ -212,20 +212,20 @@ module Kafka
212
212
  buffer_fill_percentage = buffer_fill_ratio * 100.0
213
213
 
214
214
  # This gets us the write rate.
215
- @produce_messages.increment(key)
216
- @produce_message_size.observe(key, message_size)
215
+ @produce_messages.increment(labels: key)
216
+ @produce_message_size.observe(message_size, labels: key)
217
217
 
218
218
  # This gets us the avg/max buffer size per producer.
219
- @buffer_size.observe({ client: client }, buffer_size)
219
+ @buffer_size.observe(buffer_size, labels: { client: client })
220
220
 
221
221
  # This gets us the avg/max buffer fill ratio per producer.
222
- @buffer_fill_ratio.observe({ client: client }, buffer_fill_ratio)
223
- @buffer_fill_percentage.observe({ client: client }, buffer_fill_percentage)
222
+ @buffer_fill_ratio.observe(buffer_fill_ratio, labels: { client: client })
223
+ @buffer_fill_percentage.observe(buffer_fill_percentage, labels: { client: client })
224
224
  end
225
225
 
226
226
  def buffer_overflow(event)
227
227
  key = { client: event.payload.fetch(:client_id), topic: event.payload.fetch(:topic) }
228
- @produce_errors.increment(key)
228
+ @produce_errors.increment(labels: key)
229
229
  end
230
230
 
231
231
  def deliver_messages(event)
@@ -233,40 +233,40 @@ module Kafka
233
233
  message_count = event.payload.fetch(:delivered_message_count)
234
234
  attempts = event.payload.fetch(:attempts)
235
235
 
236
- @deliver_errors.increment(key) if event.payload.key?(:exception)
237
- @deliver_latency.observe(key, event.duration)
236
+ @deliver_errors.increment(labels: key) if event.payload.key?(:exception)
237
+ @deliver_latency.observe(event.duration, labels: key)
238
238
 
239
239
  # Messages delivered to Kafka:
240
- @deliver_messages.increment(key, message_count)
240
+ @deliver_messages.increment(by: message_count, labels: key)
241
241
 
242
242
  # Number of attempts to deliver messages:
243
- @deliver_attempts.observe(key, attempts)
243
+ @deliver_attempts.observe(attempts, labels: key)
244
244
  end
245
245
 
246
246
  def ack_message(event)
247
247
  key = { client: event.payload.fetch(:client_id), topic: event.payload.fetch(:topic) }
248
248
 
249
249
  # Number of messages ACK'd for the topic.
250
- @ack_messages.increment(key)
250
+ @ack_messages.increment(labels: key)
251
251
 
252
252
  # Histogram of delay between a message being produced and it being ACK'd.
253
- @ack_delay.observe(key, event.payload.fetch(:delay))
253
+ @ack_delay.observe(event.payload.fetch(:delay), labels: key)
254
254
  end
255
255
 
256
256
  def topic_error(event)
257
257
  key = { client: event.payload.fetch(:client_id), topic: event.payload.fetch(:topic) }
258
258
 
259
- @ack_errors.increment(key)
259
+ @ack_errors.increment(labels: key)
260
260
  end
261
261
  end
262
262
 
263
263
  class AsyncProducerSubscriber < ActiveSupport::Subscriber
264
264
  def initialize
265
265
  super
266
- @queue_size = Prometheus.registry.histogram(:async_producer_queue_size, 'Queue size', {}, SIZE_BUCKETS)
267
- @queue_fill_ratio = Prometheus.registry.histogram(:async_producer_queue_fill_ratio, 'Queue fill ratio')
268
- @produce_errors = Prometheus.registry.counter(:async_producer_produce_errors, 'Producer errors')
269
- @dropped_messages = Prometheus.registry.counter(:async_producer_dropped_messages, 'Dropped messages')
266
+ @queue_size = Prometheus.registry.histogram(:async_producer_queue_size, docstring: 'Queue size', buckets: SIZE_BUCKETS, labels: [:client, :topic])
267
+ @queue_fill_ratio = Prometheus.registry.histogram(:async_producer_queue_fill_ratio, docstring: 'Queue fill ratio', labels: [:client, :topic])
268
+ @produce_errors = Prometheus.registry.counter(:async_producer_produce_errors, docstring: 'Producer errors', labels: [:client, :topic])
269
+ @dropped_messages = Prometheus.registry.counter(:async_producer_dropped_messages, docstring: 'Dropped messages', labels: [:client])
270
270
  end
271
271
 
272
272
  def enqueue_message(event)
@@ -277,29 +277,28 @@ module Kafka
277
277
  queue_fill_ratio = queue_size.to_f / max_queue_size.to_f
278
278
 
279
279
  # This gets us the avg/max queue size per producer.
280
- @queue_size.observe(key, queue_size)
280
+ @queue_size.observe(queue_size, labels: key)
281
281
 
282
282
  # This gets us the avg/max queue fill ratio per producer.
283
- @queue_fill_ratio.observe(key, queue_fill_ratio)
283
+ @queue_fill_ratio.observe(queue_fill_ratio, labels: key)
284
284
  end
285
285
 
286
286
  def buffer_overflow(event)
287
287
  key = { client: event.payload.fetch(:client_id), topic: event.payload.fetch(:topic) }
288
- @produce_errors.increment(key)
288
+ @produce_errors.increment(labels: key)
289
289
  end
290
290
 
291
291
  def drop_messages(event)
292
292
  key = { client: event.payload.fetch(:client_id) }
293
293
  message_count = event.payload.fetch(:message_count)
294
-
295
- @dropped_messages.increment(key, message_count)
294
+ @dropped_messages.increment(by: message_count, labels: key)
296
295
  end
297
296
  end
298
297
 
299
298
  class FetcherSubscriber < ActiveSupport::Subscriber
300
299
  def initialize
301
300
  super
302
- @queue_size = Prometheus.registry.gauge(:fetcher_queue_size, 'Queue size')
301
+ @queue_size = Prometheus.registry.gauge(:fetcher_queue_size, docstring: 'Queue size', labels: [:client, :group_id])
303
302
  end
304
303
 
305
304
  def loop(event)
@@ -307,7 +306,7 @@ module Kafka
307
306
  client = event.payload.fetch(:client_id)
308
307
  group_id = event.payload.fetch(:group_id)
309
308
 
310
- @queue_size.set({ client: client, group_id: group_id }, queue_size)
309
+ @queue_size.set(queue_size, labels: { client: client, group_id: group_id })
311
310
  end
312
311
  end
313
312
  end