karafka-web 0.8.0 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +16 -0
  4. data/Gemfile.lock +19 -19
  5. data/docker-compose.yml +1 -1
  6. data/lib/karafka/web/config.rb +6 -0
  7. data/lib/karafka/web/contracts/config.rb +1 -0
  8. data/lib/karafka/web/installer.rb +6 -2
  9. data/lib/karafka/web/management/actions/enable.rb +5 -0
  10. data/lib/karafka/web/management/actions/extend_boot_file.rb +3 -1
  11. data/lib/karafka/web/management/migrations/1706607960_introduce_lag_total_in_metrics.rb +38 -0
  12. data/lib/karafka/web/management/migrations/1706607960_introduce_lag_total_in_states.rb +22 -0
  13. data/lib/karafka/web/management/migrations/1706611396_rename_lag_total_to_lag_hybrid_in_metrics.rb +36 -0
  14. data/lib/karafka/web/management/migrations/1706611396_rename_lag_total_to_lag_hybrid_in_states.rb +21 -0
  15. data/lib/karafka/web/processing/consumers/aggregators/metrics.rb +7 -9
  16. data/lib/karafka/web/processing/consumers/aggregators/state.rb +8 -9
  17. data/lib/karafka/web/processing/consumers/contracts/aggregated_stats.rb +1 -2
  18. data/lib/karafka/web/processing/consumers/contracts/topic_stats.rb +1 -2
  19. data/lib/karafka/web/tracking/consumers/contracts/subscription_group.rb +1 -1
  20. data/lib/karafka/web/tracking/consumers/listeners/booting.rb +34 -0
  21. data/lib/karafka/web/tracking/consumers/sampler.rb +8 -2
  22. data/lib/karafka/web/tracking/producers/listeners/booting.rb +24 -0
  23. data/lib/karafka/web/tracking/scheduler.rb +0 -5
  24. data/lib/karafka/web/ui/controllers/consumers.rb +1 -1
  25. data/lib/karafka/web/ui/helpers/application_helper.rb +2 -0
  26. data/lib/karafka/web/ui/models/metrics/charts/topics.rb +5 -5
  27. data/lib/karafka/web/ui/models/partition.rb +22 -0
  28. data/lib/karafka/web/ui/models/process.rb +10 -12
  29. data/lib/karafka/web/ui/pro/app.rb +4 -0
  30. data/lib/karafka/web/ui/pro/controllers/consumers.rb +10 -4
  31. data/lib/karafka/web/ui/pro/controllers/health.rb +12 -0
  32. data/lib/karafka/web/ui/pro/views/consumers/_consumer.erb +1 -1
  33. data/lib/karafka/web/ui/pro/views/consumers/_counters.erb +2 -2
  34. data/lib/karafka/web/ui/pro/views/consumers/consumer/_partition.erb +3 -3
  35. data/lib/karafka/web/ui/pro/views/consumers/consumer/_subscription_group.erb +9 -3
  36. data/lib/karafka/web/ui/pro/views/consumers/index.erb +1 -1
  37. data/lib/karafka/web/ui/pro/views/consumers/subscriptions.erb +11 -11
  38. data/lib/karafka/web/ui/pro/views/dashboard/index.erb +3 -3
  39. data/lib/karafka/web/ui/pro/views/health/_breadcrumbs.erb +8 -0
  40. data/lib/karafka/web/ui/pro/views/health/_consumer_group_header.erb +14 -0
  41. data/lib/karafka/web/ui/pro/views/health/_partition.erb +1 -9
  42. data/lib/karafka/web/ui/pro/views/health/_partition_lags.erb +24 -0
  43. data/lib/karafka/web/ui/pro/views/health/_partition_offset.erb +1 -1
  44. data/lib/karafka/web/ui/pro/views/health/_tabs.erb +9 -0
  45. data/lib/karafka/web/ui/pro/views/health/changes.erb +3 -17
  46. data/lib/karafka/web/ui/pro/views/health/lags.erb +52 -0
  47. data/lib/karafka/web/ui/pro/views/health/offsets.erb +4 -17
  48. data/lib/karafka/web/ui/pro/views/health/overview.erb +4 -19
  49. data/lib/karafka/web/ui/views/consumers/_counters.erb +2 -2
  50. data/lib/karafka/web/ui/views/consumers/index.erb +1 -1
  51. data/lib/karafka/web/ui/views/dashboard/index.erb +3 -3
  52. data/lib/karafka/web/version.rb +1 -1
  53. data/lib/karafka/web.rb +2 -1
  54. data.tar.gz.sig +0 -0
  55. metadata +11 -2
  56. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 446dcc1a42f38d364747702c52aeefbdede83b203eb13bfa755c8e2e1f05438e
