karafka 2.5.5 → 2.5.7

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.
Files changed (215) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/LICENSE-COMM +4 -0
  4. data/README.md +2 -2
  5. data/certs/expired.txt +2 -0
  6. data/karafka.gemspec +23 -23
  7. data/lib/active_job/karafka.rb +2 -2
  8. data/lib/active_job/queue_adapters/karafka_adapter.rb +5 -5
  9. data/lib/karafka/active_job/consumer.rb +3 -3
  10. data/lib/karafka/active_job/current_attributes.rb +4 -4
  11. data/lib/karafka/active_job/job_options_contract.rb +2 -2
  12. data/lib/karafka/admin/acl.rb +3 -3
  13. data/lib/karafka/admin/configs/resource.rb +1 -1
  14. data/lib/karafka/admin/configs.rb +1 -1
  15. data/lib/karafka/admin/consumer_groups.rb +8 -8
  16. data/lib/karafka/admin/contracts/replication.rb +2 -2
  17. data/lib/karafka/admin/replication.rb +21 -21
  18. data/lib/karafka/admin/topics.rb +6 -6
  19. data/lib/karafka/admin.rb +4 -5
  20. data/lib/karafka/app.rb +3 -3
  21. data/lib/karafka/base_consumer.rb +34 -30
  22. data/lib/karafka/cli/base.rb +8 -8
  23. data/lib/karafka/cli/console.rb +1 -1
  24. data/lib/karafka/cli/contracts/server.rb +12 -12
  25. data/lib/karafka/cli/help.rb +2 -2
  26. data/lib/karafka/cli/info.rb +4 -4
  27. data/lib/karafka/cli/install.rb +11 -11
  28. data/lib/karafka/cli/server.rb +6 -6
  29. data/lib/karafka/cli/swarm.rb +1 -1
  30. data/lib/karafka/cli/topics/align.rb +4 -4
  31. data/lib/karafka/cli/topics/base.rb +5 -5
  32. data/lib/karafka/cli/topics/create.rb +2 -2
  33. data/lib/karafka/cli/topics/delete.rb +2 -2
  34. data/lib/karafka/cli/topics/help.rb +5 -1
  35. data/lib/karafka/cli/topics/plan.rb +16 -16
  36. data/lib/karafka/cli/topics/repartition.rb +3 -3
  37. data/lib/karafka/cli/topics.rb +22 -22
  38. data/lib/karafka/cli.rb +2 -2
  39. data/lib/karafka/connection/client.rb +17 -17
  40. data/lib/karafka/connection/listener.rb +6 -6
  41. data/lib/karafka/connection/mode.rb +1 -1
  42. data/lib/karafka/connection/proxy.rb +1 -1
  43. data/lib/karafka/connection/status.rb +2 -2
  44. data/lib/karafka/constraints.rb +3 -3
  45. data/lib/karafka/embedded.rb +3 -3
  46. data/lib/karafka/env.rb +4 -4
  47. data/lib/karafka/errors.rb +6 -1
  48. data/lib/karafka/execution_mode.rb +1 -1
  49. data/lib/karafka/helpers/config_importer.rb +2 -2
  50. data/lib/karafka/helpers/interval_runner.rb +4 -2
  51. data/lib/karafka/helpers/multi_delegator.rb +1 -1
  52. data/lib/karafka/instrumentation/assignments_tracker.rb +9 -9
  53. data/lib/karafka/instrumentation/callbacks/error.rb +5 -5
  54. data/lib/karafka/instrumentation/callbacks/oauthbearer_token_refresh.rb +4 -4
  55. data/lib/karafka/instrumentation/callbacks/rebalance.rb +6 -6
  56. data/lib/karafka/instrumentation/callbacks/statistics.rb +5 -5
  57. data/lib/karafka/instrumentation/logger.rb +7 -7
  58. data/lib/karafka/instrumentation/logger_listener.rb +76 -63
  59. data/lib/karafka/instrumentation/vendors/appsignal/base.rb +1 -1
  60. data/lib/karafka/instrumentation/vendors/appsignal/client.rb +1 -1
  61. data/lib/karafka/instrumentation/vendors/appsignal/errors_listener.rb +1 -1
  62. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +36 -36
  63. data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +33 -28
  64. data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +38 -38
  65. data/lib/karafka/instrumentation/vendors/kubernetes/base_listener.rb +5 -5
  66. data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +1 -1
  67. data/lib/karafka/instrumentation/vendors/kubernetes/swarm_liveness_listener.rb +1 -1
  68. data/lib/karafka/licenser.rb +115 -8
  69. data/lib/karafka/messages/builders/batch_metadata.rb +4 -2
  70. data/lib/karafka/messages/messages.rb +1 -1
  71. data/lib/karafka/patches/rdkafka/bindings.rb +2 -2
  72. data/lib/karafka/pro/active_job/job_options_contract.rb +2 -2
  73. data/lib/karafka/pro/cleaner/messages/messages.rb +10 -0
  74. data/lib/karafka/pro/cli/contracts/server.rb +12 -12
  75. data/lib/karafka/pro/cli/parallel_segments/base.rb +4 -4
  76. data/lib/karafka/pro/cli/parallel_segments/collapse.rb +5 -5
  77. data/lib/karafka/pro/cli/parallel_segments/distribute.rb +3 -3
  78. data/lib/karafka/pro/cli/parallel_segments.rb +7 -7
  79. data/lib/karafka/pro/cli/topics/health.rb +162 -0
  80. data/lib/karafka/pro/cli/topics.rb +52 -0
  81. data/lib/karafka/pro/connection/manager.rb +14 -14
  82. data/lib/karafka/pro/encryption/contracts/config.rb +2 -2
  83. data/lib/karafka/pro/encryption/messages/middleware.rb +2 -2
  84. data/lib/karafka/pro/encryption/messages/parser.rb +2 -2
  85. data/lib/karafka/pro/encryption/setup/config.rb +2 -2
  86. data/lib/karafka/pro/iterator/tpl_builder.rb +2 -2
  87. data/lib/karafka/pro/iterator.rb +1 -1
  88. data/lib/karafka/pro/loader.rb +2 -1
  89. data/lib/karafka/pro/processing/adaptive_iterator/consumer.rb +1 -1
  90. data/lib/karafka/pro/processing/coordinators/virtual_offset_manager.rb +24 -14
  91. data/lib/karafka/pro/processing/filters/base.rb +1 -1
  92. data/lib/karafka/pro/processing/filters/delayer.rb +2 -2
  93. data/lib/karafka/pro/processing/filters/inline_insights_delayer.rb +1 -1
  94. data/lib/karafka/pro/processing/offset_metadata/consumer.rb +1 -1
  95. data/lib/karafka/pro/processing/parallel_segments/filters/base.rb +6 -6
  96. data/lib/karafka/pro/processing/partitioner.rb +3 -3
  97. data/lib/karafka/pro/processing/periodic_job/consumer.rb +6 -5
  98. data/lib/karafka/pro/processing/piping/consumer.rb +7 -7
  99. data/lib/karafka/pro/processing/schedulers/base.rb +5 -5
  100. data/lib/karafka/pro/processing/schedulers/default.rb +5 -5
  101. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +6 -3
  102. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +6 -3
  103. data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +6 -3
  104. data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +2 -2
  105. data/lib/karafka/pro/processing/strategies/default.rb +22 -22
  106. data/lib/karafka/pro/processing/strategies/dlq/default.rb +7 -7
  107. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +6 -3
  108. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +6 -3
  109. data/lib/karafka/pro/processing/strategies/ftr/default.rb +2 -2
  110. data/lib/karafka/pro/processing/strategies/lrj/default.rb +2 -2
  111. data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +6 -3
  112. data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +6 -3
  113. data/lib/karafka/pro/processing/strategies/lrj/mom.rb +2 -2
  114. data/lib/karafka/pro/recurring_tasks/consumer.rb +2 -2
  115. data/lib/karafka/pro/recurring_tasks/contracts/config.rb +2 -2
  116. data/lib/karafka/pro/recurring_tasks/contracts/task.rb +2 -2
  117. data/lib/karafka/pro/recurring_tasks/dispatcher.rb +2 -2
  118. data/lib/karafka/pro/recurring_tasks/listener.rb +1 -1
  119. data/lib/karafka/pro/recurring_tasks/matcher.rb +2 -2
  120. data/lib/karafka/pro/recurring_tasks/serializer.rb +5 -5
  121. data/lib/karafka/pro/recurring_tasks/setup/config.rb +3 -3
  122. data/lib/karafka/pro/recurring_tasks/task.rb +4 -4
  123. data/lib/karafka/pro/recurring_tasks.rb +4 -4
  124. data/lib/karafka/pro/routing/features/adaptive_iterator/contracts/topic.rb +2 -2
  125. data/lib/karafka/pro/routing/features/dead_letter_queue/contracts/topic.rb +2 -2
  126. data/lib/karafka/pro/routing/features/dead_letter_queue/topic.rb +1 -1
  127. data/lib/karafka/pro/routing/features/delaying/contracts/topic.rb +2 -2
  128. data/lib/karafka/pro/routing/features/direct_assignments/contracts/consumer_group.rb +2 -2
  129. data/lib/karafka/pro/routing/features/direct_assignments/contracts/topic.rb +2 -2
  130. data/lib/karafka/pro/routing/features/direct_assignments/topic.rb +1 -1
  131. data/lib/karafka/pro/routing/features/expiring/contracts/topic.rb +2 -2
  132. data/lib/karafka/pro/routing/features/filtering/contracts/topic.rb +2 -2
  133. data/lib/karafka/pro/routing/features/inline_insights/contracts/topic.rb +2 -2
  134. data/lib/karafka/pro/routing/features/long_running_job/contracts/topic.rb +2 -2
  135. data/lib/karafka/pro/routing/features/long_running_job/topic.rb +1 -1
  136. data/lib/karafka/pro/routing/features/multiplexing/contracts/topic.rb +2 -2
  137. data/lib/karafka/pro/routing/features/multiplexing.rb +5 -5
  138. data/lib/karafka/pro/routing/features/non_blocking_job/topic.rb +1 -1
  139. data/lib/karafka/pro/routing/features/offset_metadata/contracts/topic.rb +2 -2
  140. data/lib/karafka/pro/routing/features/offset_metadata/topic.rb +1 -1
  141. data/lib/karafka/pro/routing/features/offset_metadata.rb +1 -1
  142. data/lib/karafka/pro/routing/features/parallel_segments/consumer_group.rb +5 -5
  143. data/lib/karafka/pro/routing/features/parallel_segments/contracts/consumer_group.rb +2 -2
  144. data/lib/karafka/pro/routing/features/patterns/contracts/consumer_group.rb +2 -2
  145. data/lib/karafka/pro/routing/features/patterns/contracts/pattern.rb +3 -3
  146. data/lib/karafka/pro/routing/features/patterns/contracts/topic.rb +2 -2
  147. data/lib/karafka/pro/routing/features/patterns/topic.rb +1 -1
  148. data/lib/karafka/pro/routing/features/pausing/contracts/topic.rb +2 -2
  149. data/lib/karafka/pro/routing/features/periodic_job/contracts/topic.rb +2 -2
  150. data/lib/karafka/pro/routing/features/periodic_job/topic.rb +1 -1
  151. data/lib/karafka/pro/routing/features/recurring_tasks/builder.rb +7 -7
  152. data/lib/karafka/pro/routing/features/recurring_tasks/contracts/topic.rb +2 -2
  153. data/lib/karafka/pro/routing/features/scheduled_messages/builder.rb +13 -13
  154. data/lib/karafka/pro/routing/features/scheduled_messages/contracts/topic.rb +2 -2
  155. data/lib/karafka/pro/routing/features/swarm/contracts/routing.rb +2 -2
  156. data/lib/karafka/pro/routing/features/swarm/contracts/topic.rb +2 -2
  157. data/lib/karafka/pro/routing/features/swarm.rb +1 -1
  158. data/lib/karafka/pro/routing/features/throttling/contracts/topic.rb +2 -2
  159. data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +7 -7
  160. data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +2 -2
  161. data/lib/karafka/pro/scheduled_messages/consumer.rb +4 -4
  162. data/lib/karafka/pro/scheduled_messages/contracts/config.rb +2 -2
  163. data/lib/karafka/pro/scheduled_messages/contracts/message.rb +10 -10
  164. data/lib/karafka/pro/scheduled_messages/daily_buffer.rb +2 -2
  165. data/lib/karafka/pro/scheduled_messages/deserializers/headers.rb +4 -4
  166. data/lib/karafka/pro/scheduled_messages/dispatcher.rb +5 -5
  167. data/lib/karafka/pro/scheduled_messages/proxy.rb +8 -8
  168. data/lib/karafka/pro/scheduled_messages/schema_validator.rb +1 -1
  169. data/lib/karafka/pro/scheduled_messages/setup/config.rb +2 -2
  170. data/lib/karafka/pro/scheduled_messages/state.rb +1 -1
  171. data/lib/karafka/pro/scheduled_messages/tracker.rb +2 -2
  172. data/lib/karafka/pro/scheduled_messages.rb +2 -2
  173. data/lib/karafka/pro/swarm/liveness_listener.rb +2 -2
  174. data/lib/karafka/process.rb +1 -1
  175. data/lib/karafka/processing/coordinator.rb +1 -1
  176. data/lib/karafka/processing/inline_insights/consumer.rb +4 -4
  177. data/lib/karafka/processing/inline_insights/tracker.rb +6 -6
  178. data/lib/karafka/processing/jobs/base.rb +6 -4
  179. data/lib/karafka/processing/jobs_queue.rb +10 -0
  180. data/lib/karafka/processing/schedulers/default.rb +4 -4
  181. data/lib/karafka/processing/strategies/base.rb +6 -6
  182. data/lib/karafka/processing/strategies/default.rb +13 -13
  183. data/lib/karafka/processing/strategies/dlq.rb +1 -1
  184. data/lib/karafka/processing/worker.rb +5 -5
  185. data/lib/karafka/railtie.rb +11 -11
  186. data/lib/karafka/routing/builder.rb +3 -3
  187. data/lib/karafka/routing/contracts/consumer_group.rb +6 -6
  188. data/lib/karafka/routing/contracts/routing.rb +2 -2
  189. data/lib/karafka/routing/contracts/topic.rb +4 -4
  190. data/lib/karafka/routing/features/active_job/contracts/topic.rb +3 -3
  191. data/lib/karafka/routing/features/base/expander.rb +4 -4
  192. data/lib/karafka/routing/features/base.rb +8 -8
  193. data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +2 -2
  194. data/lib/karafka/routing/features/declaratives/contracts/topic.rb +2 -2
  195. data/lib/karafka/routing/features/deserializers/contracts/topic.rb +2 -2
  196. data/lib/karafka/routing/features/eofed/contracts/topic.rb +3 -3
  197. data/lib/karafka/routing/features/inline_insights/contracts/topic.rb +2 -2
  198. data/lib/karafka/routing/features/inline_insights.rb +7 -7
  199. data/lib/karafka/routing/features/manual_offset_management/contracts/topic.rb +2 -2
  200. data/lib/karafka/routing/subscription_group.rb +9 -9
  201. data/lib/karafka/runner.rb +3 -3
  202. data/lib/karafka/server.rb +14 -5
  203. data/lib/karafka/setup/attributes_map.rb +7 -7
  204. data/lib/karafka/setup/config.rb +11 -11
  205. data/lib/karafka/setup/contracts/config.rb +2 -2
  206. data/lib/karafka/setup/defaults_injector.rb +11 -11
  207. data/lib/karafka/swarm/manager.rb +6 -6
  208. data/lib/karafka/swarm/node.rb +8 -37
  209. data/lib/karafka/swarm/producer_replacer.rb +110 -0
  210. data/lib/karafka/swarm/supervisor.rb +9 -6
  211. data/lib/karafka/swarm.rb +1 -1
  212. data/lib/karafka/time_trackers/pause.rb +1 -1
  213. data/lib/karafka/version.rb +1 -1
  214. data/lib/karafka.rb +36 -36
  215. metadata +7 -3
