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.
Files changed (178) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +3 -0
  3. data/.coditsu/ci.yml +3 -0
  4. data/.diffend.yml +3 -0
  5. data/.github/FUNDING.yml +1 -0
  6. data/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
  7. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  8. data/.github/workflows/ci.yml +49 -0
  9. data/.gitignore +69 -0
  10. data/.ruby-gemset +1 -0
  11. data/.ruby-version +1 -0
  12. data/CHANGELOG.md +9 -0
  13. data/CODE_OF_CONDUCT.md +46 -0
  14. data/Gemfile +7 -0
  15. data/Gemfile.lock +52 -0
  16. data/LICENSE +17 -0
  17. data/README.md +29 -0
  18. data/bin/karafka-web +33 -0
  19. data/certs/cert_chain.pem +26 -0
  20. data/config/locales/errors.yml +9 -0
  21. data/karafka-web.gemspec +44 -0
  22. data/lib/karafka/web/app.rb +17 -0
  23. data/lib/karafka/web/config.rb +80 -0
  24. data/lib/karafka/web/deserializer.rb +20 -0
  25. data/lib/karafka/web/errors.rb +25 -0
  26. data/lib/karafka/web/installer.rb +124 -0
  27. data/lib/karafka/web/processing/consumer.rb +66 -0
  28. data/lib/karafka/web/processing/consumers/aggregator.rb +130 -0
  29. data/lib/karafka/web/processing/consumers/state.rb +32 -0
  30. data/lib/karafka/web/tracking/base_contract.rb +31 -0
  31. data/lib/karafka/web/tracking/consumers/contracts/consumer_group.rb +33 -0
  32. data/lib/karafka/web/tracking/consumers/contracts/job.rb +26 -0
  33. data/lib/karafka/web/tracking/consumers/contracts/partition.rb +22 -0
  34. data/lib/karafka/web/tracking/consumers/contracts/report.rb +95 -0
  35. data/lib/karafka/web/tracking/consumers/contracts/topic.rb +29 -0
  36. data/lib/karafka/web/tracking/consumers/listeners/base.rb +33 -0
  37. data/lib/karafka/web/tracking/consumers/listeners/errors.rb +107 -0
  38. data/lib/karafka/web/tracking/consumers/listeners/pausing.rb +45 -0
  39. data/lib/karafka/web/tracking/consumers/listeners/processing.rb +157 -0
  40. data/lib/karafka/web/tracking/consumers/listeners/statistics.rb +123 -0
  41. data/lib/karafka/web/tracking/consumers/listeners/status.rb +58 -0
  42. data/lib/karafka/web/tracking/consumers/sampler.rb +216 -0
  43. data/lib/karafka/web/tracking/memoized_shell.rb +48 -0
  44. data/lib/karafka/web/tracking/reporter.rb +144 -0
  45. data/lib/karafka/web/tracking/ttl_array.rb +59 -0
  46. data/lib/karafka/web/tracking/ttl_hash.rb +16 -0
  47. data/lib/karafka/web/ui/app.rb +78 -0
  48. data/lib/karafka/web/ui/base.rb +77 -0
  49. data/lib/karafka/web/ui/controllers/base.rb +40 -0
  50. data/lib/karafka/web/ui/controllers/become_pro.rb +17 -0
  51. data/lib/karafka/web/ui/controllers/cluster.rb +24 -0
  52. data/lib/karafka/web/ui/controllers/consumers.rb +27 -0
  53. data/lib/karafka/web/ui/controllers/errors.rb +43 -0
  54. data/lib/karafka/web/ui/controllers/jobs.rb +33 -0
  55. data/lib/karafka/web/ui/controllers/requests/params.rb +30 -0
  56. data/lib/karafka/web/ui/controllers/responses/data.rb +26 -0
  57. data/lib/karafka/web/ui/controllers/routing.rb +30 -0
  58. data/lib/karafka/web/ui/helpers/application_helper.rb +144 -0
  59. data/lib/karafka/web/ui/lib/hash_proxy.rb +66 -0
  60. data/lib/karafka/web/ui/lib/paginate_array.rb +38 -0
  61. data/lib/karafka/web/ui/models/consumer_group.rb +20 -0
  62. data/lib/karafka/web/ui/models/health.rb +44 -0
  63. data/lib/karafka/web/ui/models/job.rb +13 -0
  64. data/lib/karafka/web/ui/models/message.rb +99 -0
  65. data/lib/karafka/web/ui/models/partition.rb +13 -0
  66. data/lib/karafka/web/ui/models/process.rb +56 -0
  67. data/lib/karafka/web/ui/models/processes.rb +86 -0
  68. data/lib/karafka/web/ui/models/state.rb +67 -0
  69. data/lib/karafka/web/ui/models/topic.rb +19 -0
  70. data/lib/karafka/web/ui/pro/app.rb +120 -0
  71. data/lib/karafka/web/ui/pro/controllers/cluster.rb +16 -0
  72. data/lib/karafka/web/ui/pro/controllers/consumers.rb +54 -0
  73. data/lib/karafka/web/ui/pro/controllers/dlq.rb +44 -0
  74. data/lib/karafka/web/ui/pro/controllers/errors.rb +57 -0
  75. data/lib/karafka/web/ui/pro/controllers/explorer.rb +79 -0
  76. data/lib/karafka/web/ui/pro/controllers/health.rb +33 -0
  77. data/lib/karafka/web/ui/pro/controllers/jobs.rb +26 -0
  78. data/lib/karafka/web/ui/pro/controllers/routing.rb +26 -0
  79. data/lib/karafka/web/ui/pro/views/consumers/_breadcrumbs.erb +27 -0
  80. data/lib/karafka/web/ui/pro/views/consumers/_consumer.erb +60 -0
  81. data/lib/karafka/web/ui/pro/views/consumers/_counters.erb +50 -0
  82. data/lib/karafka/web/ui/pro/views/consumers/_summary.erb +81 -0
  83. data/lib/karafka/web/ui/pro/views/consumers/consumer/_consumer_group.erb +109 -0
  84. data/lib/karafka/web/ui/pro/views/consumers/consumer/_job.erb +26 -0
  85. data/lib/karafka/web/ui/pro/views/consumers/consumer/_metrics.erb +126 -0
  86. data/lib/karafka/web/ui/pro/views/consumers/consumer/_no_jobs.erb +9 -0
  87. data/lib/karafka/web/ui/pro/views/consumers/consumer/_no_subscriptions.erb +9 -0
  88. data/lib/karafka/web/ui/pro/views/consumers/consumer/_partition.erb +32 -0
  89. data/lib/karafka/web/ui/pro/views/consumers/consumer/_stopped.erb +10 -0
  90. data/lib/karafka/web/ui/pro/views/consumers/consumer/_tabs.erb +20 -0
  91. data/lib/karafka/web/ui/pro/views/consumers/index.erb +30 -0
  92. data/lib/karafka/web/ui/pro/views/consumers/jobs.erb +42 -0
  93. data/lib/karafka/web/ui/pro/views/consumers/subscriptions.erb +23 -0
  94. data/lib/karafka/web/ui/pro/views/dlq/_breadcrumbs.erb +5 -0
  95. data/lib/karafka/web/ui/pro/views/dlq/_no_topics.erb +9 -0
  96. data/lib/karafka/web/ui/pro/views/dlq/_topic.erb +12 -0
  97. data/lib/karafka/web/ui/pro/views/dlq/index.erb +16 -0
  98. data/lib/karafka/web/ui/pro/views/errors/_breadcrumbs.erb +25 -0
  99. data/lib/karafka/web/ui/pro/views/errors/_detail.erb +29 -0
  100. data/lib/karafka/web/ui/pro/views/errors/_error.erb +26 -0
  101. data/lib/karafka/web/ui/pro/views/errors/_partition_option.erb +7 -0
  102. data/lib/karafka/web/ui/pro/views/errors/index.erb +58 -0
  103. data/lib/karafka/web/ui/pro/views/errors/show.erb +56 -0
  104. data/lib/karafka/web/ui/pro/views/explorer/_breadcrumbs.erb +29 -0
  105. data/lib/karafka/web/ui/pro/views/explorer/_detail.erb +21 -0
  106. data/lib/karafka/web/ui/pro/views/explorer/_encryption_enabled.erb +18 -0
  107. data/lib/karafka/web/ui/pro/views/explorer/_failed_deserialization.erb +4 -0
  108. data/lib/karafka/web/ui/pro/views/explorer/_message.erb +16 -0
  109. data/lib/karafka/web/ui/pro/views/explorer/_partition_option.erb +7 -0
  110. data/lib/karafka/web/ui/pro/views/explorer/_topic.erb +12 -0
  111. data/lib/karafka/web/ui/pro/views/explorer/index.erb +17 -0
  112. data/lib/karafka/web/ui/pro/views/explorer/partition.erb +56 -0
  113. data/lib/karafka/web/ui/pro/views/explorer/show.erb +65 -0
  114. data/lib/karafka/web/ui/pro/views/health/_breadcrumbs.erb +5 -0
  115. data/lib/karafka/web/ui/pro/views/health/_partition.erb +35 -0
  116. data/lib/karafka/web/ui/pro/views/health/index.erb +60 -0
  117. data/lib/karafka/web/ui/pro/views/jobs/_breadcrumbs.erb +5 -0
  118. data/lib/karafka/web/ui/pro/views/jobs/_job.erb +31 -0
  119. data/lib/karafka/web/ui/pro/views/jobs/_no_jobs.erb +9 -0
  120. data/lib/karafka/web/ui/pro/views/jobs/index.erb +34 -0
  121. data/lib/karafka/web/ui/pro/views/shared/_navigation.erb +57 -0
  122. data/lib/karafka/web/ui/public/images/favicon.ico +0 -0
  123. data/lib/karafka/web/ui/public/images/logo.svg +28 -0
  124. data/lib/karafka/web/ui/public/javascripts/application.js +41 -0
  125. data/lib/karafka/web/ui/public/javascripts/bootstrap.min.js +7 -0
  126. data/lib/karafka/web/ui/public/javascripts/highlight.min.js +337 -0
  127. data/lib/karafka/web/ui/public/javascripts/live_poll.js +124 -0
  128. data/lib/karafka/web/ui/public/javascripts/timeago.min.js +1 -0
  129. data/lib/karafka/web/ui/public/stylesheets/application.css +106 -0
  130. data/lib/karafka/web/ui/public/stylesheets/bootstrap.min.css +7 -0
  131. data/lib/karafka/web/ui/public/stylesheets/bootstrap.min.css.map +1 -0
  132. data/lib/karafka/web/ui/public/stylesheets/highlight.min.css +10 -0
  133. data/lib/karafka/web/ui/views/cluster/_breadcrumbs.erb +5 -0
  134. data/lib/karafka/web/ui/views/cluster/_broker.erb +5 -0
  135. data/lib/karafka/web/ui/views/cluster/_partition.erb +22 -0
  136. data/lib/karafka/web/ui/views/cluster/index.erb +72 -0
  137. data/lib/karafka/web/ui/views/consumers/_breadcrumbs.erb +27 -0
  138. data/lib/karafka/web/ui/views/consumers/_consumer.erb +43 -0
  139. data/lib/karafka/web/ui/views/consumers/_counters.erb +44 -0
  140. data/lib/karafka/web/ui/views/consumers/_summary.erb +81 -0
  141. data/lib/karafka/web/ui/views/consumers/consumer/_consumer_group.erb +109 -0
  142. data/lib/karafka/web/ui/views/consumers/consumer/_job.erb +26 -0
  143. data/lib/karafka/web/ui/views/consumers/consumer/_metrics.erb +126 -0
  144. data/lib/karafka/web/ui/views/consumers/consumer/_no_jobs.erb +9 -0
  145. data/lib/karafka/web/ui/views/consumers/consumer/_no_subscriptions.erb +9 -0
  146. data/lib/karafka/web/ui/views/consumers/consumer/_partition.erb +32 -0
  147. data/lib/karafka/web/ui/views/consumers/consumer/_stopped.erb +10 -0
  148. data/lib/karafka/web/ui/views/consumers/consumer/_tabs.erb +20 -0
  149. data/lib/karafka/web/ui/views/consumers/index.erb +29 -0
  150. data/lib/karafka/web/ui/views/errors/_breadcrumbs.erb +19 -0
  151. data/lib/karafka/web/ui/views/errors/_detail.erb +29 -0
  152. data/lib/karafka/web/ui/views/errors/_error.erb +26 -0
  153. data/lib/karafka/web/ui/views/errors/index.erb +38 -0
  154. data/lib/karafka/web/ui/views/errors/show.erb +30 -0
  155. data/lib/karafka/web/ui/views/jobs/_breadcrumbs.erb +5 -0
  156. data/lib/karafka/web/ui/views/jobs/_job.erb +22 -0
  157. data/lib/karafka/web/ui/views/jobs/_no_jobs.erb +9 -0
  158. data/lib/karafka/web/ui/views/jobs/index.erb +31 -0
  159. data/lib/karafka/web/ui/views/layout.erb +23 -0
  160. data/lib/karafka/web/ui/views/routing/_breadcrumbs.erb +15 -0
  161. data/lib/karafka/web/ui/views/routing/_consumer_group.erb +34 -0
  162. data/lib/karafka/web/ui/views/routing/_detail.erb +25 -0
  163. data/lib/karafka/web/ui/views/routing/_topic.erb +18 -0
  164. data/lib/karafka/web/ui/views/routing/index.erb +10 -0
  165. data/lib/karafka/web/ui/views/routing/show.erb +26 -0
  166. data/lib/karafka/web/ui/views/shared/_become_pro.erb +13 -0
  167. data/lib/karafka/web/ui/views/shared/_brand.erb +3 -0
  168. data/lib/karafka/web/ui/views/shared/_content.erb +31 -0
  169. data/lib/karafka/web/ui/views/shared/_header.erb +20 -0
  170. data/lib/karafka/web/ui/views/shared/_navigation.erb +57 -0
  171. data/lib/karafka/web/ui/views/shared/_pagination.erb +21 -0
  172. data/lib/karafka/web/ui/views/shared/exceptions/not_found.erb +39 -0
  173. data/lib/karafka/web/ui/views/shared/exceptions/pro_only.erb +52 -0
  174. data/lib/karafka/web/version.rb +8 -0
  175. data/lib/karafka/web.rb +60 -0
  176. data.tar.gz.sig +0 -0
  177. metadata +328 -0
  178. metadata.gz.sig +0 -0
