karafka-web 0.2.5 → 0.3.0
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/CHANGELOG.md +28 -0
- data/Gemfile.lock +3 -3
- data/karafka-web.gemspec +1 -1
- data/lib/karafka/web/tracking/consumers/sampler.rb +9 -22
- data/lib/karafka/web/tracking/sampler.rb +57 -0
- data/lib/karafka/web/ui/controllers/errors.rb +2 -0
- data/lib/karafka/web/ui/controllers/status.rb +1 -0
- data/lib/karafka/web/ui/models/job.rb +0 -4
- data/lib/karafka/web/ui/models/message.rb +71 -14
- data/lib/karafka/web/ui/models/process.rb +0 -7
- data/lib/karafka/web/ui/models/watermark_offsets.rb +39 -0
- data/lib/karafka/web/ui/pro/controllers/errors.rb +2 -1
- data/lib/karafka/web/ui/pro/controllers/explorer.rb +3 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_metrics.erb +29 -21
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_partition.erb +14 -2
- data/lib/karafka/web/ui/pro/views/errors/_cleaned.erb +3 -0
- data/lib/karafka/web/ui/pro/views/errors/_error.erb +33 -25
- data/lib/karafka/web/ui/pro/views/errors/_no_errors.erb +3 -0
- data/lib/karafka/web/ui/pro/views/errors/index.erb +29 -21
- data/lib/karafka/web/ui/pro/views/explorer/_message.erb +27 -16
- data/lib/karafka/web/ui/pro/views/explorer/partition/_cleaned.erb +3 -0
- data/lib/karafka/web/ui/pro/views/explorer/partition/_empty.erb +3 -0
- data/lib/karafka/web/ui/pro/views/explorer/partition/_messages.erb +18 -0
- data/lib/karafka/web/ui/pro/views/explorer/partition/_watermark_offsets.erb +10 -0
- data/lib/karafka/web/ui/pro/views/explorer/partition.erb +10 -19
- data/lib/karafka/web/ui/public/stylesheets/application.css +4 -0
- data/lib/karafka/web/ui/views/errors/_cleaned.erb +3 -0
- data/lib/karafka/web/ui/views/errors/_error.erb +33 -25
- data/lib/karafka/web/ui/views/errors/_no_errors.erb +3 -0
- data/lib/karafka/web/ui/views/errors/_watermark_offsets.erb +10 -0
- data/lib/karafka/web/ui/views/errors/index.erb +29 -21
- data/lib/karafka/web/ui/views/status/_info.erb +14 -0
- data/lib/karafka/web/ui/views/status/info/_components.erb +34 -0
- data/lib/karafka/web/ui/views/status/show.erb +9 -1
- data/lib/karafka/web/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +17 -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: 5c3bf9c5a445bd6a5d291412eea7fba31d1de171f0262543cf149c49946af788
|
4
|
+
data.tar.gz: d4febb4b2b6bf5405213abaa114892b06f6207623c100cbfc4a3037809a0e94e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ba13c91f46ef01927464720f9b0919f7a6bb5d7cc081a30e926a14b40331d375fdbab53b4de6fe3849101b15c3b9eeb70538a5821486ed15e4677a5e6995a3d
|
7
|
+
data.tar.gz: 6402543fa36aac339bd2d0795a45802d4c3f3f085d4075fed994ea51d889a872cc2f8fe17c04206bf8811c2395a7381d01698e29adba497fec4e5b35c97892c4
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Karafka Web changelog
|
2
2
|
|
3
|
+
## 0.3.0 (2023-03-27)
|
4
|
+
- **[Feature]** Support paginating over compacted topics partitions.
|
5
|
+
- [Improvement] Display watermark offsets in the errors view.
|
6
|
+
- [Improvement] Display informative message when partition is empty due to a retention policy.
|
7
|
+
- [Improvement] Display informative message when partition is empty instead of displaying nothing.
|
8
|
+
- [Improvement] Display current watermark offsets in the Explorer when viewing list of messages from a given partition.
|
9
|
+
- [Improvement] Report extra debug info in the status section.
|
10
|
+
- [Improvement] Report not only `Karafka` and `WaterDrop` versions but also `Karafka::Core`, `Rdkafka` and `librdkafka` versions.
|
11
|
+
- [Improvement] Small CSS improvements.
|
12
|
+
- [Improvement] Provide nicer info when errors topic does not contain any errors or was compacted.
|
13
|
+
- [Improvement] Improve listing of errors including compacted once.
|
14
|
+
- [Fix] Fix pagination for compacted indexes that would display despite no data being available below the low watermark offset.
|
15
|
+
- [Fix] Fix a case where reading from a compacted offset would return no data despite data being available.
|
16
|
+
- [Fix] Fix a case where explorer pagination would suggest more pages for compacted topics.
|
17
|
+
- [Fix] Fix incorrect support of compacted partitions and partitions with low watermark offset other than 0.
|
18
|
+
- [Fix] Display `N/A` instead of `-1` and `-1001` on lag stored and stored offset for consumer processes that did not mark any messages as consumed yet in the per consumer view.
|
19
|
+
- [Maintenance] Remove compatibility fallbacks for job and process tags (#1342)
|
20
|
+
- [Maintenance] Extract base sampler for tracking and web.
|
21
|
+
|
22
|
+
### Upgrade notes
|
23
|
+
|
24
|
+
Because of the removal of compatibility fallbacks for some metrics fetches, it is recommended to:
|
25
|
+
|
26
|
+
- First, deploy **all** the Karafka consumer processes (`karafka server`)
|
27
|
+
- Deploy the Web update to your web server.
|
28
|
+
|
29
|
+
Please note that if you decide to use the updated Web UI with not updated consumers, you may hit a 500 error.
|
30
|
+
|
3
31
|
## 0.2.5 (2023-03-17)
|
4
32
|
- [Fix] Critical instrumentation async errors intercepted by Web don't have JID for job removal (#1366)
|
5
33
|
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
karafka-web (0.
|
4
|
+
karafka-web (0.3.0)
|
5
5
|
erubi (~> 1.4)
|
6
|
-
karafka (>= 2.0.
|
6
|
+
karafka (>= 2.0.38, < 3.0.0)
|
7
7
|
karafka-core (>= 2.0.12, < 3.0.0)
|
8
8
|
roda (~> 3.63)
|
9
9
|
tilt (~> 2.0)
|
@@ -26,7 +26,7 @@ GEM
|
|
26
26
|
ffi (1.15.5)
|
27
27
|
i18n (1.12.0)
|
28
28
|
concurrent-ruby (~> 1.0)
|
29
|
-
karafka (2.0.
|
29
|
+
karafka (2.0.38)
|
30
30
|
karafka-core (>= 2.0.12, < 3.0.0)
|
31
31
|
thor (>= 0.20)
|
32
32
|
waterdrop (>= 2.4.10, < 3.0.0)
|
data/karafka-web.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.licenses = %w[LGPL-3.0 Commercial]
|
18
18
|
|
19
19
|
spec.add_dependency 'erubi', '~> 1.4'
|
20
|
-
spec.add_dependency 'karafka', '>= 2.0.
|
20
|
+
spec.add_dependency 'karafka', '>= 2.0.38', '< 3.0.0'
|
21
21
|
spec.add_dependency 'karafka-core', '>= 2.0.12', '< 3.0.0'
|
22
22
|
spec.add_dependency 'roda', '~> 3.63'
|
23
23
|
spec.add_dependency 'tilt', '~> 2.0'
|
@@ -6,7 +6,7 @@ module Karafka
|
|
6
6
|
# Namespace for all the things related to tracking consumers and consuming processes
|
7
7
|
module Consumers
|
8
8
|
# Samples for fetching and storing metrics samples about the consumer process
|
9
|
-
class Sampler
|
9
|
+
class Sampler < Tracking::Sampler
|
10
10
|
include ::Karafka::Core::Helpers::Time
|
11
11
|
|
12
12
|
attr_reader :counters, :consumer_groups, :errors, :times, :pauses, :jobs
|
@@ -14,7 +14,7 @@ module Karafka
|
|
14
14
|
# Current schema version
|
15
15
|
# This can be used in the future for detecting incompatible changes and writing
|
16
16
|
# migrations
|
17
|
-
SCHEMA_VERSION = '1.0.
|
17
|
+
SCHEMA_VERSION = '1.0.2'
|
18
18
|
|
19
19
|
# 60 seconds window for time tracked window-based metrics
|
20
20
|
TIMES_TTL = 60
|
@@ -25,6 +25,8 @@ module Karafka
|
|
25
25
|
private_constant :TIMES_TTL, :TIMES_TTL_MS, :SCHEMA_VERSION
|
26
26
|
|
27
27
|
def initialize
|
28
|
+
super
|
29
|
+
|
28
30
|
@counters = {
|
29
31
|
batches: 0,
|
30
32
|
messages: 0,
|
@@ -72,8 +74,11 @@ module Karafka
|
|
72
74
|
|
73
75
|
versions: {
|
74
76
|
ruby: ruby_version,
|
75
|
-
karafka:
|
76
|
-
waterdrop:
|
77
|
+
karafka: karafka_version,
|
78
|
+
waterdrop: waterdrop_version,
|
79
|
+
karafka_core: karafka_core_version,
|
80
|
+
rdkafka: rdkafka_version,
|
81
|
+
librdkafka: librdkafka_version
|
77
82
|
},
|
78
83
|
|
79
84
|
stats: jobs_queue_statistics.merge(
|
@@ -118,11 +123,6 @@ module Karafka
|
|
118
123
|
Karafka::Server.listeners&.count.to_i
|
119
124
|
end
|
120
125
|
|
121
|
-
# @return [String] Unique process name
|
122
|
-
def process_name
|
123
|
-
@process_name ||= "#{Socket.gethostname}:#{::Process.pid}:#{SecureRandom.hex(6)}"
|
124
|
-
end
|
125
|
-
|
126
126
|
# @return [Integer] memory used by this process in kilobytes
|
127
127
|
def memory_usage
|
128
128
|
pid = ::Process.pid
|
@@ -210,19 +210,6 @@ module Karafka
|
|
210
210
|
@cpu_count ||= Etc.nprocessors
|
211
211
|
end
|
212
212
|
|
213
|
-
# @return [String] currently used ruby version with details
|
214
|
-
def ruby_version
|
215
|
-
if defined?(JRUBY_VERSION)
|
216
|
-
revision = JRUBY_REVISION.to_s
|
217
|
-
version = JRUBY_VERSION
|
218
|
-
else
|
219
|
-
revision = RUBY_REVISION.to_s
|
220
|
-
version = RUBY_ENGINE_VERSION
|
221
|
-
end
|
222
|
-
|
223
|
-
"#{RUBY_ENGINE} #{version}-#{RUBY_PATCHLEVEL} #{revision[0..5]}"
|
224
|
-
end
|
225
|
-
|
226
213
|
# @return [Integer] number of threads that process work
|
227
214
|
def concurrency
|
228
215
|
@concurrency ||= Karafka::App.config.concurrency
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Web
|
5
|
+
module Tracking
|
6
|
+
# Base sampler with some basic info collectors
|
7
|
+
# This sampler should store **only** collectors that can be used for producers, consumers and
|
8
|
+
# the Web-UI itself. All specific to a given aspect of operations should be moved out.
|
9
|
+
class Sampler
|
10
|
+
# @return [String] Unique process name
|
11
|
+
def process_name
|
12
|
+
@process_name ||= "#{Socket.gethostname}:#{::Process.pid}:#{SecureRandom.hex(6)}"
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] currently used ruby version with details
|
16
|
+
def ruby_version
|
17
|
+
return @ruby_version if @ruby_version
|
18
|
+
|
19
|
+
if defined?(JRUBY_VERSION)
|
20
|
+
revision = JRUBY_REVISION.to_s
|
21
|
+
version = JRUBY_VERSION
|
22
|
+
else
|
23
|
+
revision = RUBY_REVISION.to_s
|
24
|
+
version = RUBY_ENGINE_VERSION
|
25
|
+
end
|
26
|
+
|
27
|
+
@ruby_version = "#{RUBY_ENGINE} #{version}-#{RUBY_PATCHLEVEL} #{revision[0..5]}"
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] Karafka version
|
31
|
+
def karafka_version
|
32
|
+
::Karafka::VERSION
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [String] Karafka::Core version
|
36
|
+
def karafka_core_version
|
37
|
+
::Karafka::Core::VERSION
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [String] rdkafka version
|
41
|
+
def rdkafka_version
|
42
|
+
::Rdkafka::VERSION
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [String] librdkafka version
|
46
|
+
def librdkafka_version
|
47
|
+
::Rdkafka::LIBRDKAFKA_VERSION
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [String] WaterDrop version
|
51
|
+
def waterdrop_version
|
52
|
+
::WaterDrop::VERSION
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -38,43 +38,83 @@ module Karafka
|
|
38
38
|
# @return [Array] We return both page data as well as all the details needed to build
|
39
39
|
# the pagination details.
|
40
40
|
def page(topic_id, partition_id, page)
|
41
|
-
|
42
|
-
|
41
|
+
low_offset, high_offset = Karafka::Admin.read_watermark_offsets(
|
42
|
+
topic_id,
|
43
|
+
partition_id
|
44
|
+
)
|
43
45
|
|
44
46
|
partitions_count = fetch_partition_count(topic_id)
|
45
47
|
|
48
|
+
no_data_result = [false, [], false, partitions_count]
|
49
|
+
|
46
50
|
# If there is not even one message, we need to early exit
|
47
|
-
|
51
|
+
# If low and high watermark offsets are of the same value, it means no data in the
|
52
|
+
# topic is present
|
53
|
+
return no_data_result if low_offset == high_offset
|
48
54
|
|
49
55
|
# We add plus one because we compute previous offset from which we want to start and
|
50
56
|
# not previous page leading offset
|
51
|
-
|
57
|
+
start_offset = high_offset - (per_page * page)
|
52
58
|
|
53
|
-
if
|
54
|
-
count = per_page +
|
59
|
+
if start_offset < low_offset
|
60
|
+
count = per_page + start_offset
|
55
61
|
previous_page = page < 2 ? false : page - 1
|
56
62
|
next_page = false
|
57
|
-
|
63
|
+
start_offset = 0
|
58
64
|
else
|
59
65
|
previous_page = page < 2 ? false : page - 1
|
60
66
|
next_page = page + 1
|
61
67
|
count = per_page
|
62
68
|
end
|
63
69
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
+
# This code is a bit tricky. Since topics can be compacted and certain offsets may
|
71
|
+
# not be present at all, it may happen that we want to read from a non-existing
|
72
|
+
# offset. In case like this we need to catch this error (we do it in `read_topic`)
|
73
|
+
# and we need to move to an offset closer to high offset. This is not fast but it is
|
74
|
+
# an edge case that should not happen often when inspecting real time data. This can
|
75
|
+
# happen more often for heavily compacted topics with short retention but even then
|
76
|
+
# it is ok for 25 elements we usually operate on a single page.
|
77
|
+
count.times do |index|
|
78
|
+
context_offset = start_offset + index
|
79
|
+
# We need to get less if we move up with missing offsets to get exactly
|
80
|
+
# the number we needed
|
81
|
+
context_count = count - index
|
82
|
+
|
83
|
+
messages = read_topic(
|
84
|
+
topic_id,
|
85
|
+
partition_id,
|
86
|
+
context_count,
|
87
|
+
context_offset,
|
88
|
+
# We do not reset the offset here because we are not interested in seeking from
|
89
|
+
# any offset. We are interested in the indication, that there is no offset of a
|
90
|
+
# given value so we can try with a more recent one
|
91
|
+
'auto.offset.reset': 'error'
|
92
|
+
)
|
93
|
+
|
94
|
+
next unless messages
|
95
|
+
|
96
|
+
return [
|
97
|
+
previous_page,
|
98
|
+
fill_compacted(messages, context_offset, context_count).reverse,
|
99
|
+
next_page,
|
100
|
+
partitions_count
|
101
|
+
]
|
102
|
+
end
|
103
|
+
|
104
|
+
no_data_result
|
70
105
|
end
|
71
106
|
|
72
107
|
private
|
73
108
|
|
74
109
|
# @param args [Object] anything required by the admin `#read_topic`
|
75
|
-
# @return [Array<Karafka::Messages::Message
|
110
|
+
# @return [Array<Karafka::Messages::Message>, false] topic partition messages or false
|
111
|
+
# in case we hit a non-existing offset
|
76
112
|
def read_topic(*args)
|
77
113
|
::Karafka::Admin.read_topic(*args)
|
114
|
+
rescue Rdkafka::RdkafkaError => e
|
115
|
+
return false if e.code == :auto_offset_reset
|
116
|
+
|
117
|
+
raise
|
78
118
|
end
|
79
119
|
|
80
120
|
# @param topic_id [String] id of the topic
|
@@ -91,6 +131,23 @@ module Karafka
|
|
91
131
|
def per_page
|
92
132
|
::Karafka::Web.config.ui.per_page
|
93
133
|
end
|
134
|
+
|
135
|
+
# Since we paginate with compacted offsets visible but we do not get compacted messages
|
136
|
+
# we need to fill those with just the missing offset and handle this on the UI.
|
137
|
+
#
|
138
|
+
# @param messages [Array<Karafka::Messages::Message>] selected messages
|
139
|
+
# @param start_offset [Integer] offset of the first message (lowest) that we received
|
140
|
+
# @param count [Integer] how many messages we wanted - we need that to fill spots to
|
141
|
+
# have exactly the number that was requested and not more
|
142
|
+
# @return [Array<Karafka::Messages::Message, Integer>] array with gaps filled with the
|
143
|
+
# missing offset
|
144
|
+
def fill_compacted(messages, start_offset, count)
|
145
|
+
Array.new(count) do |index|
|
146
|
+
messages.find do |message|
|
147
|
+
(message.offset - start_offset) == index
|
148
|
+
end || start_offset + index
|
149
|
+
end
|
150
|
+
end
|
94
151
|
end
|
95
152
|
end
|
96
153
|
end
|
@@ -40,13 +40,6 @@ module Karafka
|
|
40
40
|
.sort_by(&:started_at)
|
41
41
|
end
|
42
42
|
|
43
|
-
# @return [Array<String>] tags of this consuming process
|
44
|
-
# @note We use direct reference here and a fallback for users that come from the versions
|
45
|
-
# that did not report tags
|
46
|
-
def tags
|
47
|
-
@hash[:process][:tags] || []
|
48
|
-
end
|
49
|
-
|
50
43
|
# @return [Integer] collective lag on this process
|
51
44
|
def lag_stored
|
52
45
|
consumer_groups
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Web
|
5
|
+
module Ui
|
6
|
+
module Models
|
7
|
+
# Model used for accessing watermark offsets
|
8
|
+
class WatermarkOffsets < Lib::HashProxy
|
9
|
+
class << self
|
10
|
+
# Retrieve watermark offsets for given topic partition
|
11
|
+
#
|
12
|
+
# @param topic_id [String]
|
13
|
+
# @param partition_id [Integer]
|
14
|
+
# @return [WatermarkOffsets]
|
15
|
+
def find(topic_id, partition_id)
|
16
|
+
offsets = ::Karafka::Admin.read_watermark_offsets(topic_id, partition_id)
|
17
|
+
|
18
|
+
new(
|
19
|
+
low: offsets.first,
|
20
|
+
high: offsets.last
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean] true if given partition never had any messages and is empty
|
26
|
+
def empty?
|
27
|
+
low.zero? && high.zero?
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Boolean] true if given partition had data but all of it was removed due
|
31
|
+
# to log retention and compaction policies
|
32
|
+
def cleaned?
|
33
|
+
!empty? && low == high
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -29,6 +29,8 @@ module Karafka
|
|
29
29
|
@params.current_page
|
30
30
|
)
|
31
31
|
|
32
|
+
@watermark_offsets = Ui::Models::WatermarkOffsets.find(errors_topic, @partition_id)
|
33
|
+
|
32
34
|
respond
|
33
35
|
end
|
34
36
|
|
@@ -38,7 +40,6 @@ module Karafka
|
|
38
40
|
# @param offset [Integer]
|
39
41
|
def show(partition_id, offset)
|
40
42
|
errors_topic = ::Karafka::Web.config.topics.errors
|
41
|
-
|
42
43
|
@partition_id = partition_id
|
43
44
|
@offset = offset
|
44
45
|
@error_message = Models::Message.find(
|
@@ -36,6 +36,9 @@ module Karafka
|
|
36
36
|
def partition(topic_id, partition_id)
|
37
37
|
@topic_id = topic_id
|
38
38
|
@partition_id = partition_id
|
39
|
+
|
40
|
+
@watermark_offsets = Ui::Models::WatermarkOffsets.find(topic_id, partition_id)
|
41
|
+
|
39
42
|
@previous_page, @messages, @next_page, @partitions_count = Ui::Models::Message.page(
|
40
43
|
@topic_id,
|
41
44
|
@partition_id,
|
@@ -102,27 +102,35 @@
|
|
102
102
|
<div class="card">
|
103
103
|
<div class="card-body">
|
104
104
|
<h5 class="card-title">Versions</h5>
|
105
|
-
<p class="card-text">
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
</
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
105
|
+
<p class="card-text text-center">
|
106
|
+
<span class="badge bg-secondary">
|
107
|
+
<%= @process.ruby %>
|
108
|
+
</span>
|
109
|
+
|
110
|
+
<span class="badge bg-secondary">
|
111
|
+
karafka
|
112
|
+
<%= @process.karafka %>
|
113
|
+
</span>
|
114
|
+
|
115
|
+
<span class="badge bg-secondary">
|
116
|
+
karafka core
|
117
|
+
<%= @process.karafka_core %>
|
118
|
+
</span>
|
119
|
+
|
120
|
+
<span class="badge bg-secondary">
|
121
|
+
rdkafka
|
122
|
+
<%= @process.rdkafka %>
|
123
|
+
</span>
|
124
|
+
|
125
|
+
<span class="badge bg-secondary">
|
126
|
+
librdkafka
|
127
|
+
<%= @process.librdkafka %>
|
128
|
+
</span>
|
129
|
+
|
130
|
+
<span class="badge bg-secondary">
|
131
|
+
waterdrop
|
132
|
+
<%= @process.waterdrop %>
|
133
|
+
</span>
|
126
134
|
</p>
|
127
135
|
</div>
|
128
136
|
</div>
|
@@ -6,7 +6,13 @@
|
|
6
6
|
<%= partition.id %>
|
7
7
|
</td>
|
8
8
|
<td>
|
9
|
-
|
9
|
+
<% if partition.lag_stored.to_i < 0 %>
|
10
|
+
<span class="badge bg-secondary" title="Not available until first offset commit">
|
11
|
+
N/A
|
12
|
+
</span>
|
13
|
+
<% else %>
|
14
|
+
<%= partition.lag_stored %>
|
15
|
+
<% end %>
|
10
16
|
</td>
|
11
17
|
<td>
|
12
18
|
<span class="badge <%= lag_trend_bg(partition.lag_stored_d) %>">
|
@@ -17,7 +23,13 @@
|
|
17
23
|
<%= partition.committed_offset %>
|
18
24
|
</td>
|
19
25
|
<td>
|
20
|
-
|
26
|
+
<% if partition.stored_offset.to_i < 0 %>
|
27
|
+
<span class="badge bg-secondary" title="Not available until first offset commit">
|
28
|
+
N/A
|
29
|
+
</span>
|
30
|
+
<% else %>
|
31
|
+
<%= partition.stored_offset %>
|
32
|
+
<% end %>
|
21
33
|
</td>
|
22
34
|
<td>
|
23
35
|
<span class="badge <%= kafka_state_bg(partition.fetch_state) %> mt-1 mb-1">
|
@@ -1,26 +1,34 @@
|
|
1
|
-
<%
|
1
|
+
<% if error_msg.is_a?(Integer) %>
|
2
|
+
<tr>
|
3
|
+
<td colspan="5" class="text-center text-muted">
|
4
|
+
This error has either been removed or compacted and is no longer available.
|
5
|
+
</td>
|
6
|
+
</tr>
|
7
|
+
<% else %>
|
8
|
+
<% error = error_msg.payload %>
|
2
9
|
|
3
|
-
<tr>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
</tr>
|
10
|
+
<tr>
|
11
|
+
<td>
|
12
|
+
<% if error[:details].key?(:topic) %>
|
13
|
+
<%= error[:details][:topic] %>: <%= error[:details][:partition] %>
|
14
|
+
<% else %>
|
15
|
+
<%= error[:type] %>
|
16
|
+
<% end %>
|
17
|
+
</td>
|
18
|
+
<td>
|
19
|
+
<%== error[:process_name] %>
|
20
|
+
</td>
|
21
|
+
<td>
|
22
|
+
<%= error[:error_class] %>:
|
23
|
+
<%= error[:error_message].first(200) %>
|
24
|
+
</td>
|
25
|
+
<td>
|
26
|
+
<%== relative_time error[:occurred_at] %>
|
27
|
+
</td>
|
28
|
+
<td class="text-center">
|
29
|
+
<a href="<%= root_path('errors', error_msg.partition, error_msg.offset) %>" class="btn btn-sm btn-secondary text-white">
|
30
|
+
Details
|
31
|
+
</a>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
<% end %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="container mb-
|
1
|
+
<div class="container mb-4">
|
2
2
|
<div class="row">
|
3
3
|
<div class="col">
|
4
4
|
<h3>
|
@@ -33,26 +33,34 @@
|
|
33
33
|
<div class="container">
|
34
34
|
<div class="row mb-5">
|
35
35
|
<div class="col-sm-12">
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
36
|
+
<%== partial('explorer/partition/watermark_offsets') %>
|
37
|
+
|
38
|
+
<% if @watermark_offsets.empty? %>
|
39
|
+
<%== partial 'errors/no_errors' %>
|
40
|
+
<% elsif @watermark_offsets.cleaned? %>
|
41
|
+
<%== partial 'errors/cleaned' %>
|
42
|
+
<% else %>
|
43
|
+
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
|
44
|
+
<thead>
|
45
|
+
<tr class="align-middle">
|
46
|
+
<th>Origin</th>
|
47
|
+
<th>Process name</th>
|
48
|
+
<th>Error</th>
|
49
|
+
<th>Occurred at</th>
|
50
|
+
<th></th>
|
51
|
+
</tr>
|
52
|
+
</thead>
|
53
|
+
<tbody>
|
54
|
+
<%==
|
55
|
+
each_partial(
|
56
|
+
@error_messages,
|
57
|
+
'errors/error',
|
58
|
+
local: :error_msg
|
59
|
+
)
|
60
|
+
%>
|
61
|
+
</tbody>
|
62
|
+
</table>
|
63
|
+
<% end %>
|
56
64
|
</div>
|
57
65
|
</div>
|
58
66
|
</div>
|
@@ -1,16 +1,27 @@
|
|
1
|
-
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<
|
12
|
-
<
|
13
|
-
|
14
|
-
</
|
15
|
-
|
16
|
-
|
1
|
+
<% if message.is_a?(Integer) %>
|
2
|
+
<tr>
|
3
|
+
<td class="text-muted">
|
4
|
+
<%= message %>
|
5
|
+
</td>
|
6
|
+
<td colspan="3" class="text-center text-muted">
|
7
|
+
This message has either been removed or compacted and is no longer available.
|
8
|
+
</td>
|
9
|
+
</tr>
|
10
|
+
<% else %>
|
11
|
+
<tr>
|
12
|
+
<td>
|
13
|
+
<%= message.offset %>
|
14
|
+
</td>
|
15
|
+
<td>
|
16
|
+
<%== relative_time message.timestamp %>
|
17
|
+
</td>
|
18
|
+
<td>
|
19
|
+
<%= message.key %>
|
20
|
+
</td>
|
21
|
+
<td class="text-center">
|
22
|
+
<a href="<%= root_path('explorer', message.topic, message.partition, message.offset) %>" class="btn btn-sm btn-secondary">
|
23
|
+
Details
|
24
|
+
</a>
|
25
|
+
</td>
|
26
|
+
</tr>
|
27
|
+
<% end %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
|
2
|
+
<thead>
|
3
|
+
<tr class="align-middle">
|
4
|
+
<th>Offset</th>
|
5
|
+
<th>Timestamp</th>
|
6
|
+
<th>Key</th>
|
7
|
+
<th></th>
|
8
|
+
</tr>
|
9
|
+
</thead>
|
10
|
+
<tbody>
|
11
|
+
<%==
|
12
|
+
each_partial(
|
13
|
+
@messages,
|
14
|
+
'explorer/message'
|
15
|
+
)
|
16
|
+
%>
|
17
|
+
</tbody>
|
18
|
+
</table>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="container mb-
|
1
|
+
<div class="container mb-4">
|
2
2
|
<div class="row">
|
3
3
|
<div class="col">
|
4
4
|
<h3>
|
@@ -33,24 +33,15 @@
|
|
33
33
|
<div class="container">
|
34
34
|
<div class="row mb-5">
|
35
35
|
<div class="col-sm-12">
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
<tbody>
|
46
|
-
<%==
|
47
|
-
each_partial(
|
48
|
-
@messages,
|
49
|
-
'explorer/message'
|
50
|
-
)
|
51
|
-
%>
|
52
|
-
</tbody>
|
53
|
-
</table>
|
36
|
+
<%== partial('explorer/partition/watermark_offsets') %>
|
37
|
+
|
38
|
+
<% if @watermark_offsets.empty? %>
|
39
|
+
<%== partial 'explorer/partition/empty' %>
|
40
|
+
<% elsif @watermark_offsets.cleaned? %>
|
41
|
+
<%== partial 'explorer/partition/cleaned' %>
|
42
|
+
<% else %>
|
43
|
+
<%== partial('explorer/partition/messages') %>
|
44
|
+
<% end %>
|
54
45
|
</div>
|
55
46
|
</div>
|
56
47
|
</div>
|
@@ -1,26 +1,34 @@
|
|
1
|
-
<%
|
1
|
+
<% if error_msg.is_a?(Integer) %>
|
2
|
+
<tr>
|
3
|
+
<td colspan="5" class="text-center text-muted">
|
4
|
+
This error has either been removed or compacted and is no longer available.
|
5
|
+
</td>
|
6
|
+
</tr>
|
7
|
+
<% else %>
|
8
|
+
<% error = error_msg.payload %>
|
2
9
|
|
3
|
-
<tr>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
</tr>
|
10
|
+
<tr>
|
11
|
+
<td>
|
12
|
+
<% if error[:details].key?(:topic) %>
|
13
|
+
<%= error[:details][:topic] %>: <%= error[:details][:partition] %>
|
14
|
+
<% else %>
|
15
|
+
<%= error[:type] %>
|
16
|
+
<% end %>
|
17
|
+
</td>
|
18
|
+
<td>
|
19
|
+
<%== error[:process_name] %>
|
20
|
+
</td>
|
21
|
+
<td>
|
22
|
+
<%= error[:error_class] %>:
|
23
|
+
<%= error[:error_message].first(200) %>
|
24
|
+
</td>
|
25
|
+
<td>
|
26
|
+
<%== relative_time error[:occurred_at] %>
|
27
|
+
</td>
|
28
|
+
<td class="text-center">
|
29
|
+
<a href="<%= root_path('errors', error_msg.offset) %>" class="btn btn-sm btn-secondary text-white">
|
30
|
+
Details
|
31
|
+
</a>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
<% end %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="container mb-
|
1
|
+
<div class="container mb-4">
|
2
2
|
<div class="row">
|
3
3
|
<div class="col">
|
4
4
|
<h3>
|
@@ -13,26 +13,34 @@
|
|
13
13
|
<div class="container">
|
14
14
|
<div class="row mb-5">
|
15
15
|
<div class="col-sm-12">
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
16
|
+
<%== partial('errors/watermark_offsets') %>
|
17
|
+
|
18
|
+
<% if @watermark_offsets.empty? %>
|
19
|
+
<%== partial 'errors/no_errors' %>
|
20
|
+
<% elsif @watermark_offsets.cleaned? %>
|
21
|
+
<%== partial 'errors/cleaned' %>
|
22
|
+
<% else %>
|
23
|
+
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
|
24
|
+
<thead>
|
25
|
+
<tr class="align-middle">
|
26
|
+
<th>Origin</th>
|
27
|
+
<th>Process name</th>
|
28
|
+
<th>Error</th>
|
29
|
+
<th>Occurred at</th>
|
30
|
+
<th></th>
|
31
|
+
</tr>
|
32
|
+
</thead>
|
33
|
+
<tbody>
|
34
|
+
<%==
|
35
|
+
each_partial(
|
36
|
+
@error_messages,
|
37
|
+
'errors/error',
|
38
|
+
local: :error_msg
|
39
|
+
)
|
40
|
+
%>
|
41
|
+
</tbody>
|
42
|
+
</table>
|
43
|
+
<% end %>
|
36
44
|
</div>
|
37
45
|
</div>
|
38
46
|
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div class="card text-bg-alt mb-3">
|
2
|
+
<div class="card-header">
|
3
|
+
<span>
|
4
|
+
<%= title %>
|
5
|
+
</span>
|
6
|
+
|
7
|
+
<span class="float-end">
|
8
|
+
<span class="badge text-bg-secondary">Info</span>
|
9
|
+
</span>
|
10
|
+
</div>
|
11
|
+
<div class="card-body">
|
12
|
+
<%== description %>
|
13
|
+
</div>
|
14
|
+
</div>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<p>
|
2
|
+
Below you can find information about your setup. This can be helpful when debugging or reporting bugs and issues.
|
3
|
+
</p>
|
4
|
+
|
5
|
+
<p class="mb-0">
|
6
|
+
<span class="badge bg-secondary">
|
7
|
+
<%= @sampler.ruby_version %>
|
8
|
+
</span>
|
9
|
+
|
10
|
+
<span class="badge bg-secondary">
|
11
|
+
karafka
|
12
|
+
<%= @sampler.karafka_version %>
|
13
|
+
</span>
|
14
|
+
|
15
|
+
<span class="badge bg-secondary">
|
16
|
+
karafka core
|
17
|
+
<%= @sampler.karafka_core_version %>
|
18
|
+
</span>
|
19
|
+
|
20
|
+
<span class="badge bg-secondary">
|
21
|
+
rdkafka
|
22
|
+
<%= @sampler.rdkafka_version %>
|
23
|
+
</span>
|
24
|
+
|
25
|
+
<span class="badge bg-secondary">
|
26
|
+
librdkafka
|
27
|
+
<%= @sampler.librdkafka_version %>
|
28
|
+
</span>
|
29
|
+
|
30
|
+
<span class="badge bg-secondary">
|
31
|
+
waterdrop
|
32
|
+
<%= @sampler.waterdrop_version %>
|
33
|
+
</span>
|
34
|
+
</p>
|
@@ -3,7 +3,6 @@
|
|
3
3
|
<div class="container mb-5">
|
4
4
|
<div class="row">
|
5
5
|
<div class="col-lg-10 offset-md-1">
|
6
|
-
|
7
6
|
<%==
|
8
7
|
partial(
|
9
8
|
"status/#{@status.connection.to_s}",
|
@@ -104,6 +103,15 @@
|
|
104
103
|
)
|
105
104
|
%>
|
106
105
|
|
106
|
+
<%==
|
107
|
+
partial(
|
108
|
+
'status/info',
|
109
|
+
locals: {
|
110
|
+
title: 'Components info',
|
111
|
+
description: partial('status/info/components')
|
112
|
+
}
|
113
|
+
)
|
114
|
+
%>
|
107
115
|
</div>
|
108
116
|
</div>
|
109
117
|
</div>
|
data/lib/karafka/web/version.rb
CHANGED
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciej Mensfeld
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
Qf04B9ceLUaC4fPVEz10FyobjaFoY4i32xRto3XnrzeAgfEe4swLq8bQsR3w/EF3
|
36
36
|
MGU0FeSV2Yj7Xc2x/7BzLK8xQn5l7Yy75iPF+KP3vVmDHnNl
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2023-03-
|
38
|
+
date: 2023-03-27 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: erubi
|
@@ -57,7 +57,7 @@ dependencies:
|
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 2.0.
|
60
|
+
version: 2.0.38
|
61
61
|
- - "<"
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: 3.0.0
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
requirements:
|
68
68
|
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 2.0.
|
70
|
+
version: 2.0.38
|
71
71
|
- - "<"
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: 3.0.0
|
@@ -186,6 +186,7 @@ files:
|
|
186
186
|
- lib/karafka/web/tracking/consumers/sampler.rb
|
187
187
|
- lib/karafka/web/tracking/memoized_shell.rb
|
188
188
|
- lib/karafka/web/tracking/reporter.rb
|
189
|
+
- lib/karafka/web/tracking/sampler.rb
|
189
190
|
- lib/karafka/web/tracking/ttl_array.rb
|
190
191
|
- lib/karafka/web/tracking/ttl_hash.rb
|
191
192
|
- lib/karafka/web/ui/app.rb
|
@@ -213,6 +214,7 @@ files:
|
|
213
214
|
- lib/karafka/web/ui/models/state.rb
|
214
215
|
- lib/karafka/web/ui/models/status.rb
|
215
216
|
- lib/karafka/web/ui/models/topic.rb
|
217
|
+
- lib/karafka/web/ui/models/watermark_offsets.rb
|
216
218
|
- lib/karafka/web/ui/pro/app.rb
|
217
219
|
- lib/karafka/web/ui/pro/controllers/cluster.rb
|
218
220
|
- lib/karafka/web/ui/pro/controllers/consumers.rb
|
@@ -243,8 +245,10 @@ files:
|
|
243
245
|
- lib/karafka/web/ui/pro/views/dlq/_topic.erb
|
244
246
|
- lib/karafka/web/ui/pro/views/dlq/index.erb
|
245
247
|
- lib/karafka/web/ui/pro/views/errors/_breadcrumbs.erb
|
248
|
+
- lib/karafka/web/ui/pro/views/errors/_cleaned.erb
|
246
249
|
- lib/karafka/web/ui/pro/views/errors/_detail.erb
|
247
250
|
- lib/karafka/web/ui/pro/views/errors/_error.erb
|
251
|
+
- lib/karafka/web/ui/pro/views/errors/_no_errors.erb
|
248
252
|
- lib/karafka/web/ui/pro/views/errors/_partition_option.erb
|
249
253
|
- lib/karafka/web/ui/pro/views/errors/index.erb
|
250
254
|
- lib/karafka/web/ui/pro/views/errors/show.erb
|
@@ -257,6 +261,10 @@ files:
|
|
257
261
|
- lib/karafka/web/ui/pro/views/explorer/_topic.erb
|
258
262
|
- lib/karafka/web/ui/pro/views/explorer/index.erb
|
259
263
|
- lib/karafka/web/ui/pro/views/explorer/partition.erb
|
264
|
+
- lib/karafka/web/ui/pro/views/explorer/partition/_cleaned.erb
|
265
|
+
- lib/karafka/web/ui/pro/views/explorer/partition/_empty.erb
|
266
|
+
- lib/karafka/web/ui/pro/views/explorer/partition/_messages.erb
|
267
|
+
- lib/karafka/web/ui/pro/views/explorer/partition/_watermark_offsets.erb
|
260
268
|
- lib/karafka/web/ui/pro/views/explorer/show.erb
|
261
269
|
- lib/karafka/web/ui/pro/views/health/_breadcrumbs.erb
|
262
270
|
- lib/karafka/web/ui/pro/views/health/_partition.erb
|
@@ -287,8 +295,11 @@ files:
|
|
287
295
|
- lib/karafka/web/ui/views/consumers/_summary.erb
|
288
296
|
- lib/karafka/web/ui/views/consumers/index.erb
|
289
297
|
- lib/karafka/web/ui/views/errors/_breadcrumbs.erb
|
298
|
+
- lib/karafka/web/ui/views/errors/_cleaned.erb
|
290
299
|
- lib/karafka/web/ui/views/errors/_detail.erb
|
291
300
|
- lib/karafka/web/ui/views/errors/_error.erb
|
301
|
+
- lib/karafka/web/ui/views/errors/_no_errors.erb
|
302
|
+
- lib/karafka/web/ui/views/errors/_watermark_offsets.erb
|
292
303
|
- lib/karafka/web/ui/views/errors/index.erb
|
293
304
|
- lib/karafka/web/ui/views/errors/show.erb
|
294
305
|
- lib/karafka/web/ui/views/jobs/_breadcrumbs.erb
|
@@ -313,6 +324,7 @@ files:
|
|
313
324
|
- lib/karafka/web/ui/views/status/_breadcrumbs.erb
|
314
325
|
- lib/karafka/web/ui/views/status/_failure.erb
|
315
326
|
- lib/karafka/web/ui/views/status/_halted.erb
|
327
|
+
- lib/karafka/web/ui/views/status/_info.erb
|
316
328
|
- lib/karafka/web/ui/views/status/_success.erb
|
317
329
|
- lib/karafka/web/ui/views/status/_warning.erb
|
318
330
|
- lib/karafka/web/ui/views/status/failures/_connection.erb
|
@@ -321,6 +333,7 @@ files:
|
|
321
333
|
- lib/karafka/web/ui/views/status/failures/_partitions.erb
|
322
334
|
- lib/karafka/web/ui/views/status/failures/_state_calculation.erb
|
323
335
|
- lib/karafka/web/ui/views/status/failures/_topics.erb
|
336
|
+
- lib/karafka/web/ui/views/status/info/_components.erb
|
324
337
|
- lib/karafka/web/ui/views/status/show.erb
|
325
338
|
- lib/karafka/web/ui/views/status/warnings/_pro_subscription.erb
|
326
339
|
- lib/karafka/web/version.rb
|
metadata.gz.sig
CHANGED
Binary file
|