karafka-web 0.8.2 → 0.9.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (269) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ci.yml +5 -16
  4. data/CHANGELOG.md +39 -0
  5. data/Gemfile.lock +21 -23
  6. data/LICENSE +3 -3
  7. data/bin/rspecs +1 -1
  8. data/config/locales/pro_errors.yml +11 -0
  9. data/config/locales/slogans.yml +62 -0
  10. data/karafka-web.gemspec +4 -2
  11. data/lib/karafka/web/app.rb +1 -1
  12. data/lib/karafka/web/config.rb +17 -0
  13. data/lib/karafka/web/contracts/config.rb +6 -0
  14. data/lib/karafka/web/management/actions/create_topics.rb +21 -0
  15. data/lib/karafka/web/management/actions/delete_topics.rb +1 -0
  16. data/lib/karafka/web/management/actions/enable.rb +11 -5
  17. data/lib/karafka/web/management/migrations/0_base.rb +1 -1
  18. data/lib/karafka/web/pro/commanding/commands/base.rb +33 -0
  19. data/lib/karafka/web/pro/commanding/commands/probe.rb +41 -0
  20. data/lib/karafka/web/pro/commanding/commands/quiet.rb +31 -0
  21. data/lib/karafka/web/pro/commanding/commands/stop.rb +31 -0
  22. data/lib/karafka/web/pro/commanding/config.rb +57 -0
  23. data/lib/karafka/web/pro/commanding/contracts/config.rb +60 -0
  24. data/lib/karafka/web/pro/commanding/dispatcher.rb +93 -0
  25. data/lib/karafka/web/pro/commanding/listener.rb +97 -0
  26. data/lib/karafka/web/pro/commanding/manager.rb +98 -0
  27. data/lib/karafka/web/pro/commanding/matcher.rb +50 -0
  28. data/lib/karafka/web/pro/commanding.rb +40 -0
  29. data/lib/karafka/web/pro/loader.rb +40 -0
  30. data/lib/karafka/web/{ui/pro → pro/ui}/app.rb +103 -22
  31. data/lib/karafka/web/{ui/pro/controllers/cluster.rb → pro/ui/controllers/base_controller.rb} +4 -5
  32. data/lib/karafka/web/pro/ui/controllers/cluster_controller.rb +54 -0
  33. data/lib/karafka/web/pro/ui/controllers/commanding_controller.rb +118 -0
  34. data/lib/karafka/web/pro/ui/controllers/commands_controller.rb +96 -0
  35. data/lib/karafka/web/{ui/pro/controllers/consumers.rb → pro/ui/controllers/consumers_controller.rb} +31 -4
  36. data/lib/karafka/web/{ui/pro/controllers/dashboard.rb → pro/ui/controllers/dashboard_controller.rb} +5 -3
  37. data/lib/karafka/web/pro/ui/controllers/dlq_controller.rb +60 -0
  38. data/lib/karafka/web/{ui/pro/controllers/errors.rb → pro/ui/controllers/errors_controller.rb} +5 -7
  39. data/lib/karafka/web/{ui/pro/controllers/explorer.rb → pro/ui/controllers/explorer_controller.rb} +24 -19
  40. data/lib/karafka/web/{ui/pro/controllers/health.rb → pro/ui/controllers/health_controller.rb} +16 -3
  41. data/lib/karafka/web/{ui/pro/controllers/jobs.rb → pro/ui/controllers/jobs_controller.rb} +4 -4
  42. data/lib/karafka/web/{ui/pro/controllers/messages.rb → pro/ui/controllers/messages_controller.rb} +8 -6
  43. data/lib/karafka/web/{ui/pro/controllers/routing.rb → pro/ui/controllers/routing_controller.rb} +6 -22
  44. data/lib/karafka/web/{ui/pro/controllers/status.rb → pro/ui/controllers/status_controller.rb} +3 -3
  45. data/lib/karafka/web/pro/ui/controllers/topics_controller.rb +99 -0
  46. data/lib/karafka/web/pro/ui/lib/patterns_detector.rb +50 -0
  47. data/lib/karafka/web/pro/ui/views/cluster/_breadcrumbs.erb +29 -0
  48. data/lib/karafka/web/pro/ui/views/cluster/_broker.erb +13 -0
  49. data/lib/karafka/web/pro/ui/views/cluster/_config.erb +13 -0
  50. data/lib/karafka/web/pro/ui/views/cluster/_tabs.erb +27 -0
  51. data/lib/karafka/web/pro/ui/views/cluster/brokers.erb +27 -0
  52. data/lib/karafka/web/pro/ui/views/cluster/index.erb +27 -0
  53. data/lib/karafka/web/pro/ui/views/cluster/show.erb +27 -0
  54. data/lib/karafka/web/pro/ui/views/commands/_backtrace.erb +20 -0
  55. data/lib/karafka/web/pro/ui/views/commands/_breadcrumbs.erb +21 -0
  56. data/lib/karafka/web/pro/ui/views/commands/_command.erb +60 -0
  57. data/lib/karafka/web/pro/ui/views/commands/_command_details.erb +11 -0
  58. data/lib/karafka/web/pro/ui/views/commands/_details.erb +26 -0
  59. data/lib/karafka/web/pro/ui/views/commands/_empty.erb +3 -0
  60. data/lib/karafka/web/pro/ui/views/commands/_incompatible_schema.erb +14 -0
  61. data/lib/karafka/web/pro/ui/views/commands/_metadata.erb +50 -0
  62. data/lib/karafka/web/pro/ui/views/commands/_table.erb +23 -0
  63. data/lib/karafka/web/pro/ui/views/commands/index.erb +17 -0
  64. data/lib/karafka/web/pro/ui/views/commands/show.erb +38 -0
  65. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/_breadcrumbs.erb +20 -4
  66. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/_consumer.erb +2 -21
  67. data/lib/karafka/web/pro/ui/views/consumers/_consumer_controls.erb +78 -0
  68. data/lib/karafka/web/pro/ui/views/consumers/_consumer_performance.erb +59 -0
  69. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/_counters.erb +7 -5
  70. data/lib/karafka/web/pro/ui/views/consumers/_tabs.erb +35 -0
  71. data/lib/karafka/web/pro/ui/views/consumers/consumer/_commands.erb +32 -0
  72. data/lib/karafka/web/pro/ui/views/consumers/consumer/_no_jobs.erb +7 -0
  73. data/lib/karafka/web/pro/ui/views/consumers/consumer/_no_subscriptions.erb +7 -0
  74. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/consumer/_subscription_group.erb +13 -8
  75. data/lib/karafka/web/pro/ui/views/consumers/consumer/_title.erb +5 -0
  76. data/lib/karafka/web/pro/ui/views/consumers/controls.erb +67 -0
  77. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/details.erb +6 -1
  78. data/lib/karafka/web/pro/ui/views/consumers/index.erb +39 -0
  79. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/pending_jobs.erb +15 -7
  80. data/lib/karafka/web/pro/ui/views/consumers/performance.erb +52 -0
  81. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/running_jobs.erb +15 -7
  82. data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/subscriptions.erb +6 -1
  83. data/lib/karafka/web/{ui/pro → pro/ui}/views/dashboard/index.erb +10 -10
  84. data/lib/karafka/web/pro/ui/views/dlq/_no_topics.erb +7 -0
  85. data/lib/karafka/web/{ui/pro → pro/ui}/views/dlq/index.erb +1 -1
  86. data/lib/karafka/web/{ui/pro → pro/ui}/views/errors/_error.erb +2 -6
  87. data/lib/karafka/web/pro/ui/views/errors/_table.erb +23 -0
  88. data/lib/karafka/web/pro/ui/views/explorer/_failed_deserialization.erb +4 -0
  89. data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/_message.erb +7 -1
  90. data/lib/karafka/web/pro/ui/views/explorer/_no_topics.erb +5 -0
  91. data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/index.erb +1 -6
  92. data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/message/_metadata.erb +33 -9
  93. data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/message/_payload.erb +4 -4
  94. data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/message/_payload_actions.erb +1 -1
  95. data/lib/karafka/web/pro/ui/views/explorer/messages/_headers.erb +33 -0
  96. data/lib/karafka/web/pro/ui/views/explorer/messages/_key.erb +20 -0
  97. data/lib/karafka/web/pro/ui/views/explorer/partition/_cleaned.erb +5 -0
  98. data/lib/karafka/web/pro/ui/views/explorer/partition/_empty.erb +5 -0
  99. data/lib/karafka/web/pro/ui/views/explorer/partition/_messages.erb +21 -0
  100. data/lib/karafka/web/pro/ui/views/explorer/topic/_empty.erb +5 -0
  101. data/lib/karafka/web/pro/ui/views/explorer/topic/_limited.erb +10 -0
  102. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/_breadcrumbs.erb +8 -0
  103. data/lib/karafka/web/pro/ui/views/health/_no_data.erb +7 -0
  104. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/_partition.erb +1 -1
  105. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/_partition_lags.erb +6 -3
  106. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/_tabs.erb +11 -1
  107. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/changes.erb +13 -8
  108. data/lib/karafka/web/pro/ui/views/health/cluster_lags.erb +54 -0
  109. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/lags.erb +14 -8
  110. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/offsets.erb +15 -12
  111. data/lib/karafka/web/{ui/pro → pro/ui}/views/health/overview.erb +21 -7
  112. data/lib/karafka/web/{ui/pro → pro/ui}/views/jobs/_job.erb +1 -1
  113. data/lib/karafka/web/pro/ui/views/jobs/_no_jobs.erb +7 -0
  114. data/lib/karafka/web/{ui/pro → pro/ui}/views/jobs/pending.erb +12 -8
  115. data/lib/karafka/web/{ui/pro → pro/ui}/views/jobs/running.erb +12 -8
  116. data/lib/karafka/web/{ui/pro → pro/ui}/views/routing/_consumer_group.erb +2 -2
  117. data/lib/karafka/web/{ui/pro → pro/ui}/views/routing/index.erb +1 -1
  118. data/lib/karafka/web/{ui/pro → pro/ui}/views/routing/show.erb +1 -1
  119. data/lib/karafka/web/{ui/pro → pro/ui}/views/shared/_navigation.erb +14 -0
  120. data/lib/karafka/web/pro/ui/views/topics/_breadcrumbs.erb +37 -0
  121. data/lib/karafka/web/pro/ui/views/topics/_partition.erb +16 -0
  122. data/lib/karafka/web/pro/ui/views/topics/_tabs.erb +37 -0
  123. data/lib/karafka/web/pro/ui/views/topics/_topic.erb +12 -0
  124. data/lib/karafka/web/pro/ui/views/topics/config.erb +29 -0
  125. data/lib/karafka/web/pro/ui/views/topics/distribution/_badges.erb +7 -0
  126. data/lib/karafka/web/pro/ui/views/topics/distribution/_chart.erb +2 -0
  127. data/lib/karafka/web/pro/ui/views/topics/distribution/_empty_partitions.erb +1 -0
  128. data/lib/karafka/web/pro/ui/views/topics/distribution/_limited.erb +10 -0
  129. data/lib/karafka/web/pro/ui/views/topics/distribution/_partition.erb +10 -0
  130. data/lib/karafka/web/pro/ui/views/topics/distribution.erb +47 -0
  131. data/lib/karafka/web/pro/ui/views/topics/index.erb +16 -0
  132. data/lib/karafka/web/pro/ui/views/topics/replication.erb +28 -0
  133. data/lib/karafka/web/processing/consumers/aggregators/base.rb +1 -1
  134. data/lib/karafka/web/processing/consumers/aggregators/metrics.rb +1 -1
  135. data/lib/karafka/web/processing/consumers/aggregators/state.rb +4 -4
  136. data/lib/karafka/web/tracking/consumers/contracts/report.rb +1 -1
  137. data/lib/karafka/web/tracking/consumers/listeners/booting.rb +3 -1
  138. data/lib/karafka/web/tracking/consumers/listeners/errors.rb +2 -2
  139. data/lib/karafka/web/tracking/consumers/reporter.rb +3 -3
  140. data/lib/karafka/web/tracking/consumers/sampler.rb +2 -2
  141. data/lib/karafka/web/tracking/contracts/error.rb +1 -1
  142. data/lib/karafka/web/tracking/producers/listeners/booting.rb +3 -1
  143. data/lib/karafka/web/tracking/producers/listeners/errors.rb +2 -2
  144. data/lib/karafka/web/tracking/producers/reporter.rb +1 -1
  145. data/lib/karafka/web/tracking/producers/sampler.rb +1 -1
  146. data/lib/karafka/web/tracking/sampler.rb +3 -3
  147. data/lib/karafka/web/ui/app.rb +13 -9
  148. data/lib/karafka/web/ui/base.rb +1 -0
  149. data/lib/karafka/web/ui/controllers/{base.rb → base_controller.rb} +15 -2
  150. data/lib/karafka/web/ui/controllers/{become_pro.rb → become_pro_controller.rb} +1 -1
  151. data/lib/karafka/web/ui/controllers/{cluster.rb → cluster_controller.rb} +4 -4
  152. data/lib/karafka/web/ui/controllers/{consumers.rb → consumers_controller.rb} +3 -3
  153. data/lib/karafka/web/ui/controllers/{dashboard.rb → dashboard_controller.rb} +1 -1
  154. data/lib/karafka/web/ui/controllers/{errors.rb → errors_controller.rb} +2 -2
  155. data/lib/karafka/web/ui/controllers/{jobs.rb → jobs_controller.rb} +5 -5
  156. data/lib/karafka/web/ui/controllers/{routing.rb → routing_controller.rb} +2 -2
  157. data/lib/karafka/web/ui/controllers/{status.rb → status_controller.rb} +1 -1
  158. data/lib/karafka/web/ui/helpers/alerts_helper.rb +23 -0
  159. data/lib/karafka/web/ui/helpers/application_helper.rb +53 -1
  160. data/lib/karafka/web/ui/lib/paginations/offset_based.rb +3 -4
  161. data/lib/karafka/web/ui/lib/safe_runner.rb +59 -0
  162. data/lib/karafka/web/ui/models/broker.rb +66 -0
  163. data/lib/karafka/web/ui/models/health.rb +28 -2
  164. data/lib/karafka/web/ui/models/message.rb +9 -3
  165. data/lib/karafka/web/ui/models/process.rb +10 -5
  166. data/lib/karafka/web/ui/models/processes.rb +2 -2
  167. data/lib/karafka/web/ui/models/topic.rb +78 -0
  168. data/lib/karafka/web/ui/public/javascripts/application.js +18 -1
  169. data/lib/karafka/web/ui/public/javascripts/charts/data_formatting_utility.js +71 -0
  170. data/lib/karafka/web/ui/public/javascripts/charts/dataset_state_manager.js +49 -0
  171. data/lib/karafka/web/ui/public/javascripts/charts/types/bar.js +123 -0
  172. data/lib/karafka/web/ui/public/javascripts/charts/types/line.js +143 -0
  173. data/lib/karafka/web/ui/public/javascripts/charts.js +10 -325
  174. data/lib/karafka/web/ui/public/javascripts/live_poll.js +5 -5
  175. data/lib/karafka/web/ui/public/javascripts/tabs_manager.js +57 -0
  176. data/lib/karafka/web/ui/public/stylesheets/application.css +7 -6
  177. data/lib/karafka/web/ui/views/cluster/_breadcrumbs.erb +3 -3
  178. data/lib/karafka/web/ui/views/cluster/_no_partitions.erb +1 -3
  179. data/lib/karafka/web/ui/views/cluster/_tabs.erb +3 -3
  180. data/lib/karafka/web/ui/views/cluster/brokers.erb +19 -19
  181. data/lib/karafka/web/ui/views/cluster/replication.erb +37 -0
  182. data/lib/karafka/web/ui/views/consumers/_assignments_badges.erb +24 -0
  183. data/lib/karafka/web/ui/views/consumers/_consumer.erb +2 -15
  184. data/lib/karafka/web/ui/views/consumers/_counters.erb +1 -1
  185. data/lib/karafka/web/ui/views/consumers/_summary.erb +5 -5
  186. data/lib/karafka/web/ui/views/consumers/index.erb +22 -20
  187. data/lib/karafka/web/ui/views/dashboard/index.erb +9 -9
  188. data/lib/karafka/web/ui/views/errors/_cleaned.erb +1 -3
  189. data/lib/karafka/web/ui/views/errors/_error.erb +2 -6
  190. data/lib/karafka/web/ui/views/errors/_no_errors.erb +1 -3
  191. data/lib/karafka/web/ui/views/errors/index.erb +22 -20
  192. data/lib/karafka/web/ui/views/jobs/_job.erb +4 -1
  193. data/lib/karafka/web/ui/views/jobs/_no_jobs.erb +1 -3
  194. data/lib/karafka/web/ui/views/jobs/pending.erb +4 -3
  195. data/lib/karafka/web/ui/views/jobs/running.erb +4 -3
  196. data/lib/karafka/web/ui/views/routing/_consumer_group.erb +2 -2
  197. data/lib/karafka/web/ui/views/routing/index.erb +1 -1
  198. data/lib/karafka/web/ui/views/routing/show.erb +1 -1
  199. data/lib/karafka/web/ui/views/shared/_become_pro.erb +3 -3
  200. data/lib/karafka/web/ui/views/shared/_header.erb +16 -10
  201. data/lib/karafka/web/ui/views/shared/_navigation.erb +17 -3
  202. data/lib/karafka/web/ui/views/shared/_not_a_message.erb +5 -0
  203. data/lib/karafka/web/ui/views/shared/alerts/_info.erb +3 -0
  204. data/lib/karafka/web/ui/views/shared/charts/_bar.erb +7 -0
  205. data/lib/karafka/web/ui/views/shared/{_chart.erb → charts/_line.erb} +1 -1
  206. data/lib/karafka/web/ui/views/shared/exceptions/not_found.erb +1 -1
  207. data/lib/karafka/web/ui/views/status/show.erb +1 -1
  208. data/lib/karafka/web/version.rb +1 -1
  209. data/lib/karafka/web.rb +17 -1
  210. data.tar.gz.sig +0 -0
  211. metadata +189 -120
  212. metadata.gz.sig +0 -0
  213. data/lib/karafka/web/ui/pro/controllers/dlq.rb +0 -43
  214. data/lib/karafka/web/ui/pro/views/consumers/consumer/_no_jobs.erb +0 -9
  215. data/lib/karafka/web/ui/pro/views/consumers/consumer/_no_subscriptions.erb +0 -9
  216. data/lib/karafka/web/ui/pro/views/consumers/index.erb +0 -36
  217. data/lib/karafka/web/ui/pro/views/dlq/_no_topics.erb +0 -9
  218. data/lib/karafka/web/ui/pro/views/errors/_table.erb +0 -21
  219. data/lib/karafka/web/ui/pro/views/explorer/_failed_deserialization.erb +0 -4
  220. data/lib/karafka/web/ui/pro/views/explorer/_no_topics.erb +0 -7
  221. data/lib/karafka/web/ui/pro/views/explorer/messages/_headers.erb +0 -15
  222. data/lib/karafka/web/ui/pro/views/explorer/messages/_key.erb +0 -12
  223. data/lib/karafka/web/ui/pro/views/explorer/partition/_cleaned.erb +0 -3
  224. data/lib/karafka/web/ui/pro/views/explorer/partition/_empty.erb +0 -3
  225. data/lib/karafka/web/ui/pro/views/explorer/partition/_messages.erb +0 -19
  226. data/lib/karafka/web/ui/pro/views/explorer/topic/_empty.erb +0 -3
  227. data/lib/karafka/web/ui/pro/views/explorer/topic/_limited.erb +0 -4
  228. data/lib/karafka/web/ui/pro/views/health/_no_data.erb +0 -9
  229. data/lib/karafka/web/ui/pro/views/jobs/_no_jobs.erb +0 -9
  230. data/lib/karafka/web/ui/public/javascripts/tabs.js +0 -59
  231. data/lib/karafka/web/ui/views/cluster/topics.erb +0 -35
  232. /data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/consumer/_consumer_group.erb +0 -0
  233. /data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/consumer/_job.erb +0 -0
  234. /data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/consumer/_metrics.erb +0 -0
  235. /data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/consumer/_partition.erb +0 -0
  236. /data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/consumer/_stopped.erb +0 -0
  237. /data/lib/karafka/web/{ui/pro → pro/ui}/views/consumers/consumer/_tabs.erb +0 -0
  238. /data/lib/karafka/web/{ui/pro → pro/ui}/views/dlq/_breadcrumbs.erb +0 -0
  239. /data/lib/karafka/web/{ui/pro → pro/ui}/views/dlq/_topic.erb +0 -0
  240. /data/lib/karafka/web/{ui/pro → pro/ui}/views/errors/_breadcrumbs.erb +0 -0
  241. /data/lib/karafka/web/{ui/pro → pro/ui}/views/errors/_partition_option.erb +0 -0
  242. /data/lib/karafka/web/{ui/pro → pro/ui}/views/errors/_title_with_select.erb +0 -0
  243. /data/lib/karafka/web/{ui/pro → pro/ui}/views/errors/index.erb +0 -0
  244. /data/lib/karafka/web/{ui/pro → pro/ui}/views/errors/partition.erb +0 -0
  245. /data/lib/karafka/web/{ui/pro → pro/ui}/views/errors/show.erb +0 -0
  246. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/_breadcrumbs.erb +0 -0
  247. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/_filtered.erb +0 -0
  248. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/_partition_option.erb +0 -0
  249. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/_topic.erb +0 -0
  250. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/message/_message_actions.erb +0 -0
  251. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/messages/_detail.erb +0 -0
  252. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/partition/_details.erb +0 -0
  253. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/partition.erb +0 -0
  254. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/show.erb +0 -0
  255. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/topic/_details.erb +0 -0
  256. /data/lib/karafka/web/{ui/pro → pro/ui}/views/explorer/topic.erb +0 -0
  257. /data/lib/karafka/web/{ui/pro → pro/ui}/views/health/_consumer_group_header.erb +0 -0
  258. /data/lib/karafka/web/{ui/pro → pro/ui}/views/health/_partition_offset.erb +0 -0
  259. /data/lib/karafka/web/{ui/pro → pro/ui}/views/health/_partition_times.erb +0 -0
  260. /data/lib/karafka/web/{ui/pro → pro/ui}/views/routing/_detail.erb +0 -0
  261. /data/lib/karafka/web/{ui/pro → pro/ui}/views/routing/_topic.erb +0 -0
  262. /data/lib/karafka/web/ui/public/javascripts/{bootstrap.min.js → libs/bootstrap.min.js} +0 -0
  263. /data/lib/karafka/web/ui/public/javascripts/{chart.min.js → libs/chart.min.js} +0 -0
  264. /data/lib/karafka/web/ui/public/javascripts/{datepicker.js → libs/datepicker.js} +0 -0
  265. /data/lib/karafka/web/ui/public/javascripts/{highlight.min.js → libs/highlight.min.js} +0 -0
  266. /data/lib/karafka/web/ui/public/javascripts/{timeago.min.js → libs/timeago.min.js} +0 -0
  267. /data/lib/karafka/web/ui/public/stylesheets/{bootstrap.min.css → libs/bootstrap.min.css} +0 -0
  268. /data/lib/karafka/web/ui/public/stylesheets/{datepicker.min.css → libs/datepicker.min.css} +0 -0
  269. /data/lib/karafka/web/ui/public/stylesheets/{highlight.min.css → libs/highlight.min.css} +0 -0