@@ -0,0 +1,10 @@
1
+ pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
2
+ Theme: GitHub
3
+ Description: Light theme as seen on github.com
4
+ Author: github.com
5
+ Maintainer: @Hirse
6
+ Updated: 2021-05-15
7
+
8
+ Outdated base version: https://github.com/primer/github-syntax-light
9
+ Current colors taken from GitHub's CSS
10
+ */.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
@@ -0,0 +1,5 @@
1
+ <li class="breadcrumb-item">
2
+ <a href="<%= root_path('cluster') %>">
3
+ Cluster informations
4
+ </a>
5
+ </li>
@@ -0,0 +1,5 @@
1
+ <tr>
2
+ <td><%= broker[:broker_id] %></td>
3
+ <td><%= broker[:broker_name] %></td>
4
+ <td><%= broker[:broker_port] %></td>
5
+ </tr>
@@ -0,0 +1,22 @@
1
+ <% if topic[:topic_name] != '__consumer_offsets' %>
2
+ <tr>
3
+ <td>
4
+ <a href="<%= root_path('explorer', topic[:topic_name], 0) %>">
5
+ <%= topic[:topic_name] %>
6
+ </a>
7
+ <td>
8
+ <a href="<%= root_path('explorer', topic[:topic_name], partition[:partition_id]) %>">
9
+ <%= partition[:partition_id] %>
10
+ </a>
11
+ </td>
12
+ <td>
13
+ <%= partition[:leader] %>
14
+ </td>
15
+ <td>
16
+ <%= partition[:replica_count] %>
17
+ </td>
18
+ <td>
19
+ <%= partition[:in_sync_replica_brokers] %>
20
+ </td>
21
+ </tr>
22
+ <% end %>
@@ -0,0 +1,72 @@
1
+ <%== view_title('Cluster informations') %>
2
+
3
+ <div class="container mb-5">
4
+ <div class="row mb-3">
5
+ <div class="col-sm-12">
6
+ <h4 class="mb-4">
7
+ Brokers
8
+ </h4>
9
+ <hr/>
10
+ </div>
11
+ </div>
12
+
13
+ <div class="row">
14
+ <div class="col-lg-12">
15
+ <table class="processes bg-white table table-hover table-bordered table-striped">
16
+ <thead>
17
+ <tr class="align-middle">
18
+ <th>Broker id</th>
19
+ <th>Name</th>
20
+ <th>Port</th>
21
+ </tr>
22
+ </thead>
23
+ <tbody>
24
+ <%==
25
+ each_partial(
26
+ @cluster_info.brokers,
27
+ 'cluster/broker'
28
+ )
29
+ %>
30
+ </tbody>
31
+ </table>
32
+ </div>
33
+ </div>
34
+ </div>
35
+
36
+ <div class="container mb-5">
37
+ <div class="row mb-3">
38
+ <div class="col-sm-12">
39
+ <h4 class="mb-4">
40
+ Topics and partitions
41
+ </h4>
42
+ <hr/>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="row">
47
+ <div class="col-lg-12">
48
+ <table class="processes bg-white table table-hover table-bordered table-striped">
49
+ <thead>
50
+ <tr class="align-middle">
51
+ <th>Topic name</th>
52
+ <th>Partition id</th>
53
+ <th>Leader</th>
54
+ <th>Replica count</th>
55
+ <th>In sync brokers</th>
56
+ </tr>
57
+ </thead>
58
+ <tbody>
59
+ <% @topics.each do |topic| %>
60
+ <%==
61
+ each_partial(
62
+ topic[:partitions],
63
+ 'cluster/partition',
64
+ locals: { topic: topic }
65
+ )
66
+ %>
67
+ <% end %>
68
+ </tbody>
69
+ </table>
70
+ </div>
71
+ </div>
72
+ </div>
@@ -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,43 @@
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
+ </td>
32
+
33
+ <td>
34
+ <span class="badge bg-primary badge-topic">
35
+ <%= process.concurrency %> /
36
+ <%= process.busy %>
37
+ </span>
38
+ </td>
39
+
40
+ <td>
41
+ <%= process.lag_stored %>
42
+ </td>
43
+ </tr>
@@ -0,0 +1,44 @@
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') %>">
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
+ </ul>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </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:&nbsp;
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:&nbsp;
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:&nbsp;
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:&nbsp;
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:&nbsp;
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,9 @@
1
+ <div class="container mb-4">
2
+ <div class="row">
3
+ <div class="col-lg-12">
4
+ <div class="alert alert-info" role="alert">
5
+ This process is not running any jobs at the moment.
6
+ </div>
7
+ </div>
8
+ </div>
9
+ </div>
@@ -0,0 +1,9 @@
1
+ <div class="container mb-4">
2
+ <div class="row">
3
+ <div class="col-lg-12">
4
+ <div class="alert alert-info" role="alert">
5
+ This process is not subscribed to any topics.
6
+ </div>
7
+ </div>
8
+ </div>
9
+ </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,10 @@
1
+ <div class="container mb-4">
2
+ <div class="row">
3
+ <div class="col-lg-12">
4
+ <div class="alert alert-danger" role="alert">
5
+ This process has been stopped.
6
+ The state presented here shows the last report available.
7
+ </div>
8
+ </div>
9
+ </div>
10
+ </div>
@@ -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>