@@ -23,14 +23,14 @@ module Karafka
23
23
  #
24
24
  # @param tpl [Rdkafka::Consumer::TopicPartitionList]
25
25
  def on_partitions_revoke(tpl)
26
- instrument('partitions_revoke', tpl)
26
+ instrument("partitions_revoke", tpl)
27
27
  end
28
28
 
29
29
  # Publishes an event that partitions are going to be assigned
30
30
  #
31
31
  # @param tpl [Rdkafka::Consumer::TopicPartitionList]
32
32
  def on_partitions_assign(tpl)
33
- instrument('partitions_assign', tpl)
33
+ instrument("partitions_assign", tpl)
34
34
  end
35
35
 
36
36
  # Publishes an event that partitions were revoked. This is after we've lost them, so no
@@ -38,14 +38,14 @@ module Karafka
38
38
  #
39
39
  # @param tpl [Rdkafka::Consumer::TopicPartitionList]
40
40
  def on_partitions_revoked(tpl)
41
- instrument('partitions_revoked', tpl)
41
+ instrument("partitions_revoked", tpl)
42
42
  end
43
43
 
44
44
  # Publishes an event that partitions were assigned.
45
45
  #
46
46
  # @param tpl [Rdkafka::Consumer::TopicPartitionList]
47
47
  def on_partitions_assigned(tpl)