@@ -13,17 +13,18 @@
13
13
 
14
14
  module Karafka
15
15
  module Web
16
- module Ui
16
+ # Namespace for all the pro components of the Web UI
17
+ module Pro
17
18
  # Pro Web UI components
18
- module Pro
19
+ module Ui
19
20
  # Main Roda Web App that servers all the metrics and stats
20
- class App < Ui::Base
21
- opts[:root] = Karafka::Web.gem_root.join('lib/karafka/web/ui/pro')
21
+ class App < Web::Ui::Base
22
+ opts[:root] = Karafka::Web.gem_root.join('lib/karafka/web/pro/ui')
22
23
 
23
24
  instance_exec(&CONTEXT_DETAILS)
24
25
 
25
26
  plugin :render, escape: true, engine: 'erb', allowed_paths: [
26
- Karafka::Web.gem_root.join('lib/karafka/web/ui/pro/views'),
27
+ Karafka::Web.gem_root.join('lib/karafka/web/pro/ui/views'),
27
28
  Karafka::Web.gem_root.join('lib/karafka/web/ui/views')
28
29
  ]
29
30
 
@@ -42,12 +43,25 @@ module Karafka
42
43
 
43
44
  r.get 'dashboard' do
44
45
  @breadcrumbs = false
45
- controller = Controllers::Dashboard.new(params)
46
+ controller = Controllers::DashboardController.new(params)
46
47
  controller.index