4
- data.tar.gz: 20e7cc3cb0b400b382715b184db667d4791aeb0d626b4e9c6af7b314394d3309
3
+ metadata.gz: 457da6c2e847225be5d27f3a30fcf8f99a4a132f8109204315ac042e24d1bd35
4
+ data.tar.gz: c277f44c30a34ee2748ac4e9b56833814b522da87f6cc1841d21aca618af58be
5
5
  SHA512:
6
- metadata.gz: f2ecb81d1dd77b5dc1c9feaa75dc1f262335da4a812785035c0ca85fdf5e1413cefa724a73b13032908d3fc02e52096140ee89eae18ca7d933193c1ed7ddc011
7
- data.tar.gz: 59c4a2324ee277cb61c197ffa190da2e59bb594d8c615296074a5f144b3a9d6ef3ebd31a70e37ab687e7c1a872f9efc9624b24400eb2a44be1034e0901d74586
6
+ metadata.gz: 9ff1df82abd7f4f9f7002ae8a9e3e4e3fef2a71fbac820ff700d52c1926a5a81bf8e141ac6b928693d6276d8c16ef496efc11cada7574da217f4fb31efe31b5b
7
+ data.tar.gz: 3f39b8155794c25a39464d71c35f33ee82e6b59f92b55301f20ff69f1c58bc2cdf32af976720c548c2262893e25e0f8c8d31b8c033a248feb929bd088bc46d6c
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Karafka Web changelog
2
2
 
3
+ ## 0.8.2 (2024-02-16)
4
+ - [Enhancement] Defer scheduler background thread creation until needed allowing for forks.
5
+ - [Enhancement] Tag forks with fork indication + ppid reference when operating in swarm.
6
+ - [Fix] Fix issue where Health tabs would not be visible when no data reported.
7
+ - [Fix] Stopped processes subscriptions lacks indicator of no groups.
8
+ - [Fix] Terminated process state not supported in the web ui.
9
+ - [Fix] Rebalance reason can be empty on a SG when no network.
10
+
11
+ ## 0.8.1 (2024-02-01)
12
+ - [Enhancement] Introduce "Lags" health view.
13
+ - [Enhancement] Remove "Stored Lag" and "Committed Offset" from Health Overview due to Lags Tab.
14
+ - [Enhancement] Report lag on consumers that did not yet marked offsets.
15
+ - [Enhancement] Use more accurate lag reporting that compensates for lack of stored lag.
16
+ - [Fix] When first message after process start is crashed without DLQ lag is not reported.
17
+ - [Fix] Wrong order of enabled injection causes fresh install to crash.
18
+
3
19
  ## 0.8.0 (2024-01-26)
4
20
  - **[Feature]** Provide ability to sort table data for part of the views (note: not all attributes can be sorted due to technical limitations of sub-components fetching from Kafka).
5
21
  - **[Feature]** Track and report pause timeouts via "Changes" view in Health.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- karafka-web (0.8.0)
4
+ karafka-web (0.8.2)
5
5
  erubi (~> 1.4)
6
6
  karafka (>= 2.3.0, < 2.4.0)
7
7
  karafka-core (>= 2.3.0, < 2.4.0)
@@ -26,7 +26,7 @@ GEM
26
26
  byebug (11.1.3)
27
27
  concurrent-ruby (1.2.3)
28
28
  connection_pool (2.4.1)
29
- diff-lcs (1.5.0)
29
+ diff-lcs (1.5.1)
30
30
  docile (1.4.0)
31
31
  drb (2.2.0)
32
32
  ruby2_keywords
@@ -42,14 +42,14 @@ GEM
42
42
  zeitwerk (~> 2.3)
43
43
  karafka-core (2.3.0)
44
44
  karafka-rdkafka (>= 0.14.8, < 0.15.0)
45
- karafka-rdkafka (0.14.8)
45
+ karafka-rdkafka (0.14.9)
46
46
  ffi (~> 1.15)