48
- instrument('partitions_assigned', tpl)
48
+ instrument("partitions_assigned", tpl)
49
49
  end
50
50
 
51
51
  private
@@ -67,9 +67,9 @@ module Karafka
67
67
  client_id: @client_id,
68
68
  tpl: tpl
69
69
  )
70
- rescue StandardError => e
70
+ rescue => e
71
71
  monitor.instrument(
72
- 'error.occurred',
72
+ "error.occurred",
73
73
  caller: self,
74
74
  subscription_group_id: @subscription_group.id,
75
75
  consumer_group_id: @subscription_group.consumer_group.id,
@@ -28,10 +28,10 @@ module Karafka
28
28
  # rdkafka does not have per-instance statistics hook, thus we need to make sure that we
29
29
  # emit only stats that are related to current producer. Otherwise we would emit all of
30
30
  # all the time.
31
- return unless @client_name == statistics['name']
31
+ return unless @client_name == statistics["name"]
32
32
 
33
33
  monitor.instrument(
34
- 'statistics.emitted',
34
+ "statistics.emitted",
35
35
  subscription_group_id: @subscription_group_id,
36
36
  consumer_group_id: @consumer_group_id,
37
37
  statistics: @statistics_decorator.call(statistics)
@@ -39,13 +39,13 @@ module Karafka
39
39
  # We need to catch and handle any potential errors coming from the instrumentation pipeline
40
40
  # as otherwise, in case of statistics which run in the main librdkafka thread, any crash
41
41
  # will hang the whole process.
42
- rescue StandardError => e
42
+ rescue => e
43
43
  monitor.instrument(
44
- 'error.occurred',
44
+ "error.occurred",
45
45
  caller: self,
46
46
  subscription_group_id: @subscription_group_id,
47
47
  consumer_group_id: @consumer_group_id,
48
- type: 'callbacks.statistics.error',
48
+ type: "callbacks.statistics.error",
49
49
  error: e
50
50
  )
51
51
  end
@@ -7,11 +7,11 @@ module Karafka
7
7
  class Logger < ::Logger
8
8
  # Map containing information about log level for given environment
9
9
  ENV_MAP = {
10
- 'production' => Logger::ERROR,
11
- 'test' => Logger::ERROR,
12
- 'development' => Logger::INFO,
13
- 'debug' => Logger::DEBUG,
14
- 'default' => Logger::INFO
10
+ "production" => Logger::ERROR,
11
+ "test" => Logger::ERROR,
12
+ "development" => Logger::INFO,
13
+ "debug" => Logger::DEBUG,
14
+ "default" => Logger::INFO
15
15
  }.freeze
16
16
 
17
17
  private_constant :ENV_MAP
@@ -21,7 +21,7 @@ module Karafka
21
21
  # make this logger compatible with the default Ruby one
22
22
  def initialize(*_args)
23
23
  super(target)
24
- self.level = ENV_MAP[Karafka.env] || ENV_MAP['default']
24
+ self.level = ENV_MAP[Karafka.env] || ENV_MAP["default"]
25
25
  end
26
26
 
27
27
  private
@@ -45,7 +45,7 @@ module Karafka
45
45
  def file
46
46
  FileUtils.mkdir_p(File.dirname(log_path))
47
47
 
48
- @file ||= File.open(log_path, 'a')
48
+ @file ||= File.open(log_path, "a")
49
49
  rescue Errno::EACCES, Errno::EROFS
50
50
  nil
51
51
  end
@@ -29,7 +29,7 @@ module Karafka
29
29
  listener_id = event[:caller].id
30
30
  subscription_group = event[:subscription_group]
31
31
  consumer_group_id = subscription_group.consumer_group.id
32
- topics = subscription_group.topics.select(&:active?).map(&:name).join(', ')
32
+ topics = subscription_group.topics.select(&:active?).map(&:name).join(", ")
33
33
  group_details = "#{consumer_group_id}/#{subscription_group.id}"
34
34
 
35
35
  info(
@@ -70,7 +70,7 @@ module Karafka
70
70
  # @param event [Karafka::Core::Monitoring::Event] event details including payload
71
71
  def on_worker_process(event)
72
72
  job = event[:job]
73
- job_type = job.class.to_s.split('::').last
73
+ job_type = job.class.to_s.split("::").last
74
74
  consumer = job.executor.topic.consumer
75
75
  topic = job.executor.topic.name
76
76
  partition = job.executor.partition
@@ -83,11 +83,11 @@ module Karafka
83
83
  def on_worker_processed(event)
84
84
  job = event[:job]
85
85
  time = event[:time].round(2)
86
- job_type = job.class.to_s.split('::').last
86
+ job_type = job.class.to_s.split("::").last
87
87
  consumer = job.executor.topic.consumer
88
88
  topic = job.executor.topic.name
89
89
  partition = job.executor.partition
90
- info <<~MSG.tr("\n", ' ').strip!
90
+ info <<~MSG.tr("\n", " ").strip!
91
91
  [#{job.id}] #{job_type} job for #{consumer}
92
92
  on #{topic}-#{partition} finished in #{time} ms
93
93
  MSG
@@ -104,10 +104,10 @@ module Karafka
104
104
  offset = event[:offset]
105
105
  client = event[:caller]
106
106
 
107
- info <<~MSG.tr("\n", ' ').strip!
107
+ info <<~MSG.tr("\n", " ").strip!
108
108
  [#{client.id}]
109
109
  Pausing on topic #{topic}-#{partition}
110
- on #{offset ? "offset #{offset}" : 'the consecutive offset'}
110
+ on #{offset ? "offset #{offset}" : "the consecutive offset"}
111
111
  MSG
112
112
  end
113
113
 
@@ -119,7 +119,7 @@ module Karafka
119
119
  partition = event[:partition]
120
120
  client = event[:caller]
121
121
 
122
- info <<~MSG.tr("\n", ' ').strip!
122
+ info <<~MSG.tr("\n", " ").strip!
123
123
  [#{client.id}] Resuming on topic #{topic}-#{partition}
124
124
  MSG
125
125
  end
@@ -134,7 +134,7 @@ module Karafka
134
134
  consumer = event[:caller]
135
135
  timeout = event[:timeout]
136
136
 
137
- info <<~MSG.tr("\n", ' ').strip!
137
+ info <<~MSG.tr("\n", " ").strip!
138
138
  [#{consumer.id}] Retrying of #{consumer.class} after #{timeout} ms
139
139
  on topic #{topic}-#{partition} from offset #{offset}
140
140
  MSG
@@ -149,7 +149,7 @@ module Karafka
149
149
  seek_offset = event[:message].offset
150
150
  consumer = event[:caller]
151
151
 
152
- info <<~MSG.tr("\n", ' ').strip!
152
+ info <<~MSG.tr("\n", " ").strip!
153
153
  [#{consumer.id}] Seeking from #{consumer.class}
154
154
  on topic #{topic}-#{partition} to offset #{seek_offset}
155
155
  MSG
@@ -170,13 +170,13 @@ module Karafka
170
170
  Thread.list.each do |thread|
171
171
  tid = (thread.object_id ^ ::Process.pid).to_s(36)
172
172
 
173
- warn ''
173
+ warn ""
174
174
  warn "Thread TID-#{tid} #{thread.name}"
175
175
 
176
176
  if thread.backtrace && !thread.backtrace.empty?
177
177
  warn thread.backtrace.join("\n")
178
178
  else
179
- warn '<no backtrace available>'
179
+ warn "<no backtrace available>"
180
180
  end
181
181
  end
182
182
  end
@@ -232,7 +232,7 @@ module Karafka
232
232
  info "#{group_prefix}: No partitions revoked"
233
233
  else
234
234
  revoked_partitions.each do |topic, partitions|
235
- info "#{group_prefix}: #{topic}-[#{partitions.join(',')}] revoked"
235
+ info "#{group_prefix}: #{topic}-[#{partitions.join(",")}] revoked"
236
236
  end
237
237
  end
238
238
  end
@@ -250,7 +250,7 @@ module Karafka
250
250
  info "#{group_prefix}: No partitions assigned"
251
251
  else
252
252
  assigned_partitions.each do |topic, partitions|
253
- info "#{group_prefix}: #{topic}-[#{partitions.join(',')}] assigned"
253
+ info "#{group_prefix}: #{topic}-[#{partitions.join(",")}] assigned"
254
254
  end
255
255
  end
256
256
  end
@@ -266,7 +266,7 @@ module Karafka
266
266
  dlq_topic = consumer.topic.dead_letter_queue.topic
267
267
  partition = message.partition
268
268
 
269
- info <<~MSG.tr("\n", ' ').strip!
269
+ info <<~MSG.tr("\n", " ").strip!
270
270
  [#{consumer.id}] Dispatched message #{offset}
271
271
  from #{topic}-#{partition}
272
272
  to DLQ topic: #{dlq_topic}
@@ -284,7 +284,7 @@ module Karafka
284
284
  partition = message.partition
285
285
  offset = message.offset
286
286
 
287
- info <<~MSG.tr("\n", ' ').strip!
287
+ info <<~MSG.tr("\n", " ").strip!
288
288
  [#{consumer.id}] Throttled and will resume
289
289
  from message #{offset}
290
290
  on #{topic}-#{partition}
@@ -300,7 +300,7 @@ module Karafka
300
300
  partition = message.partition
301
301
  offset = message.offset
302
302
 
303
- info <<~MSG.tr("\n", ' ').strip!
303
+ info <<~MSG.tr("\n", " ").strip!
304
304
  [#{consumer.id}] Post-filtering seeking to message #{offset}
305
305
  on #{topic}-#{partition}
306
306
  MSG
@@ -330,7 +330,7 @@ module Karafka
330
330
 
331
331
  # @param event [Karafka::Core::Monitoring::Event] event details including payload
332
332
  def on_swarm_manager_control(event)
333
- pids = event[:caller].nodes.map(&:pid).join(', ')
333
+ pids = event[:caller].nodes.map(&:pid).join(", ")
334
334
  debug "Swarm manager checking nodes: #{pids}"
335
335
  end
336
336
 
@@ -342,97 +342,110 @@ module Karafka
342
342
  error = event[:error]
343
343
  backtrace = (error.backtrace || []).join("\n")
344
344
 
345
- details = [error.to_s, error_details(event)].compact.join(' ')
345
+ details = [error.to_s, error_details(event)].compact.join(" ")
346
346
 
347
347
  case type
348
- when 'consumer.initialized.error'
348
+ when "consumer.initialized.error"
349
349
  error "Consumer initialized error: #{details}"
350
350
  error backtrace
351
- when 'consumer.wrap.error'
351
+ when "consumer.wrap.error"
352
352
  error "Consumer wrap failed due to an error: #{details}"
353
353
  error backtrace
354
- when 'consumer.consume.error'
354
+ when "consumer.consume.error"
355
355
  error "Consumer consuming error: #{details}"
356
356
  error backtrace
357
- when 'consumer.revoked.error'
357
+ when "consumer.revoked.error"
358
358
  error "Consumer on revoked failed due to an error: #{details}"
359
359
  error backtrace
360
- when 'consumer.idle.error'
360
+ when "consumer.idle.error"
361
361
  error "Consumer idle failed due to an error: #{details}"
362
362
  error backtrace
363
- when 'consumer.shutdown.error'
363
+ when "consumer.shutdown.error"
364
364
  error "Consumer on shutdown failed due to an error: #{details}"
365
365
  error backtrace
366
- when 'consumer.tick.error'
366
+ when "consumer.tick.error"
367
367
  error "Consumer on tick failed due to an error: #{details}"
368
368
  error backtrace
369
- when 'consumer.eofed.error'
369
+ when "consumer.eofed.error"
370
370
  error "Consumer on eofed failed due to an error: #{details}"
371
371
  error backtrace
372
- when 'consumer.after_consume.error'
372
+ when "consumer.after_consume.error"
373
373
  error "Consumer on after_consume failed due to an error: #{details}"
374
374
  error backtrace
375
- when 'worker.process.error'
375
+ when "worker.process.error"
376
376
  fatal "Worker processing failed due to an error: #{details}"
377
377
  fatal backtrace
378
- when 'connection.listener.fetch_loop.error'
378
+ when "connection.listener.fetch_loop.error"
379
379
  error "Listener fetch loop error: #{details}"
380
380
  error backtrace
381
- when 'swarm.supervisor.error'
381
+ when "swarm.supervisor.error"
382
382
  fatal "Swarm supervisor crashed due to an error: #{details}"
383
383
  fatal backtrace
384
- when 'runner.call.error'
384
+ when "runner.call.error"
385
385
  fatal "Runner crashed due to an error: #{details}"
386
386
  fatal backtrace
387
- when 'app.stopping.error'
388
- # Counts number of workers and listeners that were still active when forcing the
389
- # shutdown. Please note, that unless all listeners are closed, workers will not finalize
390
- # their operations as well.
391
- # We need to check if listeners and workers are assigned as during super early stages of
392
- # boot they are not.
393
- listeners = Server.listeners ? Server.listeners.count(&:active?) : 0
394
- workers = Server.workers ? Server.workers.count(&:alive?) : 0
395
-
396
- message = <<~MSG.tr("\n", ' ').strip!
387
+ when "app.stopping.error"
388
+ active_listeners = event.payload[:active_listeners]
389
+ alive_workers = event.payload[:alive_workers]
390
+ in_processing = event.payload[:in_processing]
391
+
392
+ message = <<~MSG.tr("\n", " ").strip!
397
393
  Forceful Karafka server stop with:
398
- #{workers} active workers and
399
- #{listeners} active listeners
394
+ #{alive_workers.size} active workers and
395
+ #{active_listeners.size} active listeners
400
396
  MSG
401
397
 
402
398
  error message
403
- when 'app.forceful_stopping.error'
399
+
400
+ active_listeners.each do |listener|
401
+ error "Listener #{listener.id} for #{listener.subscription_group.name} still active"
402
+ end
403
+
404
+ in_processing.each do |group_id, jobs|
405
+ next if jobs.empty?
406
+
407
+ jobs.each do |job|
408
+ job_class = job.class.name.split("::").last
409
+ topic_name = job.executor.topic.name
410
+ partition = job.executor.partition
411
+
412
+ error "In processing: #{job_class} job for #{topic_name}/#{partition} " \
413
+ "(group: #{group_id})"
414
+ end
415
+ end
416
+ when "app.forceful_stopping.error"
404
417
  error "Forceful shutdown error occurred: #{details}"
405
418
  error backtrace
406
- when 'librdkafka.error'
419
+ when "librdkafka.error"
407
420
  error "librdkafka internal error occurred: #{details}"
408
421
  error backtrace
409
422
  # Those can occur when emitted statistics are consumed by the end user and the processing
410
423
  # of statistics fails. The statistics are emitted from librdkafka main loop thread and
411
424
  # any errors there crash the whole thread
412
- when 'callbacks.statistics.error'
425
+ when "callbacks.statistics.error"
413
426
  error "callbacks.statistics processing failed due to an error: #{details}"
414
427
  error backtrace
415
- when 'callbacks.error.error'
428
+ when "callbacks.error.error"
416
429
  error "callbacks.error processing failed due to an error: #{details}"
417
430
  error backtrace
418
431
  # Those will only occur when retries in the client fail and when they did not stop after
419
432
  # back-offs
420
- when 'connection.client.poll.error'
433
+ when "connection.client.poll.error"
421
434
  error "Data polling error occurred: #{details}"
422
435
  error backtrace
423
- when 'connection.client.rebalance_callback.error'
436
+ when "connection.client.rebalance_callback.error"
424
437
  error "Rebalance callback error occurred: #{details}"
425
438
  error backtrace
426
- when 'connection.client.unsubscribe.error'
439
+ when "connection.client.unsubscribe.error"
427
440
  error "Client unsubscribe error occurred: #{details}"
428
441
  error backtrace
429
- when 'parallel_segments.reducer.error'
442
+ when "parallel_segments.reducer.error"
430
443
  error "Parallel segments reducer error occurred: #{details}"
431
444
  error backtrace
432
- when 'parallel_segments.partitioner.error'
445
+ when "parallel_segments.partitioner.error"
433
446
  error "Parallel segments partitioner error occurred: #{details}"
434
447
  error backtrace
435
- when 'virtual_partitions.partitioner.error'
448
+ when "virtual_partitions.partitioner.error"
436
449
  error "Virtual partitions partitioner error occurred: #{details}"
437
450
  error backtrace
438
451
  # This handles any custom errors coming from places like Web-UI, etc
@@ -465,19 +478,19 @@ module Karafka
465
478
  # Collect extra info if it was a consumer related error.
466
479
  # Those come from user code
467
480
  details = case caller_ref
468
- when Karafka::BaseConsumer
469
- extract_consumer_info(caller_ref)
470
- when Karafka::Connection::Client
471
- extract_client_info(caller_ref)
472
- when Karafka::Connection::Listener
473
- extract_listener_info(caller_ref)
474
- else
475
- {}
476
- end
481
+ when Karafka::BaseConsumer
482
+ extract_consumer_info(caller_ref)
483
+ when Karafka::Connection::Client
484
+ extract_client_info(caller_ref)
485
+ when Karafka::Connection::Listener
486
+ extract_listener_info(caller_ref)
487
+ else
488
+ {}
489
+ end
477
490
 
478
491
  return nil if details.empty?
479
492
 
480
- "[#{details.map { |label, value| "#{label}: #{value}" }.join(', ')}]"
493
+ "[#{details.map { |label, value| "#{label}: #{value}" }.join(", ")}]"
481
494
  end
482
495
 
483
496
  # @param consumer [::Karafka::BaseConsumer]
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'client'
3
+ require_relative "client"
4
4
 
5
5
  module Karafka
6
6
  module Instrumentation
@@ -148,7 +148,7 @@ module Karafka
148
148
  # compatibility checks.
149
149
  def version_4_or_newer?
150
150
  @version_4_or_newer ||=
151
- Gem::Version.new(::Appsignal::VERSION) >= Gem::Version.new('4.0.0')
151
+ Gem::Version.new(::Appsignal::VERSION) >= Gem::Version.new("4.0.0")
152
152
  end
153
153
  end
154
154
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
3
+ require_relative "base"
4
4
 
5
5
  module Karafka
6
6
  module Instrumentation
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
3
+ require_relative "base"
4
4
 
5
5
  module Karafka
6
6
  module Instrumentation
@@ -14,30 +14,30 @@ module Karafka
14
14
  # Value object for storing a single rdkafka metric publishing details
15
15
  RdKafkaMetric = Struct.new(:type, :scope, :name, :key_location)
16
16
 
17
- setting :namespace, default: 'karafka'
17
+ setting :namespace, default: "karafka"
18
18
 
19
19
  setting :client, default: Client.new
20
20
 
21
21
  setting :rd_kafka_metrics, default: [
22
22
  # Broker metrics
23
- RdKafkaMetric.new(:count, :brokers, 'requests_retries', 'txretries_d'),
24
- RdKafkaMetric.new(:count, :brokers, 'transmission_errors', 'txerrs_d'),
25
- RdKafkaMetric.new(:count, :brokers, 'receive_errors', 'rxerrs_d'),
26
- RdKafkaMetric.new(:count, :brokers, 'connection_connects', 'connects_d'),
27
- RdKafkaMetric.new(:count, :brokers, 'connection_disconnects', 'disconnects_d'),
28
- RdKafkaMetric.new(:gauge, :brokers, 'network_latency_avg', %w[rtt avg]),
29
- RdKafkaMetric.new(:gauge, :brokers, 'network_latency_p95', %w[rtt p95]),
30
- RdKafkaMetric.new(:gauge, :brokers, 'network_latency_p99', %w[rtt p99]),
23
+ RdKafkaMetric.new(:count, :brokers, "requests_retries", "txretries_d"),
24
+ RdKafkaMetric.new(:count, :brokers, "transmission_errors", "txerrs_d"),
25
+ RdKafkaMetric.new(:count, :brokers, "receive_errors", "rxerrs_d"),
26
+ RdKafkaMetric.new(:count, :brokers, "connection_connects", "connects_d"),
27
+ RdKafkaMetric.new(:count, :brokers, "connection_disconnects", "disconnects_d"),
28
+ RdKafkaMetric.new(:gauge, :brokers, "network_latency_avg", %w[rtt avg]),
29
+ RdKafkaMetric.new(:gauge, :brokers, "network_latency_p95", %w[rtt p95]),
30
+ RdKafkaMetric.new(:gauge, :brokers, "network_latency_p99", %w[rtt p99]),
31
31
 
32
32
  # Topics partitions metrics
33
- RdKafkaMetric.new(:gauge, :topics, 'consumer_lag', 'consumer_lag_stored'),
34
- RdKafkaMetric.new(:gauge, :topics, 'consumer_lag_delta', 'consumer_lag_stored_d')
33
+ RdKafkaMetric.new(:gauge, :topics, "consumer_lag", "consumer_lag_stored"),
34
+ RdKafkaMetric.new(:gauge, :topics, "consumer_lag_delta", "consumer_lag_stored_d")
35
35
  ].freeze
36
36
 
37
37
  # Metrics that sum values on topics levels and not on partition levels
38
38
  setting :aggregated_rd_kafka_metrics, default: [
39
39
  # Topic aggregated metrics
40
- RdKafkaMetric.new(:gauge, :topics, 'consumer_aggregated_lag', 'consumer_lag_stored')
40
+ RdKafkaMetric.new(:gauge, :topics, "consumer_aggregated_lag", "consumer_lag_stored")
41
41
  ].freeze
42
42
 
43
43
  configure
@@ -65,7 +65,7 @@ module Karafka
65
65
  def on_consumer_consume(event)
66
66
  consumer = event.payload[:caller]
67
67
 
68
- start_transaction(consumer, 'consume')
68
+ start_transaction(consumer, "consume")
69
69
 
70
70
  client.metadata = {
71
71
  batch_size: consumer.messages.size,
@@ -87,9 +87,9 @@ module Karafka
87
87
  metadata = messages.metadata
88
88
 
89
89
  with_multiple_resolutions(consumer) do |tags|
90
- count('consumer_messages', messages.size, tags)
91
- count('consumer_batches', 1, tags)
92
- gauge('consumer_offsets', metadata.last_offset, tags)
90
+ count("consumer_messages", messages.size, tags)
91
+ count("consumer_batches", 1, tags)
92
+ gauge("consumer_offsets", metadata.last_offset, tags)
93
93
  end
94
94
 
95
95
  stop_transaction
@@ -140,7 +140,7 @@ module Karafka
140
140
  consumer = event.payload[:caller]
141
141
 
142
142
  with_multiple_resolutions(consumer) do |tags|
143
- count('consumer_dead', 1, tags)
143
+ count("consumer_dead", 1, tags)
144
144
  end
145
145
  end
146
146
 
@@ -154,7 +154,7 @@ module Karafka
154
154
  consumer = event.payload[:caller]
155
155
 
156
156
  with_multiple_resolutions(consumer) do |tags|
157
- count('consumer_errors', 1, tags)
157
+ count("consumer_errors", 1, tags)
158
158
  end
159
159
  end
160
160
 
@@ -186,32 +186,32 @@ module Karafka
186
186
  # way from other places
187
187
  nil
188
188
  when :brokers
189
- statistics.fetch('brokers').each_value do |broker_statistics|
189
+ statistics.fetch("brokers").each_value do |broker_statistics|
190
190
  # Skip bootstrap nodes
191
191
  # Bootstrap nodes have nodeid -1, other nodes have positive
192
192
  # node ids
193
- next if broker_statistics['nodeid'] == -1
193
+ next if broker_statistics["nodeid"] == -1
194
194
 
195
195
  public_send(
196
196
  metric.type,
197
197
  metric.name,
198
198
  broker_statistics.dig(*metric.key_location),
199
199
  {
200
- broker: broker_statistics['nodename']
200
+ broker: broker_statistics["nodename"]
201
201
  }
202
202
  )
203
203
  end
204
204
  when :topics
205
- statistics.fetch('topics').each do |topic_name, topic_values|
206
- topic_values['partitions'].each do |partition_name, partition_statistics|
207
- next if partition_name == '-1'
205
+ statistics.fetch("topics").each do |topic_name, topic_values|
206
+ topic_values["partitions"].each do |partition_name, partition_statistics|
207
+ next if partition_name == "-1"
208
208
  # Skip until lag info is available
209
- next if partition_statistics['consumer_lag'] == -1
210
- next if partition_statistics['consumer_lag_stored'] == -1
209
+ next if partition_statistics["consumer_lag"] == -1
210
+ next if partition_statistics["consumer_lag_stored"] == -1
211
211
 
212
212
  # Skip if we do not own the fetch assignment
213
- next if partition_statistics['fetch_state'] == 'stopped'
214
- next if partition_statistics['fetch_state'] == 'none'
213
+ next if partition_statistics["fetch_state"] == "stopped"
214
+ next if partition_statistics["fetch_state"] == "none"
215
215
 
216
216
  public_send(
217
217
  metric.type,
@@ -236,14 +236,14 @@ module Karafka
236
236
  # @param consumer_group_id [String] cg in context which we operate
237
237
  def report_aggregated_topics_metrics(statistics, consumer_group_id)
238
238
  config.aggregated_rd_kafka_metrics.each do |metric|
239
- statistics.fetch('topics').each do |topic_name, topic_values|
239
+ statistics.fetch("topics").each do |topic_name, topic_values|
240
240
  sum = 0
241
241
 
242
- topic_values['partitions'].each do |partition_name, partition_statistics|
243
- next if partition_name == '-1'
242
+ topic_values["partitions"].each do |partition_name, partition_statistics|
243
+ next if partition_name == "-1"
244
244
  # Skip until lag info is available
245
- next if partition_statistics['consumer_lag'] == -1
246
- next if partition_statistics['consumer_lag_stored'] == -1
245
+ next if partition_statistics["consumer_lag"] == -1
246
+ next if partition_statistics["consumer_lag_stored"] == -1
247
247
 
248
248
  sum += partition_statistics.dig(*metric.key_location)
249
249
  end
@@ -330,8 +330,8 @@ module Karafka
330
330
  def minute_probe
331
331
  concurrency = Karafka::App.config.concurrency
332
332
 
333
- count('processes_count', 1, {})
334
- count('threads_count', concurrency, {})
333
+ count("processes_count", 1, {})
334
+ count("threads_count", concurrency, {})
335
335
  end
336
336
  end
337
337
  end