47
48
  end
48
49
 
49
50
  r.on 'consumers' do
50
- controller = Controllers::Consumers.new(params)
51
+ controller = Controllers::ConsumersController.new(params)
52
+
53
+ r.get 'overview' do
54
+ @breadcrumbs = false
55
+ controller.index
56
+ end
57
+
58
+ r.get 'performance' do
59
+ controller.performance
60
+ end
61
+
62
+ r.get 'controls' do
63
+ controller.controls
64
+ end
51
65
 
52
66
  r.on String, 'jobs' do |process_id|
53
67
  r.get 'running' do
@@ -69,14 +83,53 @@ module Karafka
69
83
  controller.details(process_id)
70
84
  end
71
85
 
86
+ r.redirect root_path('consumers/overview')
87
+ end
88
+
89
+ r.on 'commands' do
90
+ controller = Controllers::CommandsController.new(params)
91
+
92
+ r.on Integer do |offset_id|
93
+ controller.show(offset_id)
94
+ end
95
+
96
+ r.get 'recent' do
97
+ controller.recent
98
+ end
99
+
72
100
  r.get do
73
- @breadcrumbs = false
74
101
  controller.index
75
102
  end
76
103
  end
77
104
 
105
+ r.on 'commanding' do
106
+ controller = Controllers::CommandingController.new(params)
107
+
108
+ r.post 'quiet_all' do
109
+ controller.quiet_all
110
+ end
111
+
112
+ r.post 'stop_all' do
113
+ controller.stop_all
114
+ end
115
+
116
+ r.on String do |process_id|
117
+ r.post 'probe' do
118
+ controller.probe(process_id)
119
+ end
120
+
121
+ r.post 'quiet' do
122
+ controller.quiet(process_id)
123
+ end
124
+
125
+ r.post 'stop' do
126
+ controller.stop(process_id)
127
+ end
128
+ end
129
+ end
130
+
78
131
  r.on 'jobs' do
