karafka-web 0.1.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 +7 -0
- checksums.yaml.gz.sig +3 -0
- data/.coditsu/ci.yml +3 -0
- data/.diffend.yml +3 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/ci.yml +49 -0
- data/.gitignore +69 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +9 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +52 -0
- data/LICENSE +17 -0
- data/README.md +29 -0
- data/bin/karafka-web +33 -0
- data/certs/cert_chain.pem +26 -0
- data/config/locales/errors.yml +9 -0
- data/karafka-web.gemspec +44 -0
- data/lib/karafka/web/app.rb +17 -0
- data/lib/karafka/web/config.rb +80 -0
- data/lib/karafka/web/deserializer.rb +20 -0
- data/lib/karafka/web/errors.rb +25 -0
- data/lib/karafka/web/installer.rb +124 -0
- data/lib/karafka/web/processing/consumer.rb +66 -0
- data/lib/karafka/web/processing/consumers/aggregator.rb +130 -0
- data/lib/karafka/web/processing/consumers/state.rb +32 -0
- data/lib/karafka/web/tracking/base_contract.rb +31 -0
- data/lib/karafka/web/tracking/consumers/contracts/consumer_group.rb +33 -0
- data/lib/karafka/web/tracking/consumers/contracts/job.rb +26 -0
- data/lib/karafka/web/tracking/consumers/contracts/partition.rb +22 -0
- data/lib/karafka/web/tracking/consumers/contracts/report.rb +95 -0
- data/lib/karafka/web/tracking/consumers/contracts/topic.rb +29 -0
- data/lib/karafka/web/tracking/consumers/listeners/base.rb +33 -0
- data/lib/karafka/web/tracking/consumers/listeners/errors.rb +107 -0
- data/lib/karafka/web/tracking/consumers/listeners/pausing.rb +45 -0
- data/lib/karafka/web/tracking/consumers/listeners/processing.rb +157 -0
- data/lib/karafka/web/tracking/consumers/listeners/statistics.rb +123 -0
- data/lib/karafka/web/tracking/consumers/listeners/status.rb +58 -0
- data/lib/karafka/web/tracking/consumers/sampler.rb +216 -0
- data/lib/karafka/web/tracking/memoized_shell.rb +48 -0
- data/lib/karafka/web/tracking/reporter.rb +144 -0
- data/lib/karafka/web/tracking/ttl_array.rb +59 -0
- data/lib/karafka/web/tracking/ttl_hash.rb +16 -0
- data/lib/karafka/web/ui/app.rb +78 -0
- data/lib/karafka/web/ui/base.rb +77 -0
- data/lib/karafka/web/ui/controllers/base.rb +40 -0
- data/lib/karafka/web/ui/controllers/become_pro.rb +17 -0
- data/lib/karafka/web/ui/controllers/cluster.rb +24 -0
- data/lib/karafka/web/ui/controllers/consumers.rb +27 -0
- data/lib/karafka/web/ui/controllers/errors.rb +43 -0
- data/lib/karafka/web/ui/controllers/jobs.rb +33 -0
- data/lib/karafka/web/ui/controllers/requests/params.rb +30 -0
- data/lib/karafka/web/ui/controllers/responses/data.rb +26 -0
- data/lib/karafka/web/ui/controllers/routing.rb +30 -0
- data/lib/karafka/web/ui/helpers/application_helper.rb +144 -0
- data/lib/karafka/web/ui/lib/hash_proxy.rb +66 -0
- data/lib/karafka/web/ui/lib/paginate_array.rb +38 -0
- data/lib/karafka/web/ui/models/consumer_group.rb +20 -0
- data/lib/karafka/web/ui/models/health.rb +44 -0
- data/lib/karafka/web/ui/models/job.rb +13 -0
- data/lib/karafka/web/ui/models/message.rb +99 -0
- data/lib/karafka/web/ui/models/partition.rb +13 -0
- data/lib/karafka/web/ui/models/process.rb +56 -0
- data/lib/karafka/web/ui/models/processes.rb +86 -0
- data/lib/karafka/web/ui/models/state.rb +67 -0
- data/lib/karafka/web/ui/models/topic.rb +19 -0
- data/lib/karafka/web/ui/pro/app.rb +120 -0
- data/lib/karafka/web/ui/pro/controllers/cluster.rb +16 -0
- data/lib/karafka/web/ui/pro/controllers/consumers.rb +54 -0
- data/lib/karafka/web/ui/pro/controllers/dlq.rb +44 -0
- data/lib/karafka/web/ui/pro/controllers/errors.rb +57 -0
- data/lib/karafka/web/ui/pro/controllers/explorer.rb +79 -0
- data/lib/karafka/web/ui/pro/controllers/health.rb +33 -0
- data/lib/karafka/web/ui/pro/controllers/jobs.rb +26 -0
- data/lib/karafka/web/ui/pro/controllers/routing.rb +26 -0
- data/lib/karafka/web/ui/pro/views/consumers/_breadcrumbs.erb +27 -0
- data/lib/karafka/web/ui/pro/views/consumers/_consumer.erb +60 -0
- data/lib/karafka/web/ui/pro/views/consumers/_counters.erb +50 -0
- data/lib/karafka/web/ui/pro/views/consumers/_summary.erb +81 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_consumer_group.erb +109 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_job.erb +26 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_metrics.erb +126 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_no_jobs.erb +9 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_no_subscriptions.erb +9 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_partition.erb +32 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_stopped.erb +10 -0
- data/lib/karafka/web/ui/pro/views/consumers/consumer/_tabs.erb +20 -0
- data/lib/karafka/web/ui/pro/views/consumers/index.erb +30 -0
- data/lib/karafka/web/ui/pro/views/consumers/jobs.erb +42 -0
- data/lib/karafka/web/ui/pro/views/consumers/subscriptions.erb +23 -0
- data/lib/karafka/web/ui/pro/views/dlq/_breadcrumbs.erb +5 -0
- data/lib/karafka/web/ui/pro/views/dlq/_no_topics.erb +9 -0
- data/lib/karafka/web/ui/pro/views/dlq/_topic.erb +12 -0
- data/lib/karafka/web/ui/pro/views/dlq/index.erb +16 -0
- data/lib/karafka/web/ui/pro/views/errors/_breadcrumbs.erb +25 -0
- data/lib/karafka/web/ui/pro/views/errors/_detail.erb +29 -0
- data/lib/karafka/web/ui/pro/views/errors/_error.erb +26 -0
- data/lib/karafka/web/ui/pro/views/errors/_partition_option.erb +7 -0
- data/lib/karafka/web/ui/pro/views/errors/index.erb +58 -0
- data/lib/karafka/web/ui/pro/views/errors/show.erb +56 -0
- data/lib/karafka/web/ui/pro/views/explorer/_breadcrumbs.erb +29 -0
- data/lib/karafka/web/ui/pro/views/explorer/_detail.erb +21 -0
- data/lib/karafka/web/ui/pro/views/explorer/_encryption_enabled.erb +18 -0
- data/lib/karafka/web/ui/pro/views/explorer/_failed_deserialization.erb +4 -0
- data/lib/karafka/web/ui/pro/views/explorer/_message.erb +16 -0
- data/lib/karafka/web/ui/pro/views/explorer/_partition_option.erb +7 -0
- data/lib/karafka/web/ui/pro/views/explorer/_topic.erb +12 -0
- data/lib/karafka/web/ui/pro/views/explorer/index.erb +17 -0
- data/lib/karafka/web/ui/pro/views/explorer/partition.erb +56 -0
- data/lib/karafka/web/ui/pro/views/explorer/show.erb +65 -0
- data/lib/karafka/web/ui/pro/views/health/_breadcrumbs.erb +5 -0
- data/lib/karafka/web/ui/pro/views/health/_partition.erb +35 -0
- data/lib/karafka/web/ui/pro/views/health/index.erb +60 -0
- data/lib/karafka/web/ui/pro/views/jobs/_breadcrumbs.erb +5 -0
- data/lib/karafka/web/ui/pro/views/jobs/_job.erb +31 -0
- data/lib/karafka/web/ui/pro/views/jobs/_no_jobs.erb +9 -0
- data/lib/karafka/web/ui/pro/views/jobs/index.erb +34 -0
- data/lib/karafka/web/ui/pro/views/shared/_navigation.erb +57 -0
- data/lib/karafka/web/ui/public/images/favicon.ico +0 -0
- data/lib/karafka/web/ui/public/images/logo.svg +28 -0
- data/lib/karafka/web/ui/public/javascripts/application.js +41 -0
- data/lib/karafka/web/ui/public/javascripts/bootstrap.min.js +7 -0
- data/lib/karafka/web/ui/public/javascripts/highlight.min.js +337 -0
- data/lib/karafka/web/ui/public/javascripts/live_poll.js +124 -0
- data/lib/karafka/web/ui/public/javascripts/timeago.min.js +1 -0
- data/lib/karafka/web/ui/public/stylesheets/application.css +106 -0
- data/lib/karafka/web/ui/public/stylesheets/bootstrap.min.css +7 -0
- data/lib/karafka/web/ui/public/stylesheets/bootstrap.min.css.map +1 -0
- data/lib/karafka/web/ui/public/stylesheets/highlight.min.css +10 -0
- data/lib/karafka/web/ui/views/cluster/_breadcrumbs.erb +5 -0
- data/lib/karafka/web/ui/views/cluster/_broker.erb +5 -0
- data/lib/karafka/web/ui/views/cluster/_partition.erb +22 -0
- data/lib/karafka/web/ui/views/cluster/index.erb +72 -0
- data/lib/karafka/web/ui/views/consumers/_breadcrumbs.erb +27 -0
- data/lib/karafka/web/ui/views/consumers/_consumer.erb +43 -0
- data/lib/karafka/web/ui/views/consumers/_counters.erb +44 -0
- data/lib/karafka/web/ui/views/consumers/_summary.erb +81 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_consumer_group.erb +109 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_job.erb +26 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_metrics.erb +126 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_no_jobs.erb +9 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_no_subscriptions.erb +9 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_partition.erb +32 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_stopped.erb +10 -0
- data/lib/karafka/web/ui/views/consumers/consumer/_tabs.erb +20 -0
- data/lib/karafka/web/ui/views/consumers/index.erb +29 -0
- data/lib/karafka/web/ui/views/errors/_breadcrumbs.erb +19 -0
- data/lib/karafka/web/ui/views/errors/_detail.erb +29 -0
- data/lib/karafka/web/ui/views/errors/_error.erb +26 -0
- data/lib/karafka/web/ui/views/errors/index.erb +38 -0
- data/lib/karafka/web/ui/views/errors/show.erb +30 -0
- data/lib/karafka/web/ui/views/jobs/_breadcrumbs.erb +5 -0
- data/lib/karafka/web/ui/views/jobs/_job.erb +22 -0
- data/lib/karafka/web/ui/views/jobs/_no_jobs.erb +9 -0
- data/lib/karafka/web/ui/views/jobs/index.erb +31 -0
- data/lib/karafka/web/ui/views/layout.erb +23 -0
- data/lib/karafka/web/ui/views/routing/_breadcrumbs.erb +15 -0
- data/lib/karafka/web/ui/views/routing/_consumer_group.erb +34 -0
- data/lib/karafka/web/ui/views/routing/_detail.erb +25 -0
- data/lib/karafka/web/ui/views/routing/_topic.erb +18 -0
- data/lib/karafka/web/ui/views/routing/index.erb +10 -0
- data/lib/karafka/web/ui/views/routing/show.erb +26 -0
- data/lib/karafka/web/ui/views/shared/_become_pro.erb +13 -0
- data/lib/karafka/web/ui/views/shared/_brand.erb +3 -0
- data/lib/karafka/web/ui/views/shared/_content.erb +31 -0
- data/lib/karafka/web/ui/views/shared/_header.erb +20 -0
- data/lib/karafka/web/ui/views/shared/_navigation.erb +57 -0
- data/lib/karafka/web/ui/views/shared/_pagination.erb +21 -0
- data/lib/karafka/web/ui/views/shared/exceptions/not_found.erb +39 -0
- data/lib/karafka/web/ui/views/shared/exceptions/pro_only.erb +52 -0
- data/lib/karafka/web/version.rb +8 -0
- data/lib/karafka/web.rb +60 -0
- data.tar.gz.sig +0 -0
- metadata +328 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
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 %>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<tr class="status-row-<%= process.status %>">
|
|
2
|
+
<td>
|
|
3
|
+
<div class="badge badge-topic <%= status_bg(process.status) %> float-end">
|
|
4
|
+
<%= process.status %>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<a href="<%= root_path('consumers', process.id, 'subscriptions') %>">
|
|
8
|
+
<%= process.name %>
|
|
9
|
+
</a>
|
|
10
|
+
|
|
11
|
+
<br/>
|
|
12
|
+
|
|
13
|
+
<% process.consumer_groups.each do |consumer_group| %>
|
|
14
|
+
<% consumer_group.topics.each do |topic| %>
|
|
15
|
+
<span class="badge bg-secondary badge-topic" title="Consumer group: <%= consumer_group.id %>">
|
|
16
|
+
<%= topic.name %>:
|
|
17
|
+
<%= topic.partitions.map(&:id).join(',') %>
|
|
18
|
+
</span>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
21
|
+
</td>
|
|
22
|
+
|
|
23
|
+
<td>
|
|
24
|
+
<%== relative_time process.started_at %>
|
|
25
|
+
</td>
|
|
26
|
+
|
|
27
|
+
<td>
|
|
28
|
+
<span class="badge bg-primary badge-topic">
|
|
29
|
+
<%= format_memory process.memory_usage %>
|
|
30
|
+
</span>
|
|
31
|
+
<span class="badge bg-primary badge-topic">
|
|
32
|
+
<%= format_memory process.memory_total_usage %>
|
|
33
|
+
</span>
|
|
34
|
+
<span class="badge bg-primary badge-topic">
|
|
35
|
+
<%= format_memory process.memory_size %>
|
|
36
|
+
</span>
|
|
37
|
+
</td>
|
|
38
|
+
|
|
39
|
+
<td>
|
|
40
|
+
<span class="badge bg-primary badge-topic">
|
|
41
|
+
<%= process.utilization.round(1) %>%
|
|
42
|
+
</span>
|
|
43
|
+
<span class="badge bg-primary badge-topic">
|
|
44
|
+
<%= process.concurrency %> /
|
|
45
|
+
<%= process.busy %>
|
|
46
|
+
</span>
|
|
47
|
+
</td>
|
|
48
|
+
|
|
49
|
+
<td>
|
|
50
|
+
<% process.cpu_usage.each do |metric| %>
|
|
51
|
+
<span class="badge bg-primary badge-topic">
|
|
52
|
+
<%= metric %>
|
|
53
|
+
</span>
|
|
54
|
+
<% end %>
|
|
55
|
+
</td>
|
|
56
|
+
|
|
57
|
+
<td>
|
|
58
|
+
<%= process.lag_stored %>
|
|
59
|
+
</td>
|
|
60
|
+
</tr>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<div id="counters" class="container mb-5">
|
|
2
|
+
<div class="row">
|
|
3
|
+
<div class="col-sm-12">
|
|
4
|
+
<div class="card">
|
|
5
|
+
<div class="card-body p-2 small">
|
|
6
|
+
<div class="col-sm-12">
|
|
7
|
+
<ul class="list-unstyled row text-center mb-0 mt-0">
|
|
8
|
+
<li class="col-sm">
|
|
9
|
+
<div class="count mb-1"><%= @counters.messages %></div>
|
|
10
|
+
<div class="desc">Messages</div>
|
|
11
|
+
</li>
|
|
12
|
+
<li class="col-sm">
|
|
13
|
+
<div class="count mb-1"><%= @counters.batches %></div>
|
|
14
|
+
<div class="desc">Batches</div>
|
|
15
|
+
</li>
|
|
16
|
+
<li class="col-sm">
|
|
17
|
+
<div class="count mb-1"><%= @processes.sum(&:lag_stored) %></div>
|
|
18
|
+
<div class="desc">Lag</div>
|
|
19
|
+
</li>
|
|
20
|
+
<li class="col-sm">
|
|
21
|
+
<div class="count mb-1"><%= @counters.busy %></div>
|
|
22
|
+
<div class="desc">Busy</div>
|
|
23
|
+
</li>
|
|
24
|
+
<li class="col-sm">
|
|
25
|
+
<div class="count mb-1"><%= @counters.enqueued %></div>
|
|
26
|
+
<div class="desc">Enqueued</div>
|
|
27
|
+
</li>
|
|
28
|
+
<li class="col-sm">
|
|
29
|
+
<a href="<%= root_path('errors/0') %>">
|
|
30
|
+
<div class="count mb-1"><%= @counters.errors %></div>
|
|
31
|
+
<div class="desc">Errors</div>
|
|
32
|
+
</a>
|
|
33
|
+
</li>
|
|
34
|
+
<li class="col-sm">
|
|
35
|
+
<div class="count mb-1"><%= @counters.retries %></div>
|
|
36
|
+
<div class="desc">Retries</div>
|
|
37
|
+
</li>
|
|
38
|
+
<li class="col-sm">
|
|
39
|
+
<a href="<%= root_path('dlq') %>">
|
|
40
|
+
<div class="count mb-1"><%= @counters.dead %></div>
|
|
41
|
+
<div class="desc">Dead</div>
|
|
42
|
+
</a>
|
|
43
|
+
</li>
|
|
44
|
+
</ul>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
@@ -0,0 +1,81 @@
|
|
|
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>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<div class="row mb-4">
|
|
2
|
+
<div class="col-sm-12">
|
|
3
|
+
<h5 class="mb-4">
|
|
4
|
+
<%= consumer_group.id %>
|
|
5
|
+
</h5>
|
|
6
|
+
|
|
7
|
+
<div class="card-group text-center">
|
|
8
|
+
<div class="card">
|
|
9
|
+
<div class="card-body d-flex flex-column align-items-center justify-content-center p-2">
|
|
10
|
+
State:
|
|
11
|
+
<span class="badge <%= kafka_state_bg(consumer_group[:state][:state]) %> mt-1 mb-1">
|
|
12
|
+
<%= consumer_group[:state][:state] %>
|
|
13
|
+
</span>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="card">
|
|
17
|
+
<div class="card-body d-flex flex-column align-items-center justify-content-center p-2">
|
|
18
|
+
Join state:
|
|
19
|
+
<span class="badge <%= kafka_state_bg(consumer_group.join_state) %> mt-1 mb-1">
|
|
20
|
+
<%= consumer_group.join_state %>
|
|
21
|
+
</span>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="card">
|
|
25
|
+
<div class="card-body d-flex flex-column align-items-center justify-content-center p-2">
|
|
26
|
+
State change:
|
|
27
|
+
<span class="badge bg-secondary mt-1 mb-1">
|
|
28
|
+
<%==
|
|
29
|
+
relative_time(
|
|
30
|
+
Time.at(@process.dispatched_at) - (consumer_group.stateage / 1_000)
|
|
31
|
+
)
|
|
32
|
+
%>
|
|
33
|
+
</span>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="card">
|
|
37
|
+
<div class="card-body d-flex flex-column align-items-center justify-content-center p-2">
|
|
38
|
+
Last rebalance:
|
|
39
|
+
<span class="badge bg-secondary mt-1 mb-1">
|
|
40
|
+
<%==
|
|
41
|
+
relative_time(
|
|
42
|
+
Time.at(@process.dispatched_at) - (consumer_group.rebalance_age / 1_000)
|
|
43
|
+
)
|
|
44
|
+
%>
|
|
45
|
+
</span>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="card">
|
|
49
|
+
<div class="card-body d-flex flex-column align-items-center justify-content-center p-2">
|
|
50
|
+
Rebalance count:
|
|
51
|
+
<span class="badge bg-secondary mt-1 mb-1">
|
|
52
|
+
<%= consumer_group.rebalance_cnt %>
|
|
53
|
+
</span>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<span class="text-end mt-3">
|
|
60
|
+
<small>
|
|
61
|
+
Last rebalance reason: <%= consumer_group.rebalance_reason %>
|
|
62
|
+
</small>
|
|
63
|
+
</span>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<% if consumer_group.topics.empty? %>
|
|
67
|
+
<div class="row">
|
|
68
|
+
<div class="col-lg-12">
|
|
69
|
+
<div class="alert alert-info" role="alert">
|
|
70
|
+
This process does not consume any messages from any topics of this consumer group.
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
<% else %>
|
|
75
|
+
<div class="row mb-5">
|
|
76
|
+
<div class="col-sm-12">
|
|
77
|
+
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
|
|
78
|
+
<thead>
|
|
79
|
+
<tr class="align-middle">
|
|
80
|
+
<th>Topic</th>
|
|
81
|
+
<th>Partition</th>
|
|
82
|
+
<th>Lag stored</th>
|
|
83
|
+
<th>Lag trend</th>
|
|
84
|
+
<th>Committed offset</th>
|
|
85
|
+
<th>Stored offset</th>
|
|
86
|
+
<th>Fetch state</th>
|
|
87
|
+
<th>Poll state</th>
|
|
88
|
+
</tr>
|
|
89
|
+
</thead>
|
|
90
|
+
<tbody>
|
|
91
|
+
<% consumer_group.topics.each do |topic| %>
|
|
92
|
+
<% topic.partitions.each do |partition| %>
|
|
93
|
+
<%==
|
|
94
|
+
partial(
|
|
95
|
+
'consumers/consumer/partition',
|
|
96
|
+
locals: {
|
|
97
|
+
topic: topic,
|
|
98
|
+
partition: partition,
|
|
99
|
+
consumer_group: consumer_group
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
%>
|
|
103
|
+
<% end %>
|
|
104
|
+
<% end %>
|
|
105
|
+
</tbody>
|
|
106
|
+
</table>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
<% end %>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<tr>
|
|
2
|
+
<td>
|
|
3
|
+
<code><%= job.consumer %></code>
|
|
4
|
+
</td>
|
|
5
|
+
<td>
|
|
6
|
+
<span class="badge bg-secondary badge-topic" title="Consumer group: <%= job.consumer_group %>">
|
|
7
|
+
<%= job.topic %>:
|
|
8
|
+
<%= job.partition %>
|
|
9
|
+
</span>
|
|
10
|
+
</td>
|
|
11
|
+
<td>
|
|
12
|
+
<code>#<%= job.type %></code>
|
|
13
|
+
</td>
|
|
14
|
+
<td>
|
|
15
|
+
<%= job.first_offset %>
|
|
16
|
+
</td>
|
|
17
|
+
<td>
|
|
18
|
+
<%= job.last_offset %>
|
|
19
|
+
</td>
|
|
20
|
+
<td>
|
|
21
|
+
<%= job.comitted_offset %>
|
|
22
|
+
</td>
|
|
23
|
+
<td>
|
|
24
|
+
<%== relative_time job.started_at %>
|
|
25
|
+
</td>
|
|
26
|
+
</tr>
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
<div class="container mb-5">
|
|
2
|
+
<div class="row" id="metrics">
|
|
3
|
+
<div class="col-lg-12">
|
|
4
|
+
<div class="card-group">
|
|
5
|
+
<div class="card">
|
|
6
|
+
<div class="card-body">
|
|
7
|
+
<h5 class="card-title">Process</h5>
|
|
8
|
+
<p class="card-text">
|
|
9
|
+
<ul style="list-style: square !important;">
|
|
10
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
11
|
+
Status:
|
|
12
|
+
<span class="badge <%= status_bg @process.status %>">
|
|
13
|
+
<%= @process.status %>
|
|
14
|
+
</span>
|
|
15
|
+
</li>
|
|
16
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
17
|
+
Started:
|
|
18
|
+
<span class="badge bg-secondary">
|
|
19
|
+
<%== relative_time @process.started_at %>
|
|
20
|
+
</span>
|
|
21
|
+
</li>
|
|
22
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
23
|
+
State from:
|
|
24
|
+
<span class="badge bg-secondary">
|
|
25
|
+
<%== relative_time @process.dispatched_at %>
|
|
26
|
+
</span>
|
|
27
|
+
</li>
|
|
28
|
+
</ul>
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="card">
|
|
33
|
+
<div class="card-body">
|
|
34
|
+
<h5 class="card-title">Utilization</h5>
|
|
35
|
+
<p class="card-text">
|
|
36
|
+
<ul style="list-style: square !important;">
|
|
37
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
38
|
+
Threads:
|
|
39
|
+
<span class="badge bg-primary">
|
|
40
|
+
<%= @process.concurrency %>
|
|
41
|
+
</span>
|
|
42
|
+
</li>
|
|
43
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
44
|
+
Threads utilization:
|
|
45
|
+
<span class="badge bg-primary">
|
|
46
|
+
<%= @process.utilization.round(2) %>%
|
|
47
|
+
</span>
|
|
48
|
+
</li>
|
|
49
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
50
|
+
CPUs:
|
|
51
|
+
<span class="badge bg-primary">
|
|
52
|
+
<%= @process.cpu_count %>
|
|
53
|
+
</span>
|
|
54
|
+
</li>
|
|
55
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
56
|
+
CPU usage:
|
|
57
|
+
<% @process.cpu_usage.each_with_index do |usage, i| %>
|
|
58
|
+
<span class="badge bg-primary">
|
|
59
|
+
<%= usage %>
|
|
60
|
+
</span>
|
|
61
|
+
|
|
62
|
+
<%= i < 2 ? '/' : '' %>
|
|
63
|
+
<% end %>
|
|
64
|
+
</li>
|
|
65
|
+
</ul>
|
|
66
|
+
</p>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="card">
|
|
70
|
+
<div class="card-body">
|
|
71
|
+
<h5 class="card-title">Memory usage</h5>
|
|
72
|
+
<p class="card-text">
|
|
73
|
+
<ul style="list-style: square !important;">
|
|
74
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
75
|
+
RSS:
|
|
76
|
+
<span class="badge bg-primary">
|
|
77
|
+
<%= format_memory @process.memory_usage %>
|
|
78
|
+
</span>
|
|
79
|
+
</li>
|
|
80
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
81
|
+
OS memory used:
|
|
82
|
+
<span class="badge bg-primary">
|
|
83
|
+
<%= format_memory @process.memory_total_usage %>
|
|
84
|
+
</span>
|
|
85
|
+
</li>
|
|
86
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
87
|
+
OS memory available:
|
|
88
|
+
<span class="badge bg-primary">
|
|
89
|
+
<%= format_memory @process.memory_size %>
|
|
90
|
+
</span>
|
|
91
|
+
</li>
|
|
92
|
+
</ul>
|
|
93
|
+
</p>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="card">
|
|
97
|
+
<div class="card-body">
|
|
98
|
+
<h5 class="card-title">Versions</h5>
|
|
99
|
+
<p class="card-text">
|
|
100
|
+
<ul style="list-style: square !important;">
|
|
101
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
102
|
+
Ruby:
|
|
103
|
+
<span class="badge bg-secondary">
|
|
104
|
+
<%= @process.ruby %>
|
|
105
|
+
</span>
|
|
106
|
+
</li>
|
|
107
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
108
|
+
Karafka:
|
|
109
|
+
<span class="badge bg-secondary">
|
|
110
|
+
<%= @process.karafka %>
|
|
111
|
+
</span>
|
|
112
|
+
</li>
|
|
113
|
+
<li class="align-items-center d-flex justify-content-between">
|
|
114
|
+
WaterDrop version:
|
|
115
|
+
<span class="badge bg-secondary">
|
|
116
|
+
<%= @process.waterdrop %>
|
|
117
|
+
</span>
|
|
118
|
+
</li>
|
|
119
|
+
</ul>
|
|
120
|
+
</p>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<tr>
|
|
2
|
+
<td>
|
|
3
|
+
<%= topic.name %>
|
|
4
|
+
</td>
|
|
5
|
+
<td>
|
|
6
|
+
<%= partition.id %>
|
|
7
|
+
</td>
|
|
8
|
+
<td>
|
|
9
|
+
<%= partition.lag_stored %>
|
|
10
|
+
</td>
|
|
11
|
+
<td>
|
|
12
|
+
<span class="badge <%= lag_trend_bg(partition.lag_stored_d) %>">
|
|
13
|
+
<%= partition.lag_stored_d %>
|
|
14
|
+
</span>
|
|
15
|
+
</td>
|
|
16
|
+
<td>
|
|
17
|
+
<%= partition.committed_offset %>
|
|
18
|
+
</td>
|
|
19
|
+
<td>
|
|
20
|
+
<%= partition.stored_offset %>
|
|
21
|
+
</td>
|
|
22
|
+
<td>
|
|
23
|
+
<span class="badge <%= kafka_state_bg(partition.fetch_state) %> mt-1 mb-1">
|
|
24
|
+
<%= partition.fetch_state %>
|
|
25
|
+
</span>
|
|
26
|
+
</td>
|
|
27
|
+
<td>
|
|
28
|
+
<span class="badge <%= kafka_state_bg(partition.poll_state) %> mt-1 mb-1">
|
|
29
|
+
<%= partition.poll_state %>
|
|
30
|
+
</span>
|
|
31
|
+
</td>
|
|
32
|
+
</tr>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<div class="container">
|
|
2
|
+
<div class="row mb-4">
|
|
3
|
+
<div class="col-sm-12">
|
|
4
|
+
|
|
5
|
+
<ul class="nav nav-tabs">
|
|
6
|
+
<li class="nav-item">
|
|
7
|
+
<a class="nav-link <%= nav_class(include: 'subscriptions') %>" href="<%= root_path('consumers', @process.id, 'subscriptions') %>">
|
|
8
|
+
Active subscriptions
|
|
9
|
+
</a>
|
|
10
|
+
</li>
|
|
11
|
+
<li class="nav-item">
|
|
12
|
+
<a class="nav-link <%= nav_class(include: 'jobs') %>" href="<%= root_path('consumers', @process.id, 'jobs') %>">
|
|
13
|
+
Running jobs
|
|
14
|
+
</a>
|
|
15
|
+
</li>
|
|
16
|
+
</ul>
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<%== partial 'consumers/counters' %>
|
|
2
|
+
<%== partial 'consumers/summary' %>
|
|
3
|
+
|
|
4
|
+
<div class="container">
|
|
5
|
+
<div class="row">
|
|
6
|
+
<div class="col-sm-12">
|
|
7
|
+
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
|
|
8
|
+
<thead>
|
|
9
|
+
<tr class="align-middle">
|
|
10
|
+
<th>Name</th>
|
|
11
|
+
<th class="col-sm-2">Started</th>
|
|
12
|
+
<th class="col-sm-1">Memory</th>
|
|
13
|
+
<th class="col-sm-1">Performance</th>
|
|
14
|
+
<th class="col-sm-1">Load</th>
|
|
15
|
+
<th class="col-sm-1">Total lag</th>
|
|
16
|
+
</tr>
|
|
17
|
+
</thead>
|
|
18
|
+
<tbody>
|
|
19
|
+
<%==
|
|
20
|
+
render_each(
|
|
21
|
+
@processes,
|
|
22
|
+
'consumers/_consumer',
|
|
23
|
+
local: :process
|
|
24
|
+
)
|
|
25
|
+
%>
|
|
26
|
+
</tbody>
|
|
27
|
+
</table>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<%== view_title(@process.name) %>
|
|
2
|
+
|
|
3
|
+
<% if @process.status == 'stopped' %>
|
|
4
|
+
<%== partial 'consumers/consumer/stopped' %>
|
|
5
|
+
<% end %>
|
|
6
|
+
|
|
7
|
+
<%== partial 'consumers/consumer/metrics' %>
|
|
8
|
+
|
|
9
|
+
<%== partial 'consumers/consumer/tabs' %>
|
|
10
|
+
|
|
11
|
+
<% if @process.jobs.empty? %>
|
|
12
|
+
<%== partial 'consumers/consumer/no_jobs' %>
|
|
13
|
+
<% else %>
|
|
14
|
+
<div class="container">
|
|
15
|
+
<div class="row mb-5">
|
|
16
|
+
<div class="col-sm-12">
|
|
17
|
+
<table class="processes bg-white table table-hover table-bordered table-striped mb-0 align-middle">
|
|
18
|
+
<thead>
|
|
19
|
+
<tr class="align-middle">
|
|
20
|
+
<th>Consumer</th>
|
|
21
|
+
<th>Topic</th>
|
|
22
|
+
<th>Type</th>
|
|
23
|
+
<th>First offset</th>
|
|
24
|
+
<th>Last offset</th>
|
|
25
|
+
<th>Committed offset</th>
|
|
26
|
+
<th>Started at</th>
|
|
27
|
+
</tr>
|
|
28
|
+
</thead>
|
|
29
|
+
<tbody>
|
|
30
|
+
<%==
|
|
31
|
+
render_each(
|
|
32
|
+
@process.jobs,
|
|
33
|
+
'consumers/consumer/_job',
|
|
34
|
+
local: :job
|
|
35
|
+
)
|
|
36
|
+
%>
|
|
37
|
+
</tbody>
|
|
38
|
+
</table>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
<% end %>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<%== view_title(@process.name) %>
|
|
2
|
+
|
|
3
|
+
<% if @process.status == 'stopped' %>
|
|
4
|
+
<%== partial 'consumers/consumer/stopped' %>
|
|
5
|
+
<% end %>
|
|
6
|
+
|
|
7
|
+
<%== partial 'consumers/consumer/metrics' %>
|
|
8
|
+
|
|
9
|
+
<%== partial 'consumers/consumer/tabs' %>
|
|
10
|
+
|
|
11
|
+
<% if @process.consumer_groups.empty? %>
|
|
12
|
+
<%== partial 'consumers/consumer/no_subscriptions' %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<div class="container">
|
|
16
|
+
<%==
|
|
17
|
+
render_each(
|
|
18
|
+
@process.consumer_groups,
|
|
19
|
+
'consumers/consumer/_consumer_group',
|
|
20
|
+
local: :consumer_group
|
|
21
|
+
)
|
|
22
|
+
%>
|
|
23
|
+
</div>
|