47
47
  mini_portile2 (~> 2.6)
48
48
  rake (> 12)
49
49
  mini_portile2 (2.8.5)
50
- minitest (5.21.2)
50
+ minitest (5.22.0)
51
51
  mutex_m (0.2.0)
52
- rack (3.0.8)
52
+ rack (3.0.9)
53
53
  rack-test (2.1.0)
54
54
  rack (>= 1.3)
55
55
  rackup (0.2.3)
@@ -58,19 +58,19 @@ GEM
58
58
  rake (13.1.0)
59
59
  roda (3.76.0)
60
60
  rack
61
- rspec (3.12.0)
62
- rspec-core (~> 3.12.0)
63
- rspec-expectations (~> 3.12.0)
64
- rspec-mocks (~> 3.12.0)
65
- rspec-core (3.12.2)
66
- rspec-support (~> 3.12.0)
67
- rspec-expectations (3.12.3)
61
+ rspec (3.13.0)
62
+ rspec-core (~> 3.13.0)
63
+ rspec-expectations (~> 3.13.0)
64
+ rspec-mocks (~> 3.13.0)
65
+ rspec-core (3.13.0)
66
+ rspec-support (~> 3.13.0)
67
+ rspec-expectations (3.13.0)
68
68
  diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.12.0)
70
- rspec-mocks (3.12.6)
69
+ rspec-support (~> 3.13.0)
70
+ rspec-mocks (3.13.0)
71
71
  diff-lcs (>= 1.2.0, < 2.0)
72
- rspec-support (~> 3.12.0)
73
- rspec-support (3.12.1)
72
+ rspec-support (~> 3.13.0)
73
+ rspec-support (3.13.0)
74
74
  ruby2_keywords (0.0.5)
75
75
  simplecov (0.22.0)
76
76
  docile (~> 1.1)
@@ -81,11 +81,11 @@ GEM
81
81
  tilt (2.3.0)
82
82
  tzinfo (2.0.6)
83
83
  concurrent-ruby (~> 1.0)
84
- waterdrop (2.6.12)
84
+ waterdrop (2.6.14)
85
85
  karafka-core (>= 2.2.3, < 3.0.0)
86
86
  zeitwerk (~> 2.3)
87
87
  webrick (1.8.1)
88
- zeitwerk (2.6.12)
88
+ zeitwerk (2.6.13)
89
89
 
90
90
  PLATFORMS
91
91
  ruby
@@ -101,4 +101,4 @@ DEPENDENCIES
101
101
  simplecov
102
102
 
103
103
  BUNDLED WITH
104
- 2.5.4
104
+ 2.5.6
data/docker-compose.yml CHANGED
@@ -3,7 +3,7 @@ version: '2'
3
3
  services:
4
4
  kafka:
5
5
  container_name: kafka
6
- image: confluentinc/cp-kafka:7.5.3
6
+ image: confluentinc/cp-kafka:7.6.0
7
7
 
8
8
  ports:
9
9
  - 9092:9092
@@ -6,6 +6,10 @@ module Karafka
6
6
  class Config
7
7
  include ::Karafka::Core::Configurable
8
8
 
9
+ # Is the Web UI enabled and things were configured.
10
+ # Automatically set to true in case things got enabled.
11
+ setting :enabled, default: false
12
+
9
13
  # How long do we consider the process alive without receiving status info about it
10
14
  # For this long we also display dead processes (shutdown) in the UI
11
15
  # This is used both in the processing for eviction and in the UI
@@ -65,6 +69,7 @@ module Karafka
65
69
 
66
70
  # Listeners needed for the Web UI to track consumer related changes