79
- controller = Controllers::Jobs.new(params)
132
+ controller = Controllers::JobsController.new(params)
80
133
 
81
134
  r.get 'running' do
82
135
  controller.running
@@ -90,7 +143,7 @@ module Karafka
90
143
  end
91
144
 
92
145
  r.on 'routing' do
93
- controller = Controllers::Routing.new(params)
146
+ controller = Controllers::RoutingController.new(params)
94
147
 
95
148
  r.get String do |topic_id|
96
149
  controller.show(topic_id)
@@ -102,7 +155,7 @@ module Karafka
102
155
  end
103
156
 
104
157
  r.on 'explorer' do
105
- controller = Controllers::Explorer.new(params)
158
+ controller = Controllers::ExplorerController.new(params)
106
159
 
107
160
  r.get String, Integer, 'recent' do |topic_id, partition_id|
108
161
  controller.recent(topic_id, partition_id)
@@ -145,7 +198,7 @@ module Karafka
145
198
  end
146
199
 
147
200
  r.on 'messages' do
148
- controller = Controllers::Messages.new(params)
201
+ controller = Controllers::MessagesController.new(params)
149
202
 
150
203
  r.post String, Integer, Integer, 'republish' do |topic_id, partition_id, offset|
151
204
  controller.republish(topic_id, partition_id, offset)
