karafka-web 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +60 -6
- data/Gemfile.lock +14 -14
- data/karafka-web.gemspec +3 -3
- data/lib/karafka/web/config.rb +11 -5
- data/lib/karafka/web/installer.rb +2 -3
- data/lib/karafka/web/tracking/consumers/contracts/consumer_group.rb +1 -1
- data/lib/karafka/web/tracking/consumers/contracts/job.rb +4 -1
- data/lib/karafka/web/tracking/consumers/contracts/partition.rb +1 -1
- data/lib/karafka/web/tracking/consumers/contracts/report.rb +1 -1
- data/lib/karafka/web/tracking/consumers/contracts/subscription_group.rb +1 -1
- data/lib/karafka/web/tracking/consumers/contracts/topic.rb +3 -1
- data/lib/karafka/web/tracking/consumers/listeners/base.rb +2 -2
- data/lib/karafka/web/tracking/consumers/listeners/errors.rb +8 -44
- data/lib/karafka/web/tracking/consumers/listeners/processing.rb +5 -0
- data/lib/karafka/web/tracking/consumers/reporter.rb +151 -0
- data/lib/karafka/web/tracking/contracts/base.rb +34 -0
- data/lib/karafka/web/tracking/contracts/error.rb +31 -0
- data/lib/karafka/web/tracking/helpers/error_info.rb +50 -0
- data/lib/karafka/web/tracking/memoized_shell.rb +1 -1
- data/lib/karafka/web/tracking/producers/listeners/base.rb +33 -0
- data/lib/karafka/web/tracking/producers/listeners/errors.rb +66 -0
- data/lib/karafka/web/tracking/producers/listeners/reporter.rb +21 -0
- data/lib/karafka/web/tracking/producers/reporter.rb +101 -0
- data/lib/karafka/web/tracking/producers/sampler.rb +42 -0
- data/lib/karafka/web/ui/controllers/consumers.rb +2 -4
- data/lib/karafka/web/ui/models/counters.rb +51 -0
- data/lib/karafka/web/ui/pro/controllers/consumers.rb +2 -3
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_job.erb +6 -6
- data/lib/karafka/web/ui/pro/views/consumers/index.erb +25 -21
- data/lib/karafka/web/ui/pro/views/consumers/jobs.erb +1 -1
- data/lib/karafka/web/ui/pro/views/errors/_breadcrumbs.erb +1 -2
- data/lib/karafka/web/ui/pro/views/errors/_error.erb +8 -6
- data/lib/karafka/web/ui/pro/views/errors/show.erb +3 -2
- data/lib/karafka/web/ui/public/stylesheets/application.css +4 -0
- data/lib/karafka/web/ui/views/consumers/_no_consumers.erb +9 -0
- data/lib/karafka/web/ui/views/consumers/index.erb +24 -20
- data/lib/karafka/web/ui/views/errors/_breadcrumbs.erb +1 -2
- data/lib/karafka/web/ui/views/errors/_detail.erb +9 -1
- data/lib/karafka/web/ui/views/errors/_error.erb +8 -6
- data/lib/karafka/web/ui/views/errors/show.erb +50 -2
- data/lib/karafka/web/ui/views/shared/_feature_pro.erb +4 -0
- data/lib/karafka/web/ui/views/shared/_pagination.erb +8 -2
- data/lib/karafka/web/ui/views/shared/exceptions/pro_only.erb +0 -4
- data/lib/karafka/web/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +26 -16
- metadata.gz.sig +0 -0
- data/lib/karafka/web/tracking/base_contract.rb +0 -31
- data/lib/karafka/web/tracking/reporter.rb +0 -144
- data/lib/karafka/web/ui/pro/views/consumers/_summary.erb +0 -81
- data/lib/karafka/web/ui/pro/views/errors/_cleaned.erb +0 -3
- data/lib/karafka/web/ui/pro/views/errors/_detail.erb +0 -31
- data/lib/karafka/web/ui/pro/views/errors/_no_errors.erb +0 -3
- data/lib/karafka/web/ui/pro/views/jobs/_breadcrumbs.erb +0 -5
- data/lib/karafka/web/ui/views/consumers/_breadcrumbs.erb +0 -27
@@ -9,14 +9,16 @@
|
|
9
9
|
|
10
10
|
<tr>
|
11
11
|
<td>
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
<span class="badge bg-secondary badge-topic">
|
13
|
+
<% if error[:details].key?(:topic) %>
|
14
|
+
<%= error[:details][:topic] %>: <%= error[:details][:partition] %>
|
15
|
+
<% else %>
|
16
|
+
<%= error[:type] %>
|
17
|
+
<% end %>
|
18
|
+
</span>
|
17
19
|
</td>
|
18
20
|
<td>
|
19
|
-
<%== error[:
|
21
|
+
<%== error[:process][:name] %>
|
20
22
|
</td>
|
21
23
|
<td>
|
22
24
|
<%= error[:error_class] %>:
|
@@ -1,12 +1,20 @@
|
|
1
1
|
<%==
|
2
2
|
type = @error_message.payload[:type]
|
3
3
|
error_class = @error_message.payload[:error_class]
|
4
|
-
offset = @error_message.offset
|
5
4
|
|
6
|
-
view_title("#{type}: #{error_class}
|
5
|
+
view_title("#{type}: #{error_class}")
|
7
6
|
%>
|
8
7
|
|
9
8
|
<div class="container">
|
9
|
+
<div class="row mb-4">
|
10
|
+
<div class="col-sm-12">
|
11
|
+
<h5 class="mb-2">
|
12
|
+
Metadata
|
13
|
+
</h5>
|
14
|
+
<hr/>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
|
10
18
|
<div class="row mb-5">
|
11
19
|
<div class="col-sm-12 table-responsive">
|
12
20
|
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
|
@@ -27,4 +35,44 @@
|
|
27
35
|
</table>
|
28
36
|
</div>
|
29
37
|
</div>
|
38
|
+
|
39
|
+
<div class="row mb-2">
|
40
|
+
<div class="col-sm-12">
|
41
|
+
<h5 class="mb-2">
|
42
|
+
Backtrace
|
43
|
+
</h5>
|
44
|
+
<hr/>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
|
48
|
+
<div class="mb-4">
|
49
|
+
<%== partial 'shared/feature_pro' %>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
<div class="row mb-4">
|
53
|
+
<div class="col-sm-12">
|
54
|
+
<div class="card">
|
55
|
+
<div class="card-body">
|
56
|
+
<pre class="m-0 p-0 blurred"><code class="wrapped json p-0 m-0">this is just an example backtrace
|
57
|
+
please subscribe to our Pro offering to be able to view the real one
|
58
|
+
gems/karafka-rdkafka/lib/rdkafka/consumer.rb:255:in `query_watermark_offsets'
|
59
|
+
gems/karafka/lib/karafka/admin.rb:56:in `block in read_topic'
|
60
|
+
gems/karafka/lib/karafka/admin.rb:184:in `with_consumer'
|
61
|
+
gems/karafka/lib/karafka/admin.rb:55:in `read_topic'
|
62
|
+
/mnt/software/Karafka/karafka-web/lib/karafka/web/processing/consumers/state.rb:19:in `current'
|
63
|
+
/mnt/software/Karafka/karafka-web/lib/karafka/web/processing/consumers/aggregator.rb:45:in `state'
|
64
|
+
/mnt/software/Karafka/karafka-web/lib/karafka/web/processing/consumers/aggregator.rb:38:in `to_json'
|
65
|
+
gems/karafka/lib/karafka/processing/strategies/default.rb:136:in `block in handle_shutdown'
|
66
|
+
gems/karafka-core/lib/karafka/core/monitoring/notifications.rb:118:in `measure_time_taken'
|
67
|
+
gems/karafka-core/lib/karafka/core/monitoring/notifications.rb:94:in `instrument'
|
68
|
+
gems/karafka-core/lib/karafka/core/monitoring/monitor.rb:34:in `instrument'
|
69
|
+
gems/karafka/lib/karafka/processing/strategies/default.rb:135:in `handle_shutdown'
|
70
|
+
gems/karafka/lib/karafka/base_consumer.rb:134:in `on_shutdown'
|
71
|
+
gems/karafka/lib/karafka/processing/executor.rb:123:in `shutdown'
|
72
|
+
gems/karafka/lib/karafka/processing/jobs/shutdown.rb:18:in `call'
|
73
|
+
gems/karafka/lib/karafka/helpers/async.rb:28:in `block in async_call'</code></pre>
|
74
|
+
</div>
|
75
|
+
</div>
|
76
|
+
</div>
|
77
|
+
</div>
|
30
78
|
</div>
|
@@ -3,9 +3,15 @@
|
|
3
3
|
<div class="row">
|
4
4
|
<nav>
|
5
5
|
<ul class="pagination justify-content-center">
|
6
|
+
<li class="page-item <%= 'disabled' if @current_page <= 1 %>">
|
7
|
+
<a class="page-link" href="<%= current_path(page: 1) %>">
|
8
|
+
<span>«</span>
|
9
|
+
</a>
|
10
|
+
</li>
|
11
|
+
|
6
12
|
<li class="page-item <%= 'disabled' if @current_page <= 1 %>">
|
7
13
|
<a class="page-link" href="<%= current_path(page: @current_page - 1) %>">
|
8
|
-
<span>&
|
14
|
+
<span>‹ Prev</span>
|
9
15
|
</a>
|
10
16
|
</li>
|
11
17
|
|
@@ -17,7 +23,7 @@
|
|
17
23
|
|
18
24
|
<li class="page-item <%= 'disabled' unless @next_page %>">
|
19
25
|
<a class="page-link" href="<%= current_path(page: @next_page) %>">
|
20
|
-
<span>Next &
|
26
|
+
<span>Next ›</span>
|
21
27
|
</a>
|
22
28
|
</li>
|
23
29
|
</ul>
|
@@ -37,10 +37,6 @@
|
|
37
37
|
<li>Architecture consultations</li>
|
38
38
|
</ul>
|
39
39
|
|
40
|
-
<p class="mb-5">
|
41
|
-
If you were looking for a given process or other real-time information, the state might have changed, and the information you are looking for no longer exists.
|
42
|
-
</p>
|
43
|
-
|
44
40
|
<p>
|
45
41
|
<a href="<%= root_path %>" class="btn btn-primary">Go Home</a>
|
46
42
|
<a href="https://karafka.io/#become-pro" class="btn btn-success" target="_blank">Become Pro!</a>
|
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.6.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-
|
38
|
+
date: 2023-06-13 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.
|
60
|
+
version: 2.1.4
|
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.
|
70
|
+
version: 2.1.4
|
71
71
|
- - "<"
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: 3.0.0
|
@@ -77,7 +77,7 @@ dependencies:
|
|
77
77
|
requirements:
|
78
78
|
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: 2.0.
|
80
|
+
version: 2.0.13
|
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.0.
|
90
|
+
version: 2.0.13
|
91
91
|
- - "<"
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: 3.0.0
|
@@ -97,14 +97,20 @@ dependencies:
|
|
97
97
|
requirements:
|
98
98
|
- - "~>"
|
99
99
|
- !ruby/object:Gem::Version
|
100
|
-
version: '3.
|
100
|
+
version: '3.68'
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.68'
|
101
104
|
type: :runtime
|
102
105
|
prerelease: false
|
103
106
|
version_requirements: !ruby/object:Gem::Requirement
|
104
107
|
requirements:
|
105
108
|
- - "~>"
|
106
109
|
- !ruby/object:Gem::Version
|
107
|
-
version: '3.
|
110
|
+
version: '3.68'
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '3.68'
|
108
114
|
- !ruby/object:Gem::Dependency
|
109
115
|
name: tilt
|
110
116
|
requirement: !ruby/object:Gem::Requirement
|
@@ -171,7 +177,6 @@ files:
|
|
171
177
|
- lib/karafka/web/processing/consumer.rb
|
172
178
|
- lib/karafka/web/processing/consumers/aggregator.rb
|
173
179
|
- lib/karafka/web/processing/consumers/state.rb
|
174
|
-
- lib/karafka/web/tracking/base_contract.rb
|
175
180
|
- lib/karafka/web/tracking/consumers/contracts/consumer_group.rb
|
176
181
|
- lib/karafka/web/tracking/consumers/contracts/job.rb
|
177
182
|
- lib/karafka/web/tracking/consumers/contracts/partition.rb
|
@@ -185,9 +190,17 @@ files:
|
|
185
190
|
- lib/karafka/web/tracking/consumers/listeners/statistics.rb
|
186
191
|
- lib/karafka/web/tracking/consumers/listeners/status.rb
|
187
192
|
- lib/karafka/web/tracking/consumers/listeners/tags.rb
|
193
|
+
- lib/karafka/web/tracking/consumers/reporter.rb
|
188
194
|
- lib/karafka/web/tracking/consumers/sampler.rb
|
195
|
+
- lib/karafka/web/tracking/contracts/base.rb
|
196
|
+
- lib/karafka/web/tracking/contracts/error.rb
|
197
|
+
- lib/karafka/web/tracking/helpers/error_info.rb
|
189
198
|
- lib/karafka/web/tracking/memoized_shell.rb
|
190
|
-
- lib/karafka/web/tracking/
|
199
|
+
- lib/karafka/web/tracking/producers/listeners/base.rb
|
200
|
+
- lib/karafka/web/tracking/producers/listeners/errors.rb
|
201
|
+
- lib/karafka/web/tracking/producers/listeners/reporter.rb
|
202
|
+
- lib/karafka/web/tracking/producers/reporter.rb
|
203
|
+
- lib/karafka/web/tracking/producers/sampler.rb
|
191
204
|
- lib/karafka/web/tracking/sampler.rb
|
192
205
|
- lib/karafka/web/tracking/ttl_array.rb
|
193
206
|
- lib/karafka/web/tracking/ttl_hash.rb
|
@@ -207,6 +220,7 @@ files:
|
|
207
220
|
- lib/karafka/web/ui/lib/hash_proxy.rb
|
208
221
|
- lib/karafka/web/ui/lib/paginate_array.rb
|
209
222
|
- lib/karafka/web/ui/models/consumer_group.rb
|
223
|
+
- lib/karafka/web/ui/models/counters.rb
|
210
224
|
- lib/karafka/web/ui/models/health.rb
|
211
225
|
- lib/karafka/web/ui/models/job.rb
|
212
226
|
- lib/karafka/web/ui/models/message.rb
|
@@ -231,7 +245,6 @@ files:
|
|
231
245
|
- lib/karafka/web/ui/pro/views/consumers/_breadcrumbs.erb
|
232
246
|
- lib/karafka/web/ui/pro/views/consumers/_consumer.erb
|
233
247
|
- lib/karafka/web/ui/pro/views/consumers/_counters.erb
|
234
|
-
- lib/karafka/web/ui/pro/views/consumers/_summary.erb
|
235
248
|
- lib/karafka/web/ui/pro/views/consumers/consumer/_consumer_group.erb
|
236
249
|
- lib/karafka/web/ui/pro/views/consumers/consumer/_job.erb
|
237
250
|
- lib/karafka/web/ui/pro/views/consumers/consumer/_metrics.erb
|
@@ -249,10 +262,7 @@ files:
|
|
249
262
|
- lib/karafka/web/ui/pro/views/dlq/_topic.erb
|
250
263
|
- lib/karafka/web/ui/pro/views/dlq/index.erb
|
251
264
|
- lib/karafka/web/ui/pro/views/errors/_breadcrumbs.erb
|
252
|
-
- lib/karafka/web/ui/pro/views/errors/_cleaned.erb
|
253
|
-
- lib/karafka/web/ui/pro/views/errors/_detail.erb
|
254
265
|
- lib/karafka/web/ui/pro/views/errors/_error.erb
|
255
|
-
- lib/karafka/web/ui/pro/views/errors/_no_errors.erb
|
256
266
|
- lib/karafka/web/ui/pro/views/errors/_partition_option.erb
|
257
267
|
- lib/karafka/web/ui/pro/views/errors/index.erb
|
258
268
|
- lib/karafka/web/ui/pro/views/errors/show.erb
|
@@ -273,7 +283,6 @@ files:
|
|
273
283
|
- lib/karafka/web/ui/pro/views/health/_breadcrumbs.erb
|
274
284
|
- lib/karafka/web/ui/pro/views/health/_partition.erb
|
275
285
|
- lib/karafka/web/ui/pro/views/health/index.erb
|
276
|
-
- lib/karafka/web/ui/pro/views/jobs/_breadcrumbs.erb
|
277
286
|
- lib/karafka/web/ui/pro/views/jobs/_job.erb
|
278
287
|
- lib/karafka/web/ui/pro/views/jobs/_no_jobs.erb
|
279
288
|
- lib/karafka/web/ui/pro/views/jobs/index.erb
|
@@ -293,9 +302,9 @@ files:
|
|
293
302
|
- lib/karafka/web/ui/views/cluster/_broker.erb
|
294
303
|
- lib/karafka/web/ui/views/cluster/_partition.erb
|
295
304
|
- lib/karafka/web/ui/views/cluster/index.erb
|
296
|
-
- lib/karafka/web/ui/views/consumers/_breadcrumbs.erb
|
297
305
|
- lib/karafka/web/ui/views/consumers/_consumer.erb
|
298
306
|
- lib/karafka/web/ui/views/consumers/_counters.erb
|
307
|
+
- lib/karafka/web/ui/views/consumers/_no_consumers.erb
|
299
308
|
- lib/karafka/web/ui/views/consumers/_summary.erb
|
300
309
|
- lib/karafka/web/ui/views/consumers/index.erb
|
301
310
|
- lib/karafka/web/ui/views/errors/_breadcrumbs.erb
|
@@ -320,6 +329,7 @@ files:
|
|
320
329
|
- lib/karafka/web/ui/views/shared/_become_pro.erb
|
321
330
|
- lib/karafka/web/ui/views/shared/_brand.erb
|
322
331
|
- lib/karafka/web/ui/views/shared/_content.erb
|
332
|
+
- lib/karafka/web/ui/views/shared/_feature_pro.erb
|
323
333
|
- lib/karafka/web/ui/views/shared/_header.erb
|
324
334
|
- lib/karafka/web/ui/views/shared/_navigation.erb
|
325
335
|
- lib/karafka/web/ui/views/shared/_pagination.erb
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Karafka
|
4
|
-
module Web
|
5
|
-
module Tracking
|
6
|
-
# Base for all the metric related contracts
|
7
|
-
class BaseContract < ::Karafka::Core::Contractable::Contract
|
8
|
-
class << self
|
9
|
-
# This layer is not for users extensive feedback, thus we can easily use the minimum
|
10
|
-
# error messaging there is.
|
11
|
-
def configure
|
12
|
-
super do |config|
|
13
|
-
config.error_messages = YAML.safe_load(
|
14
|
-
File.read(
|
15
|
-
File.join(Karafka::Web.gem_root, 'config', 'locales', 'errors.yml')
|
16
|
-
)
|
17
|
-
).fetch('en').fetch('validations').fetch('web')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# @param data [Hash] data for validation
|
23
|
-
# @return [Boolean] true if all good
|
24
|
-
# @raise [Errors::ContractError] invalid report
|
25
|
-
def validate!(data)
|
26
|
-
super(data, Errors::Tracking::ContractError)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Karafka
|
4
|
-
module Web
|
5
|
-
module Tracking
|
6
|
-
# Reports the collected data about the process and sends it, so we can use it in the UI
|
7
|
-
class Reporter
|
8
|
-
include ::Karafka::Core::Helpers::Time
|
9
|
-
include ::Karafka::Helpers::Async
|
10
|
-
|
11
|
-
# Minimum number of messages to produce to produce then in sync mode
|
12
|
-
# This acts as a small back-off not to overload the system in case we would have extremely
|
13
|
-
# big number of errors happening
|
14
|
-
PRODUCE_SYNC_THRESHOLD = 25
|
15
|
-
|
16
|
-
private_constant :PRODUCE_SYNC_THRESHOLD
|
17
|
-
|
18
|
-
# This mutex is shared between tracker and samplers so there is no case where metrics
|
19
|
-
# would be collected same time tracker reports
|
20
|
-
MUTEX = Mutex.new
|
21
|
-
|
22
|
-
def initialize
|
23
|
-
# Move back so first report is dispatched fast to indicate, that the process is alive
|
24
|
-
@tracked_at = monotonic_now - 10_000
|
25
|
-
@consumer_contract = Consumers::Contracts::Report.new
|
26
|
-
end
|
27
|
-
|
28
|
-
# Dispatches the current state from sampler to appropriate topics
|
29
|
-
#
|
30
|
-
# @param forced [Boolean] should we report bypassing the time frequency or should we report
|
31
|
-
# only in case we would not send the report for long enough time.
|
32
|
-
def report(forced: false)
|
33
|
-
MUTEX.synchronize do
|
34
|
-
# Start background thread only when needed
|
35
|
-
# This prevents us from starting it too early or for non-consumer processes where
|
36
|
-
# Karafka is being included
|
37
|
-
async_call unless @running
|
38
|
-
|
39
|
-
return unless report?(forced)
|
40
|
-
|
41
|
-
@tracked_at = monotonic_now
|
42
|
-
|
43
|
-
consumer_report = consumer_sampler.to_report
|
44
|
-
|
45
|
-
@consumer_contract.validate!(consumer_report)
|
46
|
-
|
47
|
-
process_name = consumer_report[:process][:name]
|
48
|
-
|
49
|
-
# Report consumers statuses
|
50
|
-
messages = [
|
51
|
-
{
|
52
|
-
topic: ::Karafka::Web.config.topics.consumers.reports,
|
53
|
-
payload: consumer_report.to_json,
|
54
|
-
key: process_name,
|
55
|
-
partition: 0
|
56
|
-
}
|
57
|
-
]
|
58
|
-
|
59
|
-
# Report errors that occurred (if any)
|
60
|
-
messages += consumer_sampler.errors.map do |error|
|
61
|
-
{
|
62
|
-
topic: Karafka::Web.config.topics.errors,
|
63
|
-
payload: error.to_json,
|
64
|
-
# Always dispatch errors from the same process to the same partition
|
65
|
-
key: process_name
|
66
|
-
}
|
67
|
-
end
|
68
|
-
|
69
|
-
produce(messages)
|
70
|
-
|
71
|
-
# Clear the sampler so it tracks new state changes without previous once impacting
|
72
|
-
# the data
|
73
|
-
consumer_sampler.clear
|
74
|
-
end
|
75
|
-
# Since we run this in a background thread, there may be a case upon shutdown, where the
|
76
|
-
# producer is closed right before a potential dispatch. It is not worth dealing with this
|
77
|
-
# and we can just safely ignore this
|
78
|
-
rescue WaterDrop::Errors::ProducerClosedError
|
79
|
-
nil
|
80
|
-
end
|
81
|
-
|
82
|
-
# Reports bypassing frequency check. This can be used to report when state changes in the
|
83
|
-
# process drastically. For example when process is stopping, we want to indicate this as
|
84
|
-
# fast as possible in the UI, etc.
|
85
|
-
def report!
|
86
|
-
report(forced: true)
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
# Reports the process state once in a while
|
92
|
-
def call
|
93
|
-
@running = true
|
94
|
-
|
95
|
-
loop do
|
96
|
-
report
|
97
|
-
|
98
|
-
# We won't track more often anyhow but want to try frequently not to miss a window
|
99
|
-
# We need to convert the sleep interval into seconds for sleep
|
100
|
-
sleep(::Karafka::Web.config.tracking.interval / 1_000 / 10)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# @param forced [Boolean] is this report forced. Forced means that as long as we can flush
|
105
|
-
# we will flush
|
106
|
-
# @return [Boolean] Should we report or is it not yet time to do so
|
107
|
-
def report?(forced)
|
108
|
-
# We never report in initializing phase because things are not yet fully configured
|
109
|
-
return false if ::Karafka::App.initializing?
|
110
|
-
# We never report in the initialized because server is not yet ready until Karafka is
|
111
|
-
# fully running and some of the things like listeners are not yet available
|
112
|
-
return false if ::Karafka::App.initialized?
|
113
|
-
|
114
|
-
return true if forced
|
115
|
-
|
116
|
-
(monotonic_now - @tracked_at) >= ::Karafka::Web.config.tracking.interval
|
117
|
-
end
|
118
|
-
|
119
|
-
# @return [Object] sampler for the metrics
|
120
|
-
def consumer_sampler
|
121
|
-
@consumer_sampler ||= ::Karafka::Web.config.tracking.consumers.sampler
|
122
|
-
end
|
123
|
-
|
124
|
-
# Produces messages to Kafka.
|
125
|
-
#
|
126
|
-
# @param messages [Array<Hash>]
|
127
|
-
#
|
128
|
-
# @note We pick either sync or async dependent on number of messages. The trick here is,
|
129
|
-
# that we do not want to end up overloading the internal queue with messages in case
|
130
|
-
# someone has a lot of errors from processing or other errors. Producing sync will wait
|
131
|
-
# for the delivery, hence will slow things down a little bit. On the other hand during
|
132
|
-
# normal operations we should not have that many messages to dispatch and it should not
|
133
|
-
# slowdown any processing.
|
134
|
-
def produce(messages)
|
135
|
-
if messages.count >= PRODUCE_SYNC_THRESHOLD
|
136
|
-
::Karafka.producer.produce_many_sync(messages)
|
137
|
-
else
|
138
|
-
::Karafka.producer.produce_many_async(messages)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
<div id="summary" class="container text-center mb-5">
|
2
|
-
<div class="row">
|
3
|
-
|
4
|
-
<div class="col-lg-2 offset-md-1">
|
5
|
-
<div class="card mb-0">
|
6
|
-
<div class="card-body">
|
7
|
-
<p class="card-text">
|
8
|
-
<div class="stat mb-1">
|
9
|
-
<%= @counters.processes %>
|
10
|
-
</div>
|
11
|
-
<div class="desc">
|
12
|
-
Processes
|
13
|
-
</div>
|
14
|
-
</p>
|
15
|
-
</div>
|
16
|
-
</div>
|
17
|
-
</div>
|
18
|
-
|
19
|
-
<div class="col-lg-2">
|
20
|
-
<div class="card mb-0">
|
21
|
-
<div class="card-body">
|
22
|
-
<p class="card-text">
|
23
|
-
<div class="stat mb-1">
|
24
|
-
<%= @counters.threads_count %>
|
25
|
-
</div>
|
26
|
-
<div class="desc">
|
27
|
-
Worker threads
|
28
|
-
</div>
|
29
|
-
</p>
|
30
|
-
</div>
|
31
|
-
</div>
|
32
|
-
</div>
|
33
|
-
|
34
|
-
<div class="col-lg-2">
|
35
|
-
<div class="card mb-0">
|
36
|
-
<div class="card-body">
|
37
|
-
<p class="card-text">
|
38
|
-
<div class="stat mb-1">
|
39
|
-
<%= @counters.listeners_count %>
|
40
|
-
</div>
|
41
|
-
<div class="desc">
|
42
|
-
Listeners
|
43
|
-
</div>
|
44
|
-
</p>
|
45
|
-
</div>
|
46
|
-
</div>
|
47
|
-
</div>
|
48
|
-
|
49
|
-
<div class="col-lg-2">
|
50
|
-
<div class="card mb-0">
|
51
|
-
<div class="card-body">
|
52
|
-
<p class="card-text">
|
53
|
-
<div class="stat mb-1">
|
54
|
-
<%= @counters.utilization.round(2) %>
|
55
|
-
%
|
56
|
-
</div>
|
57
|
-
<div class="desc">
|
58
|
-
Utilization
|
59
|
-
</div>
|
60
|
-
</p>
|
61
|
-
</div>
|
62
|
-
</div>
|
63
|
-
</div>
|
64
|
-
|
65
|
-
<div class="col-lg-2">
|
66
|
-
<div class="card mb-0">
|
67
|
-
<div class="card-body">
|
68
|
-
<p class="card-text">
|
69
|
-
<div class="stat mb-1">
|
70
|
-
<%= format_memory @counters.rss %>
|
71
|
-
</div>
|
72
|
-
<div class="desc">
|
73
|
-
RSS
|
74
|
-
</div>
|
75
|
-
</p>
|
76
|
-
</div>
|
77
|
-
</div>
|
78
|
-
</div>
|
79
|
-
|
80
|
-
</div>
|
81
|
-
</div>
|
@@ -1,31 +0,0 @@
|
|
1
|
-
<% if v.is_a?(Hash) %>
|
2
|
-
<% v.each do |k2, v2| %>
|
3
|
-
<tr>
|
4
|
-
<td>
|
5
|
-
<%= "#{k}.#{k2}" %>
|
6
|
-
</td>
|
7
|
-
<td>
|
8
|
-
<% if %w[sasl ssl].any? { |scope| k2.to_s.include?(scope) } %>
|
9
|
-
***
|
10
|
-
<% elsif k2.to_s == 'tags' %>
|
11
|
-
<%== tags(v2) %>
|
12
|
-
<% else %>
|
13
|
-
<%= v2 %>
|
14
|
-
<% end %>
|
15
|
-
</td>
|
16
|
-
</tr>
|
17
|
-
<% end %>
|
18
|
-
<% else %>
|
19
|
-
<tr>
|
20
|
-
<td>
|
21
|
-
<%= k %>
|
22
|
-
</td>
|
23
|
-
<td>
|
24
|
-
<% if k == :occurred_at %>
|
25
|
-
<%== relative_time v %>
|
26
|
-
<% else %>
|
27
|
-
<%= v %>
|
28
|
-
<% end %>
|
29
|
-
</td>
|
30
|
-
</tr>
|
31
|
-
<% end %>
|
@@ -1,27 +0,0 @@
|
|
1
|
-
<% if @process %>
|
2
|
-
<li class="breadcrumb-item">
|
3
|
-
<a href="<%= root_path('consumers') %>">
|
4
|
-
Consumers
|
5
|
-
</a>
|
6
|
-
</li>
|
7
|
-
|
8
|
-
<li class="breadcrumb-item">
|
9
|
-
<a href="<%= root_path('consumers', @process.id, 'subscriptions') %>">
|
10
|
-
<%= @process.name %>
|
11
|
-
</a>
|
12
|
-
</li>
|
13
|
-
|
14
|
-
<% if current_path.include?('/jobs') %>
|
15
|
-
<li class="breadcrumb-item">
|
16
|
-
<a href="<%= root_path('consumers', @process.id, 'jobs') %>">
|
17
|
-
Running jobs
|
18
|
-
</a>
|
19
|
-
</li>
|
20
|
-
<% else %>
|
21
|
-
<li class="breadcrumb-item">
|
22
|
-
<a href="<%= root_path('consumers', @process.id, 'subscriptions') %>">
|
23
|
-
Active subscriptions
|
24
|
-
</a>
|
25
|
-
</li>
|
26
|
-
<% end %>
|
27
|
-
<% end %>
|