karafka-web 0.7.8 → 0.7.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/ci.yml +3 -1
- data/CHANGELOG.md +7 -1
- data/Gemfile.lock +3 -3
- data/karafka-web.gemspec +1 -1
- data/lib/karafka/web/config.rb +17 -1
- data/lib/karafka/web/management/create_initial_states.rb +2 -2
- data/lib/karafka/web/management/enable.rb +21 -1
- data/lib/karafka/web/processing/consumer.rb +1 -1
- data/lib/karafka/web/processing/consumers/aggregators/metrics.rb +13 -4
- data/lib/karafka/web/tracking/consumers/reporter.rb +2 -2
- data/lib/karafka/web/tracking/producers/reporter.rb +2 -2
- data/lib/karafka/web/tracking/reporter.rb +2 -2
- data/lib/karafka/web/ui/models/metrics/charts/topics.rb +0 -9
- data/lib/karafka/web/ui/pro/controllers/messages.rb +1 -1
- data/lib/karafka/web/version.rb +1 -1
- data/lib/karafka/web.rb +6 -0
- data.tar.gz.sig +0 -0
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0806cac6cd5ba083c727f4737a5bacbc6fb51a45229043745e401c3f5ccfd120'
|
4
|
+
data.tar.gz: f6f5743e8fe1b32eec5c126f81d8ed4bcb0501569c050b721a238388d608a7aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a70b5779abaa3440ffb85f8d735edf6a96723ab08c0c52a982c3ac09331d4a459053de0fcf4767bd79631d0314efe9d3a13949639d1b2ee62f88cda6e6519dbb
|
7
|
+
data.tar.gz: 2ab8bc6927e8e5d0cf6ef63e2be932322eeec8d0f668c7a144b61d5dfc3ceae74a758dcd58f32deac4ccf42c4cad1d799e7df4f5c0b0bbb0494b245362104262
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
# Karafka Web changelog
|
2
2
|
|
3
|
+
## 0.7.10 (2023-10-31)
|
4
|
+
- [Fix] Max LSO chart does not work as expected (#201)
|
5
|
+
|
6
|
+
## 0.7.9 (2023-10-25)
|
7
|
+
- [Enhancement] Allow for `Karafka::Web.producer` reconfiguration from the default (`Karafka.producer`).
|
8
|
+
- [Change] Rely on `karafka-core` `>=` `2.2.4` to support lazy loaded custom web producer.
|
9
|
+
|
3
10
|
## 0.7.8 (2023-10-24)
|
4
11
|
- [Enhancement] Support transactional producer usage with Web UI.
|
5
|
-
- [Fix] Fix a bug where critical errors (like `IRB::Abort`) would not abort the ongoing transaction.
|
6
12
|
- [Fix] Prevent a scenario where an ongoing transactional producer would have stats emitted and an error that could not have been dispatched because of the transaction, creating a dead-lock.
|
7
13
|
- [Fix] Make sure that the `recent` displays the most recent non-compacted, non-system message.
|
8
14
|
- [Fix] Improve the `recent` message display to compensate for aborted transactions.
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
karafka-web (0.7.
|
4
|
+
karafka-web (0.7.10)
|
5
5
|
erubi (~> 1.4)
|
6
6
|
karafka (>= 2.2.9, < 3.0.0)
|
7
|
-
karafka-core (>= 2.2.
|
7
|
+
karafka-core (>= 2.2.4, < 3.0.0)
|
8
8
|
roda (~> 3.68, >= 3.69)
|
9
9
|
tilt (~> 2.0)
|
10
10
|
|
@@ -40,7 +40,7 @@ GEM
|
|
40
40
|
karafka-core (>= 2.2.2, < 2.3.0)
|
41
41
|
waterdrop (>= 2.6.10, < 3.0.0)
|
42
42
|
zeitwerk (~> 2.3)
|
43
|
-
karafka-core (2.2.
|
43
|
+
karafka-core (2.2.4)
|
44
44
|
concurrent-ruby (>= 1.1)
|
45
45
|
karafka-rdkafka (>= 0.13.6, < 0.14.0)
|
46
46
|
karafka-rdkafka (0.13.6)
|
data/karafka-web.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
|
19
19
|
spec.add_dependency 'erubi', '~> 1.4'
|
20
20
|
spec.add_dependency 'karafka', '>= 2.2.9', '< 3.0.0'
|
21
|
-
spec.add_dependency 'karafka-core', '>= 2.2.
|
21
|
+
spec.add_dependency 'karafka-core', '>= 2.2.4', '< 3.0.0'
|
22
22
|
spec.add_dependency 'roda', '~> 3.68', '>= 3.69'
|
23
23
|
spec.add_dependency 'tilt', '~> 2.0'
|
24
24
|
|
data/lib/karafka/web/config.rb
CHANGED
@@ -11,6 +11,17 @@ module Karafka
|
|
11
11
|
# This is used both in the processing for eviction and in the UI
|
12
12
|
setting :ttl, default: 30_000
|
13
13
|
|
14
|
+
# Producer for the Web UI. By default it is a `Karafka.producer`, however it may be
|
15
|
+
# overwritten if we want to use a separate instance in case of heavy usage of the
|
16
|
+
# transactional producer as a default. In cases like this, Karafka may not be able to report
|
17
|
+
# data because it uses this producer and it may be locked because of the transaction in a
|
18
|
+
# user space.
|
19
|
+
setting(
|
20
|
+
:producer,
|
21
|
+
constructor: -> { ::Karafka.producer },
|
22
|
+
lazy: true
|
23
|
+
)
|
24
|
+
|
14
25
|
# Topics naming - used for processing and UI
|
15
26
|
setting :topics do
|
16
27
|
# All the errors encountered will be dispatched to this topic for inspection
|
@@ -41,11 +52,13 @@ module Karafka
|
|
41
52
|
setting :scheduler, default: Tracking::Scheduler.new
|
42
53
|
|
43
54
|
setting :consumers do
|
44
|
-
# Reports the metrics collected in the sampler
|
55
|
+
# Reports the metrics collected in the consumer sampler
|
45
56
|
setting :reporter, default: Tracking::Consumers::Reporter.new
|
46
57
|
|
58
|
+
# Samples for fetching and storing metrics samples about the consumer process
|
47
59
|
setting :sampler, default: Tracking::Consumers::Sampler.new
|
48
60
|
|
61
|
+
# Listeners needed for the Web UI to track consumer related changes
|
49
62
|
setting :listeners, default: [
|
50
63
|
Tracking::Consumers::Listeners::Status.new,
|
51
64
|
Tracking::Consumers::Listeners::Errors.new,
|
@@ -57,10 +70,13 @@ module Karafka
|
|
57
70
|
end
|
58
71
|
|
59
72
|
setting :producers do
|
73
|
+
# Reports the metrics collected in the producer sampler
|
60
74
|
setting :reporter, default: Tracking::Producers::Reporter.new
|
61
75
|
|
76
|
+
# Sampler for errors from producers
|
62
77
|
setting :sampler, default: Tracking::Producers::Sampler.new
|
63
78
|
|
79
|
+
# Listeners needed for the Web UI to track producers related stuff
|
64
80
|
setting :listeners, default: [
|
65
81
|
Tracking::Producers::Listeners::Errors.new
|
66
82
|
]
|
@@ -55,7 +55,7 @@ module Karafka
|
|
55
55
|
exists('consumers state')
|
56
56
|
else
|
57
57
|
creating('consumers state')
|
58
|
-
::Karafka.producer.produce_sync(
|
58
|
+
::Karafka::Web.producer.produce_sync(
|
59
59
|
topic: Karafka::Web.config.topics.consumers.states,
|
60
60
|
key: Karafka::Web.config.topics.consumers.states,
|
61
61
|
payload: DEFAULT_STATE.to_json
|
@@ -67,7 +67,7 @@ module Karafka
|
|
67
67
|
exists('consumers metrics')
|
68
68
|
else
|
69
69
|
creating('consumers metrics')
|
70
|
-
::Karafka.producer.produce_sync(
|
70
|
+
::Karafka::Web.producer.produce_sync(
|
71
71
|
topic: Karafka::Web.config.topics.consumers.metrics,
|
72
72
|
key: Karafka::Web.config.topics.consumers.metrics,
|
73
73
|
payload: DEFAULT_METRICS.merge(dispatched_at: Time.now.to_f).to_json
|
@@ -11,6 +11,7 @@ module Karafka
|
|
11
11
|
def call
|
12
12
|
extend_routing
|
13
13
|
subscribe_to_monitor
|
14
|
+
subscribe_to_close_web_producer
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|
@@ -71,9 +72,28 @@ module Karafka
|
|
71
72
|
::Karafka.monitor.subscribe(listener)
|
72
73
|
end
|
73
74
|
|
74
|
-
# Installs all the producer related listeners
|
75
|
+
# Installs all the producer related listeners into Karafka default listener and
|
76
|
+
# into Karafka::Web listener in case it would be different than the Karafka one
|
75
77
|
::Karafka::Web.config.tracking.producers.listeners.each do |listener|
|
76
78
|
::Karafka.producer.monitor.subscribe(listener)
|
79
|
+
|
80
|
+
# Do not instrument twice in case only one default producer is used
|
81
|
+
next if ::Karafka.producer == ::Karafka::Web.producer
|
82
|
+
|
83
|
+
::Karafka::Web.producer.monitor.subscribe(listener)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# In most cases we want to close the producer if possible.
|
88
|
+
# While we cannot do it easily in user processes and we should rely on WaterDrop
|
89
|
+
# finalization logic, we can do it in `karafka server` on terminate
|
90
|
+
#
|
91
|
+
# In other places, this producer anyhow should not be used.
|
92
|
+
def subscribe_to_close_web_producer
|
93
|
+
::Karafka::App.monitor.subscribe('app.terminated') do
|
94
|
+
# If Web producer is the same as `Karafka.producer` it will do nothing as you can
|
95
|
+
# call `#close` multiple times without side effects
|
96
|
+
::Karafka::Web.producer.close
|
77
97
|
end
|
78
98
|
end
|
79
99
|
end
|
@@ -107,9 +107,18 @@ module Karafka
|
|
107
107
|
|
108
108
|
# Last stable offsets freeze durations - we pick the max freeze to indicate
|
109
109
|
# the longest open transaction that potentially may be hanging
|
110
|
-
|
111
|
-
|
112
|
-
|
110
|
+
# We select only those partitions for which LSO != HO as in any other case this
|
111
|
+
# just means we've reached the end of data and ls may freeze because there is no
|
112
|
+
# more data flowing. Such cases should not be reported as ls offset freezes because
|
113
|
+
# there is no more data to be processed and can grow until more data is present
|
114
|
+
# this does not indicate "bad" freezing that we are interested in
|
115
|
+
ls_offsets_fds = partitions_data.map do |p_details|
|
116
|
+
next if p_details.fetch(:ls_offset, 0) == p_details.fetch(:hi_offset, 0)
|
117
|
+
|
118
|
+
ls_offset_fd = p_details.fetch(:ls_offset_fd, 0)
|
119
|
+
|
120
|
+
ls_offset_fd.negative? ? nil : ls_offset_fd
|
121
|
+
end
|
113
122
|
|
114
123
|
cgs[group_name] ||= {}
|
115
124
|
cgs[group_name][topic_name] = {
|
@@ -119,7 +128,7 @@ module Karafka
|
|
119
128
|
# Take max last stable offset duration without any change. This can
|
120
129
|
# indicate a hanging transaction, because the offset will not move forward
|
121
130
|
# and will stay with a growing freeze duration when stuck
|
122
|
-
ls_offset_fd:
|
131
|
+
ls_offset_fd: ls_offsets_fds.compact.max || 0
|
123
132
|
}
|
124
133
|
end
|
125
134
|
|
@@ -135,9 +135,9 @@ module Karafka
|
|
135
135
|
# slowdown any processing.
|
136
136
|
def produce(messages)
|
137
137
|
if messages.count >= PRODUCE_SYNC_THRESHOLD
|
138
|
-
::Karafka.producer.produce_many_sync(messages)
|
138
|
+
::Karafka::Web.producer.produce_many_sync(messages)
|
139
139
|
else
|
140
|
-
::Karafka.producer.produce_many_async(messages)
|
140
|
+
::Karafka::Web.producer.produce_many_async(messages)
|
141
141
|
end
|
142
142
|
# Since we run this in a background thread, there may be a case upon shutdown, where the
|
143
143
|
# producer is closed right before a potential dispatch. It is not worth dealing with this
|
@@ -83,9 +83,9 @@ module Karafka
|
|
83
83
|
# slowdown any processing.
|
84
84
|
def produce(messages)
|
85
85
|
if messages.count >= PRODUCE_SYNC_THRESHOLD
|
86
|
-
::Karafka.producer.produce_many_sync(messages)
|
86
|
+
::Karafka::Web.producer.produce_many_sync(messages)
|
87
87
|
else
|
88
|
-
::Karafka.producer.produce_many_async(messages)
|
88
|
+
::Karafka::Web.producer.produce_many_async(messages)
|
89
89
|
end
|
90
90
|
# Since we run this in a background thread, there may be a case upon shutdown, where the
|
91
91
|
# producer is closed right before a potential dispatch. It is not worth dealing with this
|
@@ -14,8 +14,8 @@ module Karafka
|
|
14
14
|
#
|
15
15
|
# @return [Boolean]
|
16
16
|
def active?
|
17
|
-
return false unless ::Karafka::
|
18
|
-
return false unless ::Karafka::
|
17
|
+
return false unless ::Karafka::Web.producer
|
18
|
+
return false unless ::Karafka::Web.producer.status.active?
|
19
19
|
|
20
20
|
true
|
21
21
|
end
|
@@ -76,20 +76,11 @@ module Karafka
|
|
76
76
|
topic_without_cg = topic.split('[').first
|
77
77
|
|
78
78
|
metrics.each do |current|
|
79
|
-
ls_offset = current.last[:ls_offset] || 0
|
80
79
|
ls_offset_fd = current.last[:ls_offset_fd] || 0
|
81
|
-
hi_offset = current.last[:hi_offset] || 0
|
82
80
|
|
83
81
|
# We convert this to seconds from milliseconds due to our Web UI precision
|
84
82
|
# Reporting is in ms for consistency
|
85
83
|
normalized_fd = (ls_offset_fd / 1_000).round
|
86
|
-
# In case ls_offset and hi_offset are the same, it means we're reached eof
|
87
|
-
# and we just don't have more data. In cases like this, LSO freeze duration
|
88
|
-
# will grow because LSO will remain unchanged, but it does not mean it is
|
89
|
-
# frozen. It means there is just no more data in the topic partition
|
90
|
-
# This means we need to nullify this case, otherwise it would report, that
|
91
|
-
# lso is hanging.
|
92
|
-
normalized_fd = 0 if ls_offset == hi_offset
|
93
84
|
|
94
85
|
topics[topic_without_cg][current.first] << normalized_fd
|
95
86
|
end
|
@@ -28,7 +28,7 @@ module Karafka
|
|
28
28
|
def republish(topic_id, partition_id, offset)
|
29
29
|
message = Ui::Models::Message.find(topic_id, partition_id, offset)
|
30
30
|
|
31
|
-
delivery = ::Karafka.producer.produce_sync(
|
31
|
+
delivery = ::Karafka::Web.producer.produce_sync(
|
32
32
|
topic: topic_id,
|
33
33
|
partition: partition_id,
|
34
34
|
payload: message.raw_payload,
|
data/lib/karafka/web/version.rb
CHANGED
data/lib/karafka/web.rb
CHANGED
@@ -13,6 +13,12 @@ module Karafka
|
|
13
13
|
# Karafka Web UI + Karafka web monitoring
|
14
14
|
module Web
|
15
15
|
class << self
|
16
|
+
# @return [WaterDrop::Producer, nil] waterdrop messages producer or nil if not yet fully
|
17
|
+
# initialized. It may not be fully initialized until the configuration is done
|
18
|
+
def producer
|
19
|
+
@producer ||= Web.config.producer
|
20
|
+
end
|
21
|
+
|
16
22
|
# @return [String] root path of this gem
|
17
23
|
def gem_root
|
18
24
|
Pathname.new(File.expand_path('../..', __dir__))
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: karafka-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciej Mensfeld
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
AnG1dJU+yL2BK7vaVytLTstJME5mepSZ46qqIJXMuWob/YPDmVaBF39TDSG9e34s
|
36
36
|
msG3BiCqgOgHAnL23+CN3Rt8MsuRfEtoTKpJVcCfoEoNHOkc
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2023-10-
|
38
|
+
date: 2023-10-31 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: erubi
|
@@ -77,7 +77,7 @@ dependencies:
|
|
77
77
|
requirements:
|
78
78
|
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: 2.2.
|
80
|
+
version: 2.2.4
|
81
81
|
- - "<"
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: 3.0.0
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
requirements:
|
88
88
|
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: 2.2.
|
90
|
+
version: 2.2.4
|
91
91
|
- - "<"
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: 3.0.0
|
metadata.gz.sig
CHANGED
Binary file
|