@@ -161,12 +214,16 @@ module Karafka
161
214
  end
162
215
 
163
216
  r.on 'health' do
164
- controller = Controllers::Health.new(params)
217
+ controller = Controllers::HealthController.new(params)
165
218
 
166
219
  r.get 'lags' do
167
220
  controller.lags
168
221
  end
169
222
 
223
+ r.get 'cluster_lags' do
224
+ controller.cluster_lags
225
+ end
226
+
170
227
  r.get 'offsets' do
171
228
  controller.offsets
172
229
  end
@@ -185,21 +242,45 @@ module Karafka
185
242
  end
186
243
 
187
244
  r.on 'cluster' do
188
- controller = Controllers::Cluster.new(params)
245
+ controller = Controllers::ClusterController.new(params)
189
246
 
190
- r.get 'brokers' do
191
- controller.brokers
247
+ r.get 'replication' do
248
+ # We use the non-pro controller here because this action is the same
249
+ controller = Ui::Controllers::ClusterController.new(params)
250
+ controller.replication
192
251
  end
193
252
 
194
- r.get 'topics' do
195
- controller.topics
253
+ r.get String do |broker_id|
254
+ controller.show(broker_id)
196
255
  end
197
256
 
198
- r.redirect root_path('cluster/brokers')
257
+ r.get do
258
+ controller.index
259
+ end
260
+ end
261
+
262
+ r.on 'topics' do
263
+ controller = Controllers::TopicsController.new(params)
264
+
265
+ r.get 'config', String do |topic_name|
266
+ controller.config(topic_name)
267
+ end
268
+
269
+ r.get 'replication', String do |topic_name|
270
+ controller.replication(topic_name)
271
+ end
272
+
273
+ r.get 'distribution', String do |topic_name|
274
+ controller.distribution(topic_name)
275
+ end
276
+
277
+ r.get do
278
+ controller.index
279
+ end
199
280
  end