67
71
  setting :listeners, default: [
72
+ Tracking::Consumers::Listeners::Booting.new,
68
73
  Tracking::Consumers::Listeners::Status.new,
69
74
  Tracking::Consumers::Listeners::Errors.new,
70
75
  Tracking::Consumers::Listeners::Connections.new,
@@ -84,6 +89,7 @@ module Karafka
84
89
 
85
90
  # Listeners needed for the Web UI to track producers related stuff
86
91
  setting :listeners, default: [
92
+ Tracking::Producers::Listeners::Booting.new,
87
93
  Tracking::Producers::Listeners::Errors.new
88
94
  ]
89
95
  end
@@ -10,6 +10,7 @@ module Karafka
10
10
  # Use the same regexp as Karafka for topics validation
11
11
  TOPIC_REGEXP = ::Karafka::Contracts::TOPIC_REGEXP
12
12
 
13
+ required(:enabled) { |val| [true, false, nil].include?(val) }
13
14
  required(:ttl) { |val| val.is_a?(Numeric) && val.positive? }
14
15
 
15
16
  nested(:topics) do
@@ -12,9 +12,12 @@ module Karafka
12
12
  #
13
13
  # @param replication_factor [Integer] replication factor we want to use (1 by default)
14
14
  def install(replication_factor: 1)
15
+ enable!
15
16
  puts
16
17
  puts 'Installing Karafka Web UI...'
17
18
  puts
19
+ Management::Actions::ExtendBootFile.new.call
20
+ puts
18
21
  puts 'Creating necessary topics and populating state data...'
19
22
  puts
20
23
  Management::Actions::CreateTopics.new.call(replication_factor)
@@ -24,8 +27,6 @@ module Karafka
24
27
  puts 'Running data migrations...'
25
28
  Management::Actions::MigrateStatesData.new.call
26
29
  puts
27
- Management::Actions::ExtendBootFile.new.call
28
- puts
29
30
  puts("Installation #{green('completed')}. Have fun!")
30
31
  puts
31
32
  end
@@ -35,6 +36,7 @@ module Karafka
35
36
  #
36
37
  # @param replication_factor [Integer] replication factor we want to use (1 by default)
37
38
  def migrate(replication_factor: 1)
39
+ enable!
38
40
  puts
39
41
  puts 'Creating necessary topics and populating state data...'
40
42
  puts
@@ -52,6 +54,7 @@ module Karafka
52
54
  # Removes all the Karafka topics and creates them again with the same replication factor
53
55
  # @param replication_factor [Integer] replication factor we want to use (1 by default)
54
56
  def reset(replication_factor: 1)
57
+ enable!
55
58
  puts
56
59
  puts 'Resetting Karafka Web UI...'
57
60
  puts
@@ -70,6 +73,7 @@ module Karafka
70
73
 
71
74
  # Removes all the Karafka Web topics and cleans after itself.
72
75
  def uninstall
76
+ enable!
73
77
  puts
74
78
  puts 'Uninstalling Karafka Web UI...'
75
79
  puts
@@ -10,6 +10,11 @@ module Karafka
10
10
  class Enable < Base
11
11
  # Enables routing consumer group and subscribes Web-UI listeners
12
12
  def call
13
+ # Prevent double enabling
14
+ return if ::Karafka::Web.config.enabled
15
+
16
+ ::Karafka::Web.config.enabled = true
17
+
13
18
  extend_routing
14
19
  setup_tracking_activity
15
20
 
@@ -22,7 +22,9 @@ module Karafka
22
22
 
23
23
  # Adds needed code
24
24
  def call
25
- if File.read(Karafka.boot_file).include?(ENABLER_CODE)
25
+ # We detect this that way so in case our template or user has enabled as a comment
26
+ # it still adds the template and runs install
27
+ if File.readlines(Karafka.boot_file).any? { |line| line.start_with?(ENABLER_CODE) }
26
28
  puts "Web UI #{already} installed."
27
29
  else
28
30
  puts 'Updating the Karafka boot file...'
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Web
5
+ module Management
6
+ module Migrations
7
+ # Moves to using lag total as a normalization for both lags
8
+ class IntroduceLagTotalInMetrics < Base
9
+ self.versions_until = '1.2.0'
10
+ self.type = :consumers_metrics
11
+
12
+ # @param state [Hash]
13
+ def migrate(state)
14
+ state[:aggregated].each_value do |metrics|
15
+ metrics.each do |metric|
16
+ metric.last[:lag_total] = metric.last[:lag_stored]
17
+ metric.last.delete(:lag_stored)
18
+ metric.last.delete(:lag)
19
+ end
20
+ end
21
+
22
+ state[:consumer_groups].each_value do |metrics|
23
+ metrics.each do |metric_group|
24
+ metric_group.last.each_value do |metric|
25
+ metric.each_value do |sample|
26
+ sample[:lag_total] = sample[:lag_stored]
27
+ sample.delete(:lag_stored)
28
+ sample.delete(:lag)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Web
5
+ module Management
6
+ module Migrations
7
+ # Moves to using lag total as a normalization for both lags
8
+ class IntroduceLagTotalInStates < Base
9
+ self.versions_until = '1.3.0'
10
+ self.type = :consumers_state
11
+
12
+ # @param state [Hash]
13
+ def migrate(state)
14
+ state[:stats][:lag_total] = state[:stats][:lag_stored]
15
+ state[:stats].delete(:lag)
16
+ state[:stats].delete(:lag_stored)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Web
5
+ module Management
6
+ module Migrations
7
+ # Renames total lag to hybrid to better represent what it is
8
+ class RenameLagTotalToLagHybridInMetrics < Base
9
+ self.versions_until = '1.2.1'
10
+ self.type = :consumers_metrics
11
+
12
+ # @param state [Hash]
13
+ def migrate(state)
14
+ state[:aggregated].each_value do |metrics|
15
+ metrics.each do |metric|
16
+ metric.last[:lag_hybrid] = metric.last[:lag_total] || 0
17
+ metric.last.delete(:lag_total)
18
+ end
19
+ end
20
+
21
+ state[:consumer_groups].each_value do |metrics|
22
+ metrics.each do |metric_group|
23
+ metric_group.last.each_value do |metric|
24
+ metric.each_value do |sample|
25
+ sample[:lag_hybrid] = sample[:lag_total]
26
+ sample.delete(:lag_total)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Web
5
+ module Management
6
+ module Migrations
7
+ # Renames total lag to hybrid to better represent what it is
8
+ class RenameLagTotalToLagHybridInStates < Base
9
+ self.versions_until = '1.3.1'
10
+ self.type = :consumers_state
11
+
12
+ # @param state [Hash]
13
+ def migrate(state)
14
+ state[:stats][:lag_hybrid] = state[:stats][:lag_total] || 0
15
+ state[:stats].delete(:lag_total)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -11,7 +11,7 @@ module Karafka
11
11
  class Metrics < Base
12
12
  # Current schema version
13
13
  # This is used for detecting incompatible changes and writing migrations
14
- SCHEMA_VERSION = '1.1.2'
14
+ SCHEMA_VERSION = '1.2.1'
15
15
 
16
16
  def initialize
17
17
  super
@@ -92,12 +92,11 @@ module Karafka
92
92
  cgs = {}
93
93
 
94
94
  iterate_partitions_data do |group_name, topic_name, partitions_data|
95
- lags = partitions_data
96
- .map { |p_details| p_details.fetch(:lag, -1) }
97
- .reject(&:negative?)
98
-
99
- lags_stored = partitions_data
100
- .map { |p_details| p_details.fetch(:lag_stored, -1) }
95
+ lags_hybrid = partitions_data
96
+ .map do |p_details|
97
+ lag_stored = p_details.fetch(:lag_stored, -1)
98
+ lag_stored.negative? ? p_details.fetch(:lag, -1) : lag_stored
99
+ end
101
100
  .reject(&:negative?)
102
101
 
103
102
  offsets_hi = partitions_data
@@ -121,8 +120,7 @@ module Karafka
121
120
 
122
121
  cgs[group_name] ||= {}
123
122
  cgs[group_name][topic_name] = {
124
- lag_stored: lags_stored.sum,
125
- lag: lags.sum,
123
+ lag_hybrid: lags_hybrid.sum,
126
124
  pace: offsets_hi.sum,
127
125
  # Take max last stable offset duration without any change. This can
128
126
  # indicate a hanging transaction, because the offset will not move forward
@@ -20,7 +20,7 @@ module Karafka
20
20
  # Current schema version
21
21
  # This can be used in the future for detecting incompatible changes and writing
22
22
  # migrations
23
- SCHEMA_VERSION = '1.2.2'
23
+ SCHEMA_VERSION = '1.3.1'
24
24
 
25
25
  # @param schema_manager [Karafka::Web::Processing::Consumers::SchemaManager] schema
26
26
  # manager that tracks the compatibility of schemas.
@@ -127,8 +127,7 @@ module Karafka
127
127
  stats[:processes] = 0
128
128
  stats[:rss] = 0
129
129
  stats[:listeners] = { active: 0, standby: 0 }
130
- stats[:lag] = 0
131
- stats[:lag_stored] = 0
130
+ stats[:lag_hybrid] = 0
132
131
  stats[:bytes_received] = 0
133
132
  stats[:bytes_sent] = 0
134
133
  utilization = 0
@@ -140,12 +139,13 @@ module Karafka
140
139
  report_stats = report[:stats]
141
140
  report_process = report[:process]
142
141
 
143
- lags = []
144
- lags_stored = []
142
+ lags_hybrid = []
145
143
 
146
144
  iterate_partitions(report) do |partition_stats|
147
- lags << partition_stats[:lag]
148
- lags_stored << partition_stats[:lag_stored]
145
+ lag_stored = partition_stats[:lag_stored]
146
+ lag = partition_stats[:lag]
147
+
148
+ lags_hybrid << (lag_stored.negative? ? lag : lag_stored)
149
149
  end
150
150
 
151
151
  stats[:busy] += report_stats[:busy]
@@ -157,8 +157,7 @@ module Karafka
157
157
  stats[:listeners][:standby] += report_process[:listeners][:standby]
158
158
  stats[:processes] += 1
159
159
  stats[:rss] += report_process[:memory_usage]
160
- stats[:lag] += lags.compact.reject(&:negative?).sum
161
- stats[:lag_stored] += lags_stored.compact.reject(&:negative?).sum
160
+ stats[:lag_hybrid] += lags_hybrid.compact.reject(&:negative?).sum
162
161
  utilization += report_stats[:utilization]
163
162
  end
164
163
 
@@ -21,8 +21,7 @@ module Karafka
21
21
  required(:processes) { |val| val.is_a?(Integer) && val >= 0 }
22
22
  required(:rss) { |val| val.is_a?(Numeric) && val >= 0 }
23
23
  required(:utilization) { |val| val.is_a?(Numeric) && val >= 0 }
24
- required(:lag_stored) { |val| val.is_a?(Integer) }
25
- required(:lag) { |val| val.is_a?(Integer) }
24
+ required(:lag_hybrid) { |val| val.is_a?(Integer) }
26
25
 
27
26
  nested(:listeners) do
28
27
  required(:active) { |val| val.is_a?(Integer) && val >= 0 }
@@ -9,8 +9,7 @@ module Karafka
9
9
  class TopicStats < Web::Contracts::Base
10
10
  configure
11
11
 
12
- required(:lag_stored) { |val| val.is_a?(Integer) }
13
- required(:lag) { |val| val.is_a?(Integer) }
12
+ required(:lag_hybrid) { |val| val.is_a?(Integer) }
14
13
  required(:pace) { |val| val.is_a?(Integer) }
15
14
  required(:ls_offset_fd) { |val| val.is_a?(Integer) && val >= 0 }
16
15
  end
@@ -19,7 +19,7 @@ module Karafka
19
19
  required(:stateage) { |val| val.is_a?(Integer) && val >= 0 }
20
20
  required(:rebalance_age) { |val| val.is_a?(Integer) && val >= 0 }
21
21
  required(:rebalance_cnt) { |val| val.is_a?(Integer) && val >= 0 }
22
- required(:rebalance_reason) { |val| val.is_a?(String) && !val.empty? }
22
+ required(:rebalance_reason) { |val| val.is_a?(String) }
23
23
  required(:poll_age) { |val| val.is_a?(Numeric) && val >= 0 }
24
24
  end
25
25
 
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Web
5
+ module Tracking
6
+ module Consumers
7
+ module Listeners
8
+ # Listener needed to start schedulers and other things that we need to collect and report
9
+ # data. We do not want to start this when code is loaded because it may not be fork
10
+ # compatible that way
11
+ class Booting < Base
12
+ # Starts (if needed) the Web UI tracking scheduler thread that periodically pings
13
+ # reporters to report needed data (when it is time).
14
+ #
15
+ # @param _event [Karafka::Core::Monitoring::Event]
16
+ def on_app_running(_event)
17
+ ::Karafka::Web.config.tracking.scheduler.async_call
18
+ end
19
+
20
+ # Updates the web producer after fork if needed and adds ppid to nodes
21
+ # @param _event [Karafka::Core::Monitoring::Event]
22
+ def on_swarm_node_after_fork(_event)
23
+ ::Karafka::Process.tags.add(:node_ppid, "ppid:#{::Process.ppid}")
24
+
25
+ return if Karafka::Web.config.producer == Karafka::App.config.producer
26
+
27
+ Web.config.producer = Karafka::App.config.producer
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -46,7 +46,6 @@ module Karafka
46
46
  end
47
47
  @subscription_groups = {}
48
48
  @errors = []
49
- @started_at = float_now
50
49
  @pauses = {}
51
50
  @jobs = {}
52
51
  @shell = MemoizedShell.new
@@ -71,7 +70,7 @@ module Karafka
71
70
  dispatched_at: float_now,
72
71
 
73
72
  process: {
74
- started_at: @started_at,
73
+ started_at: started_at,
75
74
  name: process_name,
76
75
  status: ::Karafka::App.config.internal.status.to_s,
77
76
  listeners: listeners,
@@ -129,6 +128,13 @@ module Karafka
129
128
 
130
129
  private
131
130
 
131
+ # @return [Float] time of start of this process
132
+ # @note We memoize it on first run as forks should have their creation time matching the
133
+ # fork time.
134
+ def started_at
135
+ @started_at ||= float_now
136
+ end
137
+
132
138
  # @return [Numeric] % utilization of all the threads. 100% means all the threads are
133
139
  # utilized all the time within the given time window. 0% means, nothing is happening
134
140
  # most if not all the time.
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Web
5
+ module Tracking
6
+ module Producers
7
+ module Listeners
8
+ # Listener needed to start schedulers and other things that we need to collect and report
9
+ # data. We do not want to start this when code is loaded because it may not be fork
10
+ # compatible that way
11
+ class Booting < Base
12
+ # Starts (if needed) the Web UI tracking scheduler thread that periodically pings
13
+ # reporters to report needed data (when it is time).
14
+ #
15
+ # @param _event [Karafka::Core::Monitoring::Event]
16
+ def on_producer_connected(_event)
17
+ ::Karafka::Web.config.tracking.scheduler.async_call
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -11,11 +11,6 @@ module Karafka
11
11
  class Scheduler
12
12
  include ::Karafka::Helpers::Async
13
13
 
14
- # Creates the scheduler and runs its internal reporting
15
- def initialize
16
- async_call
17
- end
18
-
19
14
  private
20
15
 
21
16
  # Reports the process state once in a while
@@ -9,7 +9,7 @@ module Karafka
9
9
  self.sortable_attributes = %w[
10
10
  name
11
11
  started_at
12
- lag_stored
12
+ lag_hybrid
13
13
  ].freeze
14
14
 
15
15
  # List page with consumers
@@ -41,11 +41,13 @@ module Karafka
41
41
  def status_bg(status)
42
42
  case status
43
43
  when 'initialized' then 'bg-success'
44
+ when 'supervising' then 'bg-success'
44
45
  when 'running' then 'bg-success'
45
46
  when 'quieting' then 'bg-warning'
46
47
  when 'quiet' then 'bg-warning text-dark'
47
48
  when 'stopping' then 'bg-warning text-dark'
48
49
  when 'stopped' then 'bg-danger'
50
+ when 'terminated' then 'bg-danger'
49
51
  else
50
52
  raise ::Karafka::Errors::UnsupportedCaseError, status
51
53
  end
@@ -16,17 +16,17 @@ module Karafka
16
16
 
17
17
  # @return [String] JSON with lags of each of the topics + total lag of all the topics
18
18
  # from all the consumer groups.
19
- def lags_stored
19
+ def lags_hybrid
20
20
  total = Hash.new { |h, v| h[v] = 0 }
21
21
 
22
22
  @data.to_h.each_value do |metrics|
23
23
  metrics.each do |metric|
24
24
  time = metric.first
25
- lag_stored = metric.last[:lag_stored]
25
+ lag_hybrid = metric.last[:lag_hybrid]
26
26
 
27
- if lag_stored
27
+ if lag_hybrid
28
28
  total[time] ||= 0
29
- total[time] += lag_stored
29
+ total[time] += lag_hybrid
30
30
  else
31
31
  next if total.key?(time)
32
32
 
@@ -37,7 +37,7 @@ module Karafka
37
37
 
38
38
  # Extract the lag stored only from all the data
39
39
  per_topic = @data.to_h.map do |topic, metrics|
40
- extracted = metrics.map { |metric| [metric.first, metric.last[:lag_stored]] }
40
+ extracted = metrics.map { |metric| [metric.first, metric.last[:lag_hybrid]] }
41
41
 
42
42
  [topic, extracted]
43
43
  end.to_h