200
281
 
201
282
  r.on 'errors' do
202
- controller = Controllers::Errors.new(params)
283
+ controller = Controllers::ErrorsController.new(params)
203
284
 
204
285
  r.get Integer, Integer do |partition_id, offset|
205
286
  if params.current_offset != -1
@@ -219,12 +300,12 @@ module Karafka
219
300
  end
220
301
 
221
302
  r.get 'dlq' do
222
- controller = Controllers::Dlq.new(params)
303
+ controller = Controllers::DlqController.new(params)
223
304
  controller.index
224
305
  end
225
306
 
226
307
  r.get 'status' do
227
- controller = Controllers::Status.new(params)
308
+ controller = Controllers::StatusController.new(params)
228
309
  controller.show
229
310
  end
230
311
  end
@@ -13,13 +13,12 @@
13
13
 
14
14
  module Karafka
15
15
  module Web
16
- module Ui
17
- module Pro
16
+ module Pro
17
+ module Ui
18
18
  # Namespace for Pro controllers
19
19
  module Controllers
20
- # Cluster controller
21
- class Cluster < Ui::Controllers::Cluster
22
- self.sortable_attributes = Ui::Controllers::Cluster.sortable_attributes
20
+ # Base Pro controller
21
+ class BaseController < Web::Ui::Controllers::BaseController
23
22
  end
24
23
  end
25
24
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Web
16
+ module Pro
17
+ module Ui
18
+ # Namespace for Pro controllers
19
+ module Controllers
20
+ # Cluster details controller
21
+ class ClusterController < Web::Ui::Controllers::ClusterController
22
+ self.sortable_attributes = %w[
23
+ id
24
+ name
25
+ default?
26
+ read_only?
27
+ synonym?
28
+ sensitive?
29
+ port
30
+ ].freeze
31
+
32
+ # Lists available brokers in the cluster
33
+ def index
34
+ @brokers = refine(Models::Broker.all)
35
+
36
+ render
37
+ end
38
+
39
+ # Displays selected broker configuration
40
+ #
41
+ # @param broker_id [String] id of the broker
42
+ def show(broker_id)
43
+ @broker = Models::Broker.find(broker_id)
44
+
45
+ @configs = refine(@broker.configs)
46
+
47
+ render
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Web
16
+ module Pro
17
+ module Ui
18
+ module Controllers
19
+ # Controller responsible for handling requests that should trigger some action on the
20
+ # consumers.
21
+ class CommandingController < BaseController
22
+ # Dispatches the probe request to a given process
23
+ #
24
+ # @param process_id [String]
25
+ def probe(process_id)
26
+ command(:probe, process_id)
27
+
28
+ redirect(
29
+ :back,
30
+ success: dispatched_to_one_msg(:probe, process_id)
31
+ )
32
+ end
33
+
34
+ # Dispatches the quiet request to a given process
35
+ #
36
+ # @param process_id [String]
37
+ def quiet(process_id)
38
+ command(:quiet, process_id)
39
+
40
+ redirect(
41
+ :back,
42
+ success: dispatched_to_one_msg(:quiet, process_id)
43
+ )
44
+ end
45
+
46
+ # Dispatches the stop request to a given process
47
+ #
48
+ # @param process_id [String]
49
+ def stop(process_id)
50
+ command(:stop, process_id)
51
+
52
+ redirect(
53
+ :back,
54
+ success: dispatched_to_one_msg(:stop, process_id)
55
+ )
56
+ end
57
+
58
+ # Dispatches the quiet request that should trigger on all consumers
59
+ def quiet_all
60
+ command(:quiet, '*')
61
+
62
+ redirect(
63
+ :back,
64
+ success: dispatched_to_all(:quiet)
65
+ )
66
+ end
67
+
68
+ # Dispatches the stop request that should trigger on all consumers
69
+ def stop_all
70
+ command(:stop, '*')
71
+
72
+ redirect(
73
+ :back,
74
+ success: dispatched_to_all(:stop)
75
+ )
76
+ end
77
+
78
+ private
79
+
80
+ # Dispatches given command
81
+ # @param command [Symbol] command
82
+ # @param process_id [String] process id
83
+ def command(command, process_id)
84
+ Commanding::Dispatcher.command(command, process_id)
85
+ end
86
+
87
+ # @param process_id [String] find given process
88
+ def find_process(process_id)
89
+ Models::Process.find(
90
+ Models::ConsumersState.current!,
91
+ process_id
92
+ )
93
+ end
94
+
95
+ # Generates a nice flash message about the dispatch
96
+ # @param command [Symbol]
97
+ # @param process_id [String]
98
+ # @return [String] flash message that command has been dispatched to a given process
99
+ def dispatched_to_one_msg(command, process_id)
100
+ command_name = command.to_s.capitalize
101
+
102
+ "The #{command_name} command has been dispatched to the #{process_id} process."
103
+ end
104
+
105
+ # Generates a nice flash message about dispatch of multi-process command
106
+ # @param command [Symbol]
107
+ # @return [String] flash message that command has been dispatched
108
+ def dispatched_to_all(command)
109
+ command_name = command.to_s.capitalize
110
+
111
+ "The #{command_name} command has been dispatched to all active processes."
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Web
16
+ module Pro
17
+ module Ui
18
+ module Controllers
19
+ # Controller for viewing details of dispatched commands and their results
20
+ class CommandsController < BaseController
21
+ # Lists commands from the consumers commands topic
22
+ def index
23
+ @schema_version = Commanding::Dispatcher::SCHEMA_VERSION
24
+ @watermark_offsets = Models::WatermarkOffsets.find(commands_topic, 0)
25
+
26
+ previous_offset, @command_messages, next_offset = current_partition_data
27
+
28
+ # If message is an array, it means it's a compacted dummy offset representation
29
+ mapped_messages = @command_messages.map do |message|
30
+ message.is_a?(Array) ? message.last : message.offset
31
+ end
32
+
33
+ paginate(
34
+ previous_offset,
35
+ @params.current_offset,
36
+ next_offset,
37
+ mapped_messages
38
+ )
39
+
40
+ render
41
+ end
42
+
43
+ # Shows details about given command / result
44
+ #
45
+ # @param offset [Integer] offset of the command message we're interested in
46
+ def show(offset)
47
+ @schema_version = Commanding::Dispatcher::SCHEMA_VERSION
48
+ @command_message = Models::Message.find(
49
+ commands_topic,
50
+ 0,
51
+ offset
52
+ )
53
+
54
+ render
55
+ end
56
+
57
+ # Displays the most recent available command message details
58
+ def recent
59
+ # We read 25 just in case there would be a lot of transactional noise
60
+ messages = ::Karafka::Admin.read_topic(commands_topic, 0, 25)
61
+
62
+ # We find the most recent (last since they are shipped in reverse order)
63
+ recent = messages.reverse.find { |message| !message.is_a?(Array) }
64
+
65
+ return show(recent.offset) if recent
66
+
67
+ # If nothing found, lets redirect user back to the commands list
68
+ redirect(
69
+ 'commands',
70
+ warning: 'No recent commands available.'
71
+ )
72
+ end
73
+
74
+ private
75
+
76
+ # @return [Array] Array with requested messages as well as pagination details and other
77
+ # obtained metadata
78
+ def current_partition_data
79
+ Models::Message.offset_page(
80
+ commands_topic,
81
+ 0,
82
+ @params.current_offset,
83
+ @watermark_offsets
84
+ )
85
+ end
86
+
87
+ # @return [String] consumers commands topic name
88
+ def commands_topic
89
+ ::Karafka::Web.config.topics.consumers.commands
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -13,14 +13,18 @@
13
13
 
14
14
  module Karafka
15
15
  module Web
16
- module Ui
17
- module Pro
16
+ module Pro
17
+ module Ui
18
18
  module Controllers
19
19
  # Controller for displaying consumers states and details about them
20
- class Consumers < Ui::Controllers::Base
20
+ class ConsumersController < BaseController
21
+ include Web::Ui::Lib::Paginations
22
+
21
23
  self.sortable_attributes = %w[
22
24
  id
25
+ process_id
23
26
  name
27
+ status
24
28
  started_at
25
29
  lag_hybrid
26
30
  lag_hybrid_d
@@ -36,6 +40,15 @@ module Karafka
36
40
  first_offset
37
41
  last_offset
38
42
  updated_at
43
+ memory_usage
44
+ threads
45
+ utilization
46
+ busy
47
+ workers
48
+ active
49
+ standby
50
+ running_jobs_count
51
+ pending_jobs_count
39
52
  ].freeze
40
53
 
41
54
  # Consumers list
@@ -43,7 +56,7 @@ module Karafka
43
56
  @current_state = Models::ConsumersState.current!
44
57
  @counters = Models::Counters.new(@current_state)
45
58
 
46
- @processes, last_page = Lib::Paginations::Paginators::Arrays.call(
59
+ @processes, last_page = Paginators::Arrays.call(
47
60
  refine(Models::Processes.active(@current_state)),
48
61
  @params.current_page
49
62
  )
@@ -53,6 +66,20 @@ module Karafka
53
66
  render
54
67
  end
55
68
 
69
+ # Displays per-process performance details
70
+ def performance
71
+ index
72
+
73
+ render
74
+ end
75
+
76
+ # Displays processes with details + ability to manage
77
+ def controls
78
+ index
79
+
80
+ render
81
+ end
82
+
56
83
  # @param process_id [String] id of the process we're interested in
57
84
  def details(process_id)
58
85
  current_state = Models::ConsumersState.current!
@@ -13,11 +13,13 @@
13
13
 
14
14
  module Karafka
15
15
  module Web
16
- module Ui
17
- module Pro
16
+ module Pro
17
+ module Ui
18
18
  module Controllers
19
19
  # Main Karafka Pro Web-Ui dashboard controller
20
- class Dashboard < Ui::Controllers::Base
20
+ class DashboardController < BaseController
21
+ include Web::Ui
22
+
21
23
  # View with statistics dashboard details
22
24
  def index
23
25
  @current_state = Models::ConsumersState.current!
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Web
16
+ module Pro
17
+ module Ui
18
+ module Controllers
19
+ # DLQ topics overview
20
+ class DlqController < BaseController
21
+ # Lists DLQ topics
22
+ def index
23
+ topics = Karafka::App.consumer_groups.flat_map(&:topics).flat_map(&:to_a)
24
+
25
+ dlq_topic_patterns = topics
26
+ .map { |source_topic| source_topic.dead_letter_queue.topic }
27
+ .uniq
28
+ .compact
29
+ .select(&:itself)
30
+
31
+ dlq_topic_patterns += Web.config.ui.dlq_patterns
32
+
33
+ @dlq_topics = Models::ClusterInfo
34
+ .topics
35
+ .select { |topic| dlq?(dlq_topic_patterns, topic[:topic_name]) }
36
+ .sort_by { |topic| topic[:topic_name] }
37
+
38
+ render
39
+ end
40
+
41
+ private
42
+
43
+ # Checks if topic is in topics we consider DLQ or if it matches any predefined regular
44
+ # expressions used for auto-DLQ discovery
45
+ #
46
+ # @param topics_matches [Array<String, Regexp>] array with list of DLQ topics matches
47
+ # from the routing and regular expressions for auto-discovery
48
+ # @param name [String] topic name for which we want to know if it is used in DLQ
49
+ # @return [Boolean] is the given topic a DLQ topic
50
+ def dlq?(topics_matches, name)
51
+ topics_matches.any? do |candidate|
52
+ candidate.match?(name)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -13,13 +13,11 @@
13
13
 
14
14
  module Karafka
15
15
  module Web
16
- module Ui
17
- module Pro
16
+ module Pro
17
+ module Ui
18
18
  module Controllers
19
19
  # Errors details controller
20
- class Errors < Ui::Controllers::Base
21
- include Ui::Lib::Paginations
22
-
20
+ class ErrorsController < BaseController
23
21
  # Lists all the errors from all the partitions
24
22
  def index
25
23
  @topic_id = errors_topic
@@ -41,7 +39,7 @@ module Karafka
41
39
  # @param partition_id [Integer] id of the partition of errors we are interested in
42
40
  def partition(partition_id)
43
41
  @partition_id = partition_id
44
- @watermark_offsets = Ui::Models::WatermarkOffsets.find(errors_topic, @partition_id)
42
+ @watermark_offsets = Models::WatermarkOffsets.find(errors_topic, @partition_id)
45
43
  @partitions_count = Models::ClusterInfo.partitions_count(errors_topic)
46
44
 
47
45
  previous_offset, @error_messages, next_offset = Models::Message.offset_page(
@@ -74,7 +72,7 @@ module Karafka
74
72
  @offset
75
73
  )
76
74
 
77
- watermark_offsets = Ui::Models::WatermarkOffsets.find(errors_topic, partition_id)
75
+ watermark_offsets = Models::WatermarkOffsets.find(errors_topic, partition_id)
78
76
  paginate(offset, watermark_offsets.low, watermark_offsets.high)
79
77
 
80
78
  render