karafka-web 0.9.2 → 0.10.0.beta1

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 (417) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ci.yml +30 -0
  4. data/.gitignore +2 -0
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +84 -3
  7. data/Gemfile +1 -0
  8. data/Gemfile.lock +30 -25
  9. data/LICENSE +1 -1
  10. data/bin/build_assets +51 -0
  11. data/bin/release +6 -0
  12. data/config/locales/pro_errors.yml +18 -0
  13. data/docker-compose.yml +1 -1
  14. data/gulpfile.js +73 -0
  15. data/karafka-web.gemspec +7 -2
  16. data/lib/karafka/web/config.rb +9 -10
  17. data/lib/karafka/web/contracts/base.rb +2 -0
  18. data/lib/karafka/web/contracts/config.rb +2 -1
  19. data/lib/karafka/web/errors.rb +12 -0
  20. data/lib/karafka/web/inflector.rb +1 -1
  21. data/lib/karafka/web/management/actions/enable.rb +11 -0
  22. data/lib/karafka/web/management/migrations/consumers_metrics/0_set_initial.rb +39 -0
  23. data/lib/karafka/web/management/migrations/consumers_metrics/1699543515_fill_missing_received_and_sent_bytes.rb +28 -0
  24. data/lib/karafka/web/management/migrations/consumers_metrics/1700234522_introduce_waiting.rb +26 -0
  25. data/lib/karafka/web/management/migrations/consumers_metrics/1700234522_remove_processing.rb +26 -0
  26. data/lib/karafka/web/management/migrations/consumers_metrics/1704722380_split_listeners_into_active_and_paused.rb +38 -0
  27. data/lib/karafka/web/management/migrations/consumers_metrics/1706607960_introduce_lag_total.rb +40 -0
  28. data/lib/karafka/web/management/migrations/consumers_metrics/1706611396_rename_lag_total_to_lag_hybrid.rb +38 -0
  29. data/lib/karafka/web/management/migrations/consumers_metrics/1716218393_populate_jobs_metrics.rb +26 -0
  30. data/lib/karafka/web/management/migrations/consumers_states/0_set_initial.rb +46 -0
  31. data/lib/karafka/web/management/migrations/consumers_states/1699543515_fill_missing_received_and_sent_bytes.rb +25 -0
  32. data/lib/karafka/web/management/migrations/consumers_states/1700234522_introduce_waiting.rb +22 -0
  33. data/lib/karafka/web/management/migrations/consumers_states/1700234522_remove_processing.rb +22 -0
  34. data/lib/karafka/web/management/migrations/consumers_states/1704722380_split_listeners_into_active_and_paused.rb +34 -0
  35. data/lib/karafka/web/management/migrations/consumers_states/1706607960_introduce_lag_total.rb +24 -0
  36. data/lib/karafka/web/management/migrations/consumers_states/1706611396_rename_lag_total_to_lag_hybrid.rb +23 -0
  37. data/lib/karafka/web/management/migrations/consumers_states/1716218393_add_jobs_counter.rb +24 -0
  38. data/lib/karafka/web/management/migrator.rb +5 -5
  39. data/lib/karafka/web/pro/commanding/commands/base.rb +8 -0
  40. data/lib/karafka/web/pro/commanding/commands/quiet.rb +4 -1
  41. data/lib/karafka/web/pro/commanding/commands/stop.rb +4 -1
  42. data/lib/karafka/web/pro/loader.rb +8 -0
  43. data/lib/karafka/web/pro/ui/app.rb +44 -7
  44. data/lib/karafka/web/pro/ui/controllers/dlq_controller.rb +1 -1
  45. data/lib/karafka/web/pro/ui/controllers/errors_controller.rb +1 -0
  46. data/lib/karafka/web/pro/ui/controllers/explorer_controller.rb +6 -14
  47. data/lib/karafka/web/pro/ui/controllers/messages_controller.rb +5 -4
  48. data/lib/karafka/web/pro/ui/controllers/search_controller.rb +73 -0
  49. data/lib/karafka/web/pro/ui/controllers/support_controller.rb +26 -0
  50. data/lib/karafka/web/pro/ui/controllers/topics_controller.rb +31 -0
  51. data/lib/karafka/web/pro/ui/controllers/ux_controller.rb +26 -0
  52. data/lib/karafka/web/pro/ui/lib/policies/config.rb +39 -0
  53. data/lib/karafka/web/pro/ui/lib/policies/contracts/config.rb +46 -0
  54. data/lib/karafka/web/pro/ui/lib/policies/messages.rb +76 -0
  55. data/lib/karafka/web/pro/ui/lib/policies/requests.rb +36 -0
  56. data/lib/karafka/web/pro/ui/lib/policies.rb +34 -0
  57. data/lib/karafka/web/pro/ui/lib/safe_runner.rb +98 -0
  58. data/lib/karafka/web/pro/ui/lib/search/config.rb +53 -0
  59. data/lib/karafka/web/pro/ui/lib/search/contracts/config.rb +101 -0
  60. data/lib/karafka/web/pro/ui/lib/search/contracts/form.rb +111 -0
  61. data/lib/karafka/web/pro/ui/lib/search/matchers/base.rb +59 -0
  62. data/lib/karafka/web/pro/ui/lib/search/matchers/raw_header_includes.rb +57 -0
  63. data/lib/karafka/web/pro/ui/lib/search/matchers/raw_key_includes.rb +41 -0
  64. data/lib/karafka/web/pro/ui/lib/search/matchers/raw_payload_includes.rb +45 -0
  65. data/lib/karafka/web/pro/ui/lib/search/normalizer.rb +47 -0
  66. data/lib/karafka/web/pro/ui/lib/search/runner.rb +230 -0
  67. data/lib/karafka/web/pro/ui/lib/search.rb +36 -0
  68. data/lib/karafka/web/pro/ui/views/cluster/_breadcrumbs.erb +4 -4
  69. data/lib/karafka/web/pro/ui/views/cluster/_tabs.erb +14 -24
  70. data/lib/karafka/web/pro/ui/views/cluster/index.erb +20 -22
  71. data/lib/karafka/web/pro/ui/views/cluster/show.erb +21 -25
  72. data/lib/karafka/web/pro/ui/views/commands/_backtrace.erb +4 -19
  73. data/lib/karafka/web/pro/ui/views/commands/_breadcrumbs.erb +3 -3
  74. data/lib/karafka/web/pro/ui/views/commands/_command.erb +6 -6
  75. data/lib/karafka/web/pro/ui/views/commands/_command_details.erb +1 -11
  76. data/lib/karafka/web/pro/ui/views/commands/_incompatible_schema.erb +3 -14
  77. data/lib/karafka/web/pro/ui/views/commands/_metadata.erb +33 -42
  78. data/lib/karafka/web/pro/ui/views/commands/_table.erb +9 -3
  79. data/lib/karafka/web/pro/ui/views/commands/index.erb +18 -12
  80. data/lib/karafka/web/pro/ui/views/commands/show.erb +24 -29
  81. data/lib/karafka/web/pro/ui/views/consumers/_breadcrumbs.erb +8 -8
  82. data/lib/karafka/web/pro/ui/views/consumers/_consumer.erb +13 -23
  83. data/lib/karafka/web/pro/ui/views/consumers/_consumer_controls.erb +51 -35
  84. data/lib/karafka/web/pro/ui/views/consumers/_consumer_performance.erb +1 -1
  85. data/lib/karafka/web/pro/ui/views/consumers/_tabs.erb +28 -30
  86. data/lib/karafka/web/pro/ui/views/consumers/consumer/_commands.erb +68 -28
  87. data/lib/karafka/web/pro/ui/views/consumers/consumer/_job.erb +1 -1
  88. data/lib/karafka/web/pro/ui/views/consumers/consumer/_metrics.erb +114 -133
  89. data/lib/karafka/web/pro/ui/views/consumers/consumer/_partition.erb +4 -4
  90. data/lib/karafka/web/pro/ui/views/consumers/consumer/_stopped.erb +6 -9
  91. data/lib/karafka/web/pro/ui/views/consumers/consumer/_subscription_group.erb +116 -126
  92. data/lib/karafka/web/pro/ui/views/consumers/consumer/_tabs.erb +26 -31
  93. data/lib/karafka/web/pro/ui/views/consumers/controls.erb +53 -57
  94. data/lib/karafka/web/pro/ui/views/consumers/details.erb +4 -17
  95. data/lib/karafka/web/pro/ui/views/consumers/index.erb +31 -34
  96. data/lib/karafka/web/pro/ui/views/consumers/pending_jobs.erb +41 -46
  97. data/lib/karafka/web/pro/ui/views/consumers/performance.erb +43 -47
  98. data/lib/karafka/web/pro/ui/views/consumers/running_jobs.erb +41 -46
  99. data/lib/karafka/web/pro/ui/views/consumers/subscriptions.erb +14 -17
  100. data/lib/karafka/web/pro/ui/views/dashboard/index.erb +67 -76
  101. data/lib/karafka/web/pro/ui/views/dlq/_breadcrumbs.erb +1 -1
  102. data/lib/karafka/web/pro/ui/views/dlq/_no_topics.erb +1 -7
  103. data/lib/karafka/web/pro/ui/views/dlq/_topic.erb +7 -10
  104. data/lib/karafka/web/pro/ui/views/dlq/index.erb +8 -10
  105. data/lib/karafka/web/pro/ui/views/errors/_breadcrumbs.erb +3 -3
  106. data/lib/karafka/web/pro/ui/views/errors/_error.erb +8 -5
  107. data/lib/karafka/web/pro/ui/views/errors/_selector.erb +12 -0
  108. data/lib/karafka/web/pro/ui/views/errors/_table.erb +5 -4
  109. data/lib/karafka/web/pro/ui/views/errors/index.erb +50 -15
  110. data/lib/karafka/web/pro/ui/views/errors/partition.erb +61 -14
  111. data/lib/karafka/web/pro/ui/views/errors/show.erb +28 -46
  112. data/lib/karafka/web/pro/ui/views/explorer/_breadcrumbs.erb +11 -3
  113. data/lib/karafka/web/pro/ui/views/explorer/_failed_deserialization.erb +8 -3
  114. data/lib/karafka/web/pro/ui/views/explorer/_message.erb +12 -6
  115. data/lib/karafka/web/pro/ui/views/explorer/_no_topics.erb +1 -5
  116. data/lib/karafka/web/pro/ui/views/explorer/_selector.erb +12 -0
  117. data/lib/karafka/web/pro/ui/views/explorer/_topic.erb +6 -8
  118. data/lib/karafka/web/pro/ui/views/explorer/index.erb +13 -15
  119. data/lib/karafka/web/pro/ui/views/explorer/message/_metadata.erb +68 -32
  120. data/lib/karafka/web/pro/ui/views/explorer/message/_payload.erb +17 -16
  121. data/lib/karafka/web/pro/ui/views/explorer/message/_resources_utilization.erb +127 -0
  122. data/lib/karafka/web/pro/ui/views/explorer/message/_too_big_to_be_displayed.erb +20 -0
  123. data/lib/karafka/web/pro/ui/views/explorer/messages/_detail.erb +1 -1
  124. data/lib/karafka/web/pro/ui/views/explorer/partition/_cleaned.erb +3 -5
  125. data/lib/karafka/web/pro/ui/views/explorer/partition/_empty.erb +3 -5
  126. data/lib/karafka/web/pro/ui/views/explorer/partition/_messages.erb +6 -3
  127. data/lib/karafka/web/pro/ui/views/explorer/partition.erb +67 -46
  128. data/lib/karafka/web/pro/ui/views/explorer/show.erb +85 -21
  129. data/lib/karafka/web/pro/ui/views/explorer/topic/_actions.erb +27 -0
  130. data/lib/karafka/web/pro/ui/views/explorer/topic/_empty.erb +3 -5
  131. data/lib/karafka/web/pro/ui/views/explorer/topic/_limited.erb +8 -10
  132. data/lib/karafka/web/pro/ui/views/explorer/topic.erb +24 -44
  133. data/lib/karafka/web/pro/ui/views/health/_breadcrumbs.erb +7 -7
  134. data/lib/karafka/web/pro/ui/views/health/_no_data.erb +1 -7
  135. data/lib/karafka/web/pro/ui/views/health/_partition.erb +3 -3
  136. data/lib/karafka/web/pro/ui/views/health/_partition_lags.erb +3 -3
  137. data/lib/karafka/web/pro/ui/views/health/_partition_offset.erb +2 -2
  138. data/lib/karafka/web/pro/ui/views/health/_partition_times.erb +3 -7
  139. data/lib/karafka/web/pro/ui/views/health/_table_metadata.erb +8 -0
  140. data/lib/karafka/web/pro/ui/views/health/_tabs.erb +32 -49
  141. data/lib/karafka/web/pro/ui/views/health/changes.erb +51 -51
  142. data/lib/karafka/web/pro/ui/views/health/cluster_lags.erb +28 -41
  143. data/lib/karafka/web/pro/ui/views/health/lags.erb +52 -52
  144. data/lib/karafka/web/pro/ui/views/health/offsets.erb +55 -55
  145. data/lib/karafka/web/pro/ui/views/health/overview.erb +60 -60
  146. data/lib/karafka/web/pro/ui/views/jobs/_job.erb +1 -1
  147. data/lib/karafka/web/pro/ui/views/jobs/_no_jobs.erb +1 -7
  148. data/lib/karafka/web/pro/ui/views/jobs/pending.erb +36 -38
  149. data/lib/karafka/web/pro/ui/views/jobs/running.erb +36 -38
  150. data/lib/karafka/web/pro/ui/views/routing/_consumer_group.erb +7 -12
  151. data/lib/karafka/web/pro/ui/views/routing/_topic.erb +13 -11
  152. data/lib/karafka/web/pro/ui/views/routing/index.erb +7 -9
  153. data/lib/karafka/web/pro/ui/views/routing/show.erb +41 -33
  154. data/lib/karafka/web/pro/ui/views/search/_fix_errors.erb +3 -0
  155. data/lib/karafka/web/pro/ui/views/search/_metadata.erb +71 -0
  156. data/lib/karafka/web/pro/ui/views/search/_no_results.erb +3 -0
  157. data/lib/karafka/web/pro/ui/views/search/_no_search_criteria.erb +5 -0
  158. data/lib/karafka/web/pro/ui/views/search/_search_criteria.erb +37 -0
  159. data/lib/karafka/web/pro/ui/views/search/_search_modal.erb +139 -0
  160. data/lib/karafka/web/pro/ui/views/search/_timeout.erb +3 -0
  161. data/lib/karafka/web/pro/ui/views/search/index.erb +29 -0
  162. data/lib/karafka/web/pro/ui/views/shared/_navigation.erb +80 -28
  163. data/lib/karafka/web/pro/ui/views/topics/_breadcrumbs.erb +14 -6
  164. data/lib/karafka/web/pro/ui/views/topics/_partition_offsets.erb +10 -0
  165. data/lib/karafka/web/pro/ui/views/topics/_tabs.erb +26 -32
  166. data/lib/karafka/web/pro/ui/views/topics/_topic.erb +7 -10
  167. data/lib/karafka/web/pro/ui/views/topics/config.erb +21 -25
  168. data/lib/karafka/web/pro/ui/views/topics/distribution/_badges.erb +10 -5
  169. data/lib/karafka/web/pro/ui/views/topics/distribution/_chart.erb +3 -1
  170. data/lib/karafka/web/pro/ui/views/topics/distribution/_limited.erb +1 -1
  171. data/lib/karafka/web/pro/ui/views/topics/distribution.erb +34 -39
  172. data/lib/karafka/web/pro/ui/views/topics/index.erb +13 -15
  173. data/lib/karafka/web/pro/ui/views/topics/offsets.erb +24 -0
  174. data/lib/karafka/web/pro/ui/views/topics/replication.erb +20 -24
  175. data/lib/karafka/web/processing/consumers/aggregators/metrics.rb +1 -1
  176. data/lib/karafka/web/processing/consumers/aggregators/state.rb +1 -1
  177. data/lib/karafka/web/processing/consumers/contracts/aggregated_stats.rb +1 -0
  178. data/lib/karafka/web/tracking/consumers/contracts/report.rb +6 -0
  179. data/lib/karafka/web/tracking/consumers/listeners/connections.rb +8 -6
  180. data/lib/karafka/web/tracking/consumers/listeners/processing.rb +2 -0
  181. data/lib/karafka/web/tracking/consumers/listeners/tags.rb +1 -1
  182. data/lib/karafka/web/tracking/consumers/reporter.rb +6 -8
  183. data/lib/karafka/web/tracking/consumers/sampler.rb +16 -5
  184. data/lib/karafka/web/ui/app.rb +20 -1
  185. data/lib/karafka/web/ui/base.rb +26 -20
  186. data/lib/karafka/web/ui/controllers/base_controller.rb +6 -4
  187. data/lib/karafka/web/ui/controllers/dashboard_controller.rb +8 -0
  188. data/lib/karafka/web/ui/controllers/requests/params.rb +16 -2
  189. data/lib/karafka/web/ui/controllers/support_controller.rb +17 -0
  190. data/lib/karafka/web/ui/controllers/ux_controller.rb +17 -0
  191. data/lib/karafka/web/ui/helpers/application_helper.rb +75 -42
  192. data/lib/karafka/web/ui/helpers/paths_helper.rb +24 -0
  193. data/lib/karafka/web/ui/helpers/tailwind_helper.rb +90 -0
  194. data/lib/karafka/web/ui/lib/sorter.rb +1 -1
  195. data/lib/karafka/web/ui/models/metrics/aggregated.rb +1 -0
  196. data/lib/karafka/web/ui/models/metrics/charts/topics.rb +36 -20
  197. data/lib/karafka/web/ui/models/status.rb +28 -1
  198. data/lib/karafka/web/ui/public/images/calendar.svg +3 -0
  199. data/lib/karafka/web/ui/public/javascripts/application.js +39 -15
  200. data/lib/karafka/web/ui/public/javascripts/application.min.js +64 -0
  201. data/lib/karafka/web/ui/public/javascripts/application.min.js.br +0 -0
  202. data/lib/karafka/web/ui/public/javascripts/application.min.js.gz +0 -0
  203. data/lib/karafka/web/ui/public/javascripts/charts/types/line.js +41 -9
  204. data/lib/karafka/web/ui/public/javascripts/components/btn_toggle_manager.js +37 -0
  205. data/lib/karafka/web/ui/public/javascripts/{live_poll.js → components/live_poll.js} +44 -8
  206. data/lib/karafka/web/ui/public/javascripts/{offset_datetime.js → components/offset_datetime.js} +1 -1
  207. data/lib/karafka/web/ui/public/javascripts/components/search.js +102 -0
  208. data/lib/karafka/web/ui/public/javascripts/components/tabs_manager.js +84 -0
  209. data/lib/karafka/web/ui/public/javascripts/components/theme_manager.js +59 -0
  210. data/lib/karafka/web/ui/public/javascripts/components/turbo_tracker.js +30 -0
  211. data/lib/karafka/web/ui/public/javascripts/libs/datepicker.js +2 -2
  212. data/lib/karafka/web/ui/public/javascripts/libs/turbo.js +6618 -0
  213. data/lib/karafka/web/ui/public/stylesheets/application.css +16 -113
  214. data/lib/karafka/web/ui/public/stylesheets/application.min.css +13 -0
  215. data/lib/karafka/web/ui/public/stylesheets/application.min.css.br +0 -0
  216. data/lib/karafka/web/ui/public/stylesheets/application.min.css.gz +0 -0
  217. data/lib/karafka/web/ui/public/stylesheets/libs/highlight_dark.min.css +8 -0
  218. data/lib/karafka/web/ui/public/stylesheets/libs/highlight_dark.min.css.br +0 -0
  219. data/lib/karafka/web/ui/public/stylesheets/libs/highlight_dark.min.css.gz +0 -0
  220. data/lib/karafka/web/ui/public/stylesheets/libs/highlight_light.min.css.br +0 -0
  221. data/lib/karafka/web/ui/public/stylesheets/libs/highlight_light.min.css.gz +0 -0
  222. data/lib/karafka/web/ui/public/stylesheets/libs/tailwind.css +391 -0
  223. data/lib/karafka/web/ui/views/cluster/_breadcrumbs.erb +3 -3
  224. data/lib/karafka/web/ui/views/cluster/_tabs.erb +14 -24
  225. data/lib/karafka/web/ui/views/cluster/brokers.erb +20 -22
  226. data/lib/karafka/web/ui/views/cluster/replication.erb +28 -32
  227. data/lib/karafka/web/ui/views/consumers/_assignments_badges.erb +1 -1
  228. data/lib/karafka/web/ui/views/consumers/_breadcrumbs.erb +5 -0
  229. data/lib/karafka/web/ui/views/consumers/_consumer.erb +9 -13
  230. data/lib/karafka/web/ui/views/consumers/_no_consumers.erb +2 -8
  231. data/lib/karafka/web/ui/views/consumers/_summary.erb +34 -45
  232. data/lib/karafka/web/ui/views/consumers/_tabs.erb +35 -0
  233. data/lib/karafka/web/ui/views/consumers/index.erb +31 -33
  234. data/lib/karafka/web/ui/views/dashboard/_counters.erb +76 -0
  235. data/lib/karafka/web/ui/views/dashboard/_feature_pro.erb +6 -2
  236. data/lib/karafka/web/ui/views/dashboard/_not_enough_data.erb +3 -15
  237. data/lib/karafka/web/ui/views/dashboard/_ranges_selector.erb +12 -12
  238. data/lib/karafka/web/ui/views/dashboard/index.erb +78 -52
  239. data/lib/karafka/web/ui/views/errors/_breadcrumbs.erb +2 -2
  240. data/lib/karafka/web/ui/views/errors/_detail.erb +1 -3
  241. data/lib/karafka/web/ui/views/errors/_error.erb +3 -5
  242. data/lib/karafka/web/ui/views/errors/index.erb +34 -44
  243. data/lib/karafka/web/ui/views/errors/show.erb +29 -47
  244. data/lib/karafka/web/ui/views/jobs/_breadcrumbs.erb +3 -3
  245. data/lib/karafka/web/ui/views/jobs/_job.erb +1 -1
  246. data/lib/karafka/web/ui/views/jobs/_no_jobs.erb +1 -7
  247. data/lib/karafka/web/ui/views/jobs/_tabs.erb +14 -24
  248. data/lib/karafka/web/ui/views/jobs/pending.erb +30 -32
  249. data/lib/karafka/web/ui/views/jobs/running.erb +30 -32
  250. data/lib/karafka/web/ui/views/layout.erb +37 -21
  251. data/lib/karafka/web/ui/views/routing/_breadcrumbs.erb +2 -2
  252. data/lib/karafka/web/ui/views/routing/_consumer_group.erb +7 -12
  253. data/lib/karafka/web/ui/views/routing/_topic.erb +3 -5
  254. data/lib/karafka/web/ui/views/routing/index.erb +7 -9
  255. data/lib/karafka/web/ui/views/routing/show.erb +30 -22
  256. data/lib/karafka/web/ui/views/shared/_become_pro.erb +8 -8
  257. data/lib/karafka/web/ui/views/shared/_brand.erb +2 -2
  258. data/lib/karafka/web/ui/views/shared/_breadcrumbs.erb +23 -0
  259. data/lib/karafka/web/ui/views/shared/_content.erb +2 -28
  260. data/lib/karafka/web/ui/views/shared/_controls.erb +15 -0
  261. data/lib/karafka/web/ui/views/shared/_flashes.erb +5 -7
  262. data/lib/karafka/web/ui/views/shared/_header.erb +14 -19
  263. data/lib/karafka/web/ui/views/shared/_navigation.erb +84 -28
  264. data/lib/karafka/web/ui/views/shared/_no_paginated_data.erb +5 -9
  265. data/lib/karafka/web/ui/views/shared/_pagination.erb +11 -11
  266. data/lib/karafka/web/ui/views/shared/_tab_nav.erb +4 -5
  267. data/lib/karafka/web/ui/views/shared/_title.erb +5 -0
  268. data/lib/karafka/web/ui/views/shared/alerts/_box_error.erb +15 -0
  269. data/lib/karafka/web/ui/views/shared/alerts/_box_info.erb +15 -0
  270. data/lib/karafka/web/ui/views/shared/alerts/_box_primary.erb +15 -0
  271. data/lib/karafka/web/ui/views/shared/alerts/_box_secondary.erb +15 -0
  272. data/lib/karafka/web/ui/views/shared/alerts/_box_success.erb +15 -0
  273. data/lib/karafka/web/ui/views/shared/alerts/_box_warning.erb +15 -0
  274. data/lib/karafka/web/ui/views/shared/alerts/_error.erb +4 -0
  275. data/lib/karafka/web/ui/views/shared/alerts/_info.erb +5 -2
  276. data/lib/karafka/web/ui/views/shared/alerts/_primary.erb +4 -0
  277. data/lib/karafka/web/ui/views/shared/alerts/_secondary.erb +4 -0
  278. data/lib/karafka/web/ui/views/shared/alerts/_success.erb +4 -0
  279. data/lib/karafka/web/ui/views/shared/alerts/_warning.erb +4 -0
  280. data/lib/karafka/web/ui/views/shared/charts/_line.erb +1 -1
  281. data/lib/karafka/web/ui/views/shared/exceptions/not_allowed.erb +14 -19
  282. data/lib/karafka/web/ui/views/shared/exceptions/not_found.erb +16 -21
  283. data/lib/karafka/web/ui/views/shared/exceptions/pro_only.erb +16 -28
  284. data/lib/karafka/web/ui/views/shared/icons/_arrow_down_on_square.erb +3 -0
  285. data/lib/karafka/web/ui/views/shared/icons/_arrow_down_tray.erb +3 -0
  286. data/lib/karafka/web/ui/views/shared/icons/_arrow_on_squares.erb +3 -0
  287. data/lib/karafka/web/ui/views/shared/icons/_arrow_path_rounded.erb +3 -0
  288. data/lib/karafka/web/ui/views/shared/icons/_arrow_uturn_right.erb +3 -0
  289. data/lib/karafka/web/ui/views/shared/icons/_arrows_right_left.erb +3 -0
  290. data/lib/karafka/web/ui/views/shared/icons/_blocks.erb +3 -0
  291. data/lib/karafka/web/ui/views/shared/icons/_book_open.erb +3 -0
  292. data/lib/karafka/web/ui/views/shared/icons/_bug.erb +3 -0
  293. data/lib/karafka/web/ui/views/shared/icons/_burger.erb +14 -0
  294. data/lib/karafka/web/ui/views/shared/icons/_calendar_days.erb +3 -0
  295. data/lib/karafka/web/ui/views/shared/icons/_chart_bar.erb +3 -0
  296. data/lib/karafka/web/ui/views/shared/icons/_check_badge.erb +3 -0
  297. data/lib/karafka/web/ui/views/shared/icons/_check_circle.erb +3 -0
  298. data/lib/karafka/web/ui/views/shared/icons/_circle_stack.erb +3 -0
  299. data/lib/karafka/web/ui/views/shared/icons/_cpu.erb +3 -0
  300. data/lib/karafka/web/ui/views/shared/icons/_document_glass.erb +3 -0
  301. data/lib/karafka/web/ui/views/shared/icons/_exclamation_triangle.erb +3 -0
  302. data/lib/karafka/web/ui/views/shared/icons/_eye.erb +4 -0
  303. data/lib/karafka/web/ui/views/shared/icons/_gear.erb +4 -0
  304. data/lib/karafka/web/ui/views/shared/icons/_github.erb +13 -0
  305. data/lib/karafka/web/ui/views/shared/icons/_globe.erb +3 -0
  306. data/lib/karafka/web/ui/views/shared/icons/_heart.erb +3 -0
  307. data/lib/karafka/web/ui/views/shared/icons/_home.erb +3 -0
  308. data/lib/karafka/web/ui/views/shared/icons/_info_circle.erb +3 -0
  309. data/lib/karafka/web/ui/views/shared/icons/_lifebuoy.erb +3 -0
  310. data/lib/karafka/web/ui/views/shared/icons/_light_bulb.erb +3 -0
  311. data/lib/karafka/web/ui/views/shared/icons/_list_bullets.erb +3 -0
  312. data/lib/karafka/web/ui/views/shared/icons/_magnifying_glass.erb +3 -0
  313. data/lib/karafka/web/ui/views/shared/icons/_moon.erb +3 -0
  314. data/lib/karafka/web/ui/views/shared/icons/_offices.erb +3 -0
  315. data/lib/karafka/web/ui/views/shared/icons/_pause.erb +3 -0
  316. data/lib/karafka/web/ui/views/shared/icons/_pause_circle.erb +3 -0
  317. data/lib/karafka/web/ui/views/shared/icons/_play_circle.erb +4 -0
  318. data/lib/karafka/web/ui/views/shared/icons/_question_circle.erb +3 -0
  319. data/lib/karafka/web/ui/views/shared/icons/_queue_list.erb +3 -0
  320. data/lib/karafka/web/ui/views/shared/icons/_refresh.erb +3 -0
  321. data/lib/karafka/web/ui/views/shared/icons/_slack.erb +16 -0
  322. data/lib/karafka/web/ui/views/shared/icons/_stop.erb +3 -0
  323. data/lib/karafka/web/ui/views/shared/icons/_sun.erb +3 -0
  324. data/lib/karafka/web/ui/views/shared/icons/_x_circle.erb +3 -0
  325. data/lib/karafka/web/ui/views/shared/icons/_x_mark.erb +3 -0
  326. data/lib/karafka/web/ui/views/status/_breadcrumbs.erb +1 -1
  327. data/lib/karafka/web/ui/views/status/_failure.erb +2 -13
  328. data/lib/karafka/web/ui/views/status/_halted.erb +2 -10
  329. data/lib/karafka/web/ui/views/status/_info.erb +2 -13
  330. data/lib/karafka/web/ui/views/status/_success.erb +2 -10
  331. data/lib/karafka/web/ui/views/status/_warning.erb +2 -13
  332. data/lib/karafka/web/ui/views/status/failures/_connection.erb +2 -2
  333. data/lib/karafka/web/ui/views/status/failures/_consumers_reports.erb +3 -3
  334. data/lib/karafka/web/ui/views/status/failures/_consumers_reports_schema_state.erb +4 -4
  335. data/lib/karafka/web/ui/views/status/failures/_enabled.erb +2 -2
  336. data/lib/karafka/web/ui/views/status/failures/_initial_consumers_metrics.erb +6 -6
  337. data/lib/karafka/web/ui/views/status/failures/_initial_consumers_state.erb +6 -6
  338. data/lib/karafka/web/ui/views/status/failures/_live_reporting.erb +2 -2
  339. data/lib/karafka/web/ui/views/status/failures/_materializing_lag.erb +11 -0
  340. data/lib/karafka/web/ui/views/status/failures/_partitions.erb +3 -3
  341. data/lib/karafka/web/ui/views/status/failures/_state_calculation.erb +2 -2
  342. data/lib/karafka/web/ui/views/status/failures/_topics.erb +3 -3
  343. data/lib/karafka/web/ui/views/status/info/_components.erb +14 -41
  344. data/lib/karafka/web/ui/views/status/show.erb +165 -154
  345. data/lib/karafka/web/ui/views/status/warnings/_connection.erb +3 -3
  346. data/lib/karafka/web/ui/views/status/warnings/_pro_subscription.erb +2 -2
  347. data/lib/karafka/web/ui/views/status/warnings/_replication.erb +2 -2
  348. data/lib/karafka/web/ui/views/status/warnings/_routing_topics_presence.erb +1 -1
  349. data/lib/karafka/web/ui/views/support/_breadcrumbs.erb +5 -0
  350. data/lib/karafka/web/ui/views/support/show.erb +71 -0
  351. data/lib/karafka/web/ui/views/ux/_alerts.erb +25 -0
  352. data/lib/karafka/web/ui/views/ux/_badges.erb +21 -0
  353. data/lib/karafka/web/ui/views/ux/_breadcrumbs.erb +5 -0
  354. data/lib/karafka/web/ui/views/ux/_buttons.erb +47 -0
  355. data/lib/karafka/web/ui/views/ux/_card_detail.erb +15 -0
  356. data/lib/karafka/web/ui/views/ux/_card_metric.erb +123 -0
  357. data/lib/karafka/web/ui/views/ux/_card_summary.erb +72 -0
  358. data/lib/karafka/web/ui/views/ux/_card_support.erb +39 -0
  359. data/lib/karafka/web/ui/views/ux/_code.erb +9 -0
  360. data/lib/karafka/web/ui/views/ux/_data_table.erb +52 -0
  361. data/lib/karafka/web/ui/views/ux/_headers.erb +2 -0
  362. data/lib/karafka/web/ui/views/ux/_icons.erb +9 -0
  363. data/lib/karafka/web/ui/views/ux/_pagination.erb +32 -0
  364. data/lib/karafka/web/ui/views/ux/_row_table.erb +52 -0
  365. data/lib/karafka/web/ui/views/ux/_status_rows.erb +53 -0
  366. data/lib/karafka/web/ui/views/ux/_tabs.erb +14 -0
  367. data/lib/karafka/web/ui/views/ux/_text.erb +2 -0
  368. data/lib/karafka/web/ui/views/ux/_topic_tiles.erb +42 -0
  369. data/lib/karafka/web/ui/views/ux/show.erb +19 -0
  370. data/lib/karafka/web/version.rb +1 -1
  371. data/lib/karafka/web.rb +2 -0
  372. data/package-lock.json +4158 -0
  373. data/package.json +15 -0
  374. data/postcss.config.js +6 -0
  375. data/tailwind.config.js +16 -0
  376. data.tar.gz.sig +4 -0
  377. metadata +203 -51
  378. metadata.gz.sig +0 -0
  379. data/lib/karafka/web/management/migrations/0_set_initial_consumers_metrics.rb +0 -36
  380. data/lib/karafka/web/management/migrations/0_set_initial_consumers_state.rb +0 -43
  381. data/lib/karafka/web/management/migrations/1699543515_fill_missing_received_and_sent_bytes_in_consumers_metrics.rb +0 -26
  382. data/lib/karafka/web/management/migrations/1699543515_fill_missing_received_and_sent_bytes_in_consumers_state.rb +0 -23
  383. data/lib/karafka/web/management/migrations/1700234522_introduce_waiting_in_consumers_metrics.rb +0 -24
  384. data/lib/karafka/web/management/migrations/1700234522_introduce_waiting_in_consumers_state.rb +0 -20
  385. data/lib/karafka/web/management/migrations/1700234522_remove_processing_from_consumers_metrics.rb +0 -24
  386. data/lib/karafka/web/management/migrations/1700234522_remove_processing_from_consumers_state.rb +0 -20
  387. data/lib/karafka/web/management/migrations/1704722380_split_listeners_into_active_and_paused_in_metrics.rb +0 -36
  388. data/lib/karafka/web/management/migrations/1704722380_split_listeners_into_active_and_paused_in_states.rb +0 -32
  389. data/lib/karafka/web/management/migrations/1706607960_introduce_lag_total_in_metrics.rb +0 -38
  390. data/lib/karafka/web/management/migrations/1706607960_introduce_lag_total_in_states.rb +0 -22
  391. data/lib/karafka/web/management/migrations/1706611396_rename_lag_total_to_lag_hybrid_in_metrics.rb +0 -36
  392. data/lib/karafka/web/management/migrations/1706611396_rename_lag_total_to_lag_hybrid_in_states.rb +0 -21
  393. data/lib/karafka/web/pro/ui/views/cluster/brokers.erb +0 -27
  394. data/lib/karafka/web/pro/ui/views/commands/_details.erb +0 -26
  395. data/lib/karafka/web/pro/ui/views/consumers/_counters.erb +0 -72
  396. data/lib/karafka/web/pro/ui/views/consumers/consumer/_title.erb +0 -5
  397. data/lib/karafka/web/pro/ui/views/errors/_title_with_select.erb +0 -31
  398. data/lib/karafka/web/pro/ui/views/explorer/message/_message_actions.erb +0 -18
  399. data/lib/karafka/web/pro/ui/views/explorer/message/_payload_actions.erb +0 -19
  400. data/lib/karafka/web/pro/ui/views/explorer/partition/_details.erb +0 -35
  401. data/lib/karafka/web/pro/ui/views/explorer/topic/_details.erb +0 -23
  402. data/lib/karafka/web/pro/ui/views/health/_consumer_group_header.erb +0 -14
  403. data/lib/karafka/web/ui/controllers/responses/deny.rb +0 -15
  404. data/lib/karafka/web/ui/helpers/alerts_helper.rb +0 -23
  405. data/lib/karafka/web/ui/lib/safe_runner.rb +0 -59
  406. data/lib/karafka/web/ui/models/visibility_filter.rb +0 -49
  407. data/lib/karafka/web/ui/public/javascripts/libs/bootstrap.min.js +0 -6
  408. data/lib/karafka/web/ui/public/javascripts/tabs_manager.js +0 -57
  409. data/lib/karafka/web/ui/public/stylesheets/libs/bootstrap.min.css +0 -6
  410. data/lib/karafka/web/ui/views/consumers/_counters.erb +0 -62
  411. data/lib/karafka/web/ui/views/errors/_watermark_offsets.erb +0 -10
  412. data/lib/karafka/web/ui/views/shared/_feature_pro.erb +0 -4
  413. data/lib/karafka/web/ui/views/shared/_footer.erb +0 -22
  414. data/lib/karafka/web/ui/views/shared/_live_poll.erb +0 -7
  415. /data/lib/karafka/web/management/migrations/{0_base.rb → base.rb} +0 -0
  416. /data/lib/karafka/web/ui/public/javascripts/{charts.js → components/charts.js} +0 -0
  417. /data/lib/karafka/web/ui/public/stylesheets/libs/{highlight.min.css → highlight_light.min.css} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54d4c84ba9869d6e2ffe28327741b1190944e9d4f5f2761f4a7ee1f185cb79aa
4
- data.tar.gz: b5d3260c8caddbf509331dfbbe38781f169b294f4fb44aa1d4dafcb3af781987
3
+ metadata.gz: d03bd99016dad674c04a734df15c1dd42c52d869ea7c5e1c5158f1b2ad5d31f9
4
+ data.tar.gz: 830c8e38a82bee5876519a5517d321ac1c6f9bb0f197bab0644bb65ae8ba7cba
5
5
  SHA512:
6
- metadata.gz: 5f2ae9888e234698cd8d0763f161ad4320567b95d3dc13ddc6f50379b3b0f7defe01401438730afe523def3fa4f72c520d80b68e259fc4710c85938961f37ae4
7
- data.tar.gz: b9322b453246e5faf628f2efe6fccae1da02d39c74f6570147032c34bb214d2b8477b652d6e95bb0b18cfc9d51d4cae3eb1229176f33a87e7c7c6ee685e95856
6
+ metadata.gz: cce9fba1e6f3f3503a8893d74711c9de78e7ff54b3f7c07a6e8add2aa7d8adf3b61411a051f08c0c5b31550cb1533b2a80c6b903e4ba0e42a022895160146616
7
+ data.tar.gz: 2e823dd6b69bc5be01f9c9b330b4691af8e278d1a306fde6c9d762eb6d282a0b2defefeb192aa705b17dddc5ba8cda11ea3bbb5128ea9ecacf9d2e9ad89620bc
checksums.yaml.gz.sig ADDED
Binary file
@@ -22,6 +22,7 @@ jobs:
22
22
  fail-fast: false
23
23
  matrix:
24
24
  ruby:
25
+ - '3.4.0-preview1'
25
26
  - '3.3'
26
27
  - '3.2'
27
28
  - '3.1'
@@ -101,3 +102,32 @@ jobs:
101
102
  CODITSU_API_KEY: ${{ secrets.CODITSU_API_KEY }}
102
103
  CODITSU_API_SECRET: ${{ secrets.CODITSU_API_SECRET }}
103
104
  run: \curl -sSL https://api.coditsu.io/run/ci | bash
105
+
106
+
107
+ assets:
108
+ runs-on: ubuntu-latest
109
+ steps:
110
+ - name: Checkout code
111
+ uses: actions/checkout@v4
112
+
113
+ - name: Set up Node.js
114
+ uses: actions/setup-node@v4
115
+ with:
116
+ node-version: '17'
117
+
118
+ - name: Cache node modules
119
+ uses: actions/cache@v4
120
+ with:
121
+ path: ~/.npm
122
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
123
+ restore-keys: |
124
+ ${{ runner.os }}-node-
125
+
126
+ - name: Install dependencies
127
+ run: npm install
128
+
129
+ - name: Build development assets
130
+ run: ./bin/build_assets
131
+
132
+ - name: Build release assets
133
+ run: KARAFKA_RELEASE=true ./bin/build_assets
data/.gitignore CHANGED
@@ -38,8 +38,10 @@ db/*.sqlite3
38
38
  /capybara-*.html
39
39
  /gems
40
40
  /specifications
41
+ /node_modules
41
42
  rerun.txt
42
43
  pickle-email-*.html
44
+ tailwind.min.css
43
45
 
44
46
  # If you find yourself ignoring temporary files generated by your text editor
45
47
  # or operating system, you probably want to add a global ignore instead:
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.3.1
1
+ 3.3.4
data/CHANGELOG.md CHANGED
@@ -1,7 +1,88 @@
1
- # Karafka Web changelog
1
+ # Karafka Web Changelog
2
+
3
+ ## 0.10.0 (Unreleased)
4
+ - **[Breaking]** Rename and reorganize visibility filter to policies engine since it is not only about visibility.
5
+ - **[Feature]** Replace Bootstrap with with tailwind + DaisyUI.
6
+ - **[Feature]** Redesign the UI and move navigation to the left to make space for future features.
7
+ - **[Feature]** Support per request policies for inspection and operations limitation.
8
+ - **[Feature]** Provide Search capabilities in the Explorer (Pro).
9
+ - **[Feature]** Provide dark mode.
10
+ - [Enhancement] Provide topics watermarks inspection page (Pro).
11
+ - [Enhancement] Use Turbo to improve usability.
12
+ - [Enhancement] Round poll age reporting to precision of 2 reducing the payload size.
13
+ - [Enhancement] Round utilization reporting to precision of 2 reducing the payload size.
14
+ - [Enhancement] Validate states materialization lag in the status view.
15
+ - [Enhancement] Promote topics data pace to OSS.
16
+ - [Enhancement] Rename and normalize dashboard tabs.
17
+ - [Enhancement] Enable live data polling on the first visit so it does not have to be enabled manually.
18
+ - [Enhancement] Allow disabling ability to republish messages via policies.
19
+ - [Enhancement] Display raw numerical timestamp alongside message time.
20
+ - [Enhancement] Support `/topics` root redirect.
21
+ - [Enhancement] Prevent explorer from displaying too big payloads (bigger than 1MB by default)
22
+ - [Enhancement] Include deserialization object allocation stats.
23
+ - [Enhancement] Improve how charts with many topics work.
24
+ - [Enhancement] Count and display executed jobs independently from processed batches.
25
+ - [Enhancement] Prevent karafka-web from being configured before karafka is configured.
26
+ - [Enhancement] Use `ostruct` from RubyGems in testing.
27
+ - [Enhancement] Indicate in the status reporting whether Karafka is OSS or Pro.
28
+ - [Enhancement] Ship JS and CSS assets using Brotli and Gzip when possible.
29
+ - [Enhancement] Introduce a `/ux` page to ease with styling improvements and components management.
30
+ - [Enhancement] disallow usage of `<script>` blocks to prevent XSS.
31
+ - [Enhancement] Display full subscription group information in the Routing view, including injectable defaults.
32
+ - [Enhancement] Report Karafka consumer server execution mode.
33
+ - [Enhancement] Expose `sync_threshold` consumer tracking config to allow aligning of error-intense applications.
34
+ - [Refactor] Optimize subscription group data tracking flow.
35
+ - [Refactor] Namespace migrations so migrations related to each topic data are in an independent directory.
36
+ - [Refactor] Use errors for deny flow so request denials can occur from the inspection layer.
37
+ - [Maintenance] Require `karafka` `2.4.7` due to fixes and API changes.
38
+ - [Fix] Disallow quiet and stop commands for swarm workers.
39
+ - [Fix] Disallow quiet and stop commands for embedded workers.
40
+ - [Fix] Fix invalid deserialization metadata display in the per-message Explorer view.
41
+ - [Fix] Fix a case where started page refresh would update content despite limiters being in place.
42
+ - [Fix] Ruby 3.4.0 preview1 - No such file or directory.
43
+ - [Fix] Fix the live poll button state flickering when disabled.
44
+ - [Fix] Pace computation does not compensate for partial data reported.
45
+ - [Fix] DLQ parent topics get classified as DLQ in the Web.
46
+ - [Fix] Add missing space in the attempt label.
47
+ - [Fix] Fix lack of highlight of "Consumers" navigation when in the "Commands" tab.
48
+ - [Fix] Fix not working page reporting in breadcrumbs.
49
+ - [Fix] Fix invalid redirect when trying to view particular errors partition time location.
50
+ - [Fix] Fix several UI inconsistencies.
51
+ - [Fix] License identifier `LGPL-3.0` is deprecated for SPDX (#2177).
52
+ - [Fix] Do not include prettifying the payload for visibility in the resource computation cost.
2
53
 
3
- ## 0.9.2 (2025-09-19)
4
- - [Fix] Fix BaseController caller action name extraction.
54
+ ### Upgrade Notes
55
+
56
+ This is a **major** release that brings many things to the table.
57
+
58
+ This version of the Karafka Web UI requires Karafka `>= 2.4.7`. You can either upgrade both or upgrade Karafka first and then the Web UI. Karafka `2.4.7` is also compatible with Web UI `0.9.1`; thus, you can upgrade one at a time.
59
+
60
+ #### Configuration
61
+
62
+ Visibility Filters have been reorganized into messages policies.
63
+
64
+ Please read the [Policies API](https://karafka.io/docs/Pro-Web-UI-Policies/) documentation and convert your visibility filters to policies.
65
+
66
+ Your existing message-related visibility filter policies should now be assigned to a new configuration:
67
+
68
+ ```ruby
69
+ Karafka::Web.setup do |config|
70
+ config.ui.policies.messages = MyCustomRequestsPolicy.new
71
+ end
72
+ ```
73
+
74
+ #### Deployment
75
+
76
+ Because of the reporting schema update, it is recommended to:
77
+
78
+ 0. Make sure you have upgraded to `0.9.1` before and that it was fully deployed.
79
+ 1. Test the upgrade on a staging or dev environment.
80
+ 3. The Web UI interface may throw 500 errors during the upgrade because of schema incompatibility (until Puma is deployed and all consumers redeployed). This will have no long-term effects and can be ignored.
81
+ 4. `Karafka::Web::Errors::Processing::IncompatibleSchemaError` **is expected**. It is part of the Karafka Web UI zero-downtime deployment strategy. This error allows the Web UI materialization consumer to back off and wait for it to be replaced with a new one.
82
+ 5. Perform a rolling deployment (or a regular one) and replace all consumer processes.
83
+ 6. Update the Web UI Puma.
84
+ 7. **No** CLI command execution is required.
85
+ 8. Enjoy.
5
86
 
6
87
  ## 0.9.1 (2024-05-03)
7
88
  - [Fix] OSS `lag_stored` for not-subscribed consumers causes Web UI to crash.
data/Gemfile CHANGED
@@ -9,6 +9,7 @@ gemspec
9
9
  group :test do
10
10
  gem 'byebug'
11
11
  gem 'factory_bot'
12
+ gem 'ostruct'
12
13
  gem 'rack-test'
13
14
  gem 'rspec'
14
15
  gem 'simplecov'
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- karafka-web (0.9.2)
4
+ karafka-web (0.10.0.beta1)
5
5
  erubi (~> 1.4)
6
- karafka (>= 2.4.0, < 2.5.0)
6
+ karafka (>= 2.4.7, < 2.5.0)
7
7
  karafka-core (>= 2.4.0, < 2.5.0)
8
8
  roda (~> 3.68, >= 3.69)
9
9
  tilt (~> 2.0)
@@ -11,7 +11,7 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activesupport (7.1.3.2)
14
+ activesupport (7.1.3.4)
15
15
  base64
16
16
  bigdecimal
17
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -22,40 +22,43 @@ GEM
22
22
  mutex_m
23
23
  tzinfo (~> 2.0)
24
24
  base64 (0.2.0)
25
- bigdecimal (3.1.7)
25
+ bigdecimal (3.1.8)
26
26
  byebug (11.1.3)
27
- concurrent-ruby (1.2.3)
27
+ concurrent-ruby (1.3.3)
28
28
  connection_pool (2.4.1)
29
29
  diff-lcs (1.5.1)
30
30
  docile (1.4.0)
31
31
  drb (2.2.1)
32
- erubi (1.12.0)
32
+ erubi (1.13.0)
33
33
  factory_bot (6.4.6)
34
34
  activesupport (>= 5.0.0)
35
- ffi (1.16.3)
36
- i18n (1.14.4)
35
+ ffi (1.17.0)
36
+ ffi (1.17.0-x86_64-linux-gnu)
37
+ i18n (1.14.5)
37
38
  concurrent-ruby (~> 1.0)
38
- karafka (2.4.0)
39
- karafka-core (>= 2.4.0, < 2.5.0)
40
- waterdrop (>= 2.7.0, < 3.0.0)
39
+ karafka (2.4.7)
40
+ base64 (~> 0.2)
41
+ karafka-core (>= 2.4.3, < 2.5.0)
42
+ waterdrop (>= 2.7.3, < 3.0.0)
41
43
  zeitwerk (~> 2.3)
42
- karafka-core (2.4.0)
43
- karafka-rdkafka (>= 0.15.0, < 0.16.0)
44
- karafka-rdkafka (0.15.0)
44
+ karafka-core (2.4.4)
45
+ karafka-rdkafka (>= 0.15.0, < 0.18.0)
46
+ karafka-rdkafka (0.17.1)
45
47
  ffi (~> 1.15)
46
48
  mini_portile2 (~> 2.6)
47
49
  rake (> 12)
48
- mini_portile2 (2.8.6)
49
- minitest (5.22.3)
50
+ mini_portile2 (2.8.7)
51
+ minitest (5.24.0)
50
52
  mutex_m (0.2.0)
51
- rack (3.0.10)
53
+ ostruct (0.6.0)
54
+ rack (3.1.4)
52
55
  rack-test (2.1.0)
53
56
  rack (>= 1.3)
54
57
  rackup (0.2.3)
55
58
  rack (>= 3.0.0.beta1)
56
59
  webrick
57
60
  rake (13.2.1)
58
- roda (3.79.0)
61
+ roda (3.81.0)
59
62
  rack
60
63
  rspec (3.13.0)
61
64
  rspec-core (~> 3.13.0)
@@ -63,10 +66,10 @@ GEM
63
66
  rspec-mocks (~> 3.13.0)
64
67
  rspec-core (3.13.0)
65
68
  rspec-support (~> 3.13.0)
66
- rspec-expectations (3.13.0)
69
+ rspec-expectations (3.13.1)
67
70
  diff-lcs (>= 1.2.0, < 2.0)
68
71
  rspec-support (~> 3.13.0)
69
- rspec-mocks (3.13.0)
72
+ rspec-mocks (3.13.1)
70
73
  diff-lcs (>= 1.2.0, < 2.0)
71
74
  rspec-support (~> 3.13.0)
72
75
  rspec-support (3.13.1)
@@ -76,14 +79,15 @@ GEM
76
79
  simplecov_json_formatter (~> 0.1)
77
80
  simplecov-html (0.12.3)
78
81
  simplecov_json_formatter (0.1.4)
79
- tilt (2.3.0)
82
+ tilt (2.4.0)
80
83
  tzinfo (2.0.6)
81
84
  concurrent-ruby (~> 1.0)
82
- waterdrop (2.7.0)
83
- karafka-core (>= 2.4.0, < 3.0.0)
85
+ waterdrop (2.7.4)
86
+ karafka-core (>= 2.4.3, < 3.0.0)
87
+ karafka-rdkafka (>= 0.15.1)
84
88
  zeitwerk (~> 2.3)
85
89
  webrick (1.8.1)
86
- zeitwerk (2.6.13)
90
+ zeitwerk (2.6.17)
87
91
 
88
92
  PLATFORMS
89
93
  ruby
@@ -93,10 +97,11 @@ DEPENDENCIES
93
97
  byebug
94
98
  factory_bot
95
99
  karafka-web!
100
+ ostruct
96
101
  rack-test
97
102
  rackup (~> 0.2)
98
103
  rspec
99
104
  simplecov
100
105
 
101
106
  BUNDLED WITH
102
- 2.5.9
107
+ 2.5.14
data/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
1
  Copyright (c) Maciej Mensfeld
2
2
 
3
3
  Karafka Web is part of Karafka and it is an Open Source project licensed under the terms of
4
- the LGPLv3 license. Please see <https://github.com/karafka/karafka/blob/master/LGPL>
4
+ the LGPLv3 license. Please see <https://github.com/karafka/karafka/blob/master/LICENSE-LGPL>
5
5
  for license text.
6
6
 
7
7
  Karafka and Karafka Web have also commercial-friendly license, commercial support and commercial components.
data/bin/build_assets ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env bash
2
+
3
+ rm -f lib/karafka/web/ui/public/javascripts/application.min.*
4
+ rm -f lib/karafka/web/ui/public/stylesheets/application.min.*
5
+ rm -f lib/karafka/web/ui/public/stylesheets/libs/highlight_light.min.css.*
6
+ rm -f lib/karafka/web/ui/public/stylesheets/libs/highlight_dark.min.css.*
7
+
8
+ set -e
9
+
10
+ npx postcss \
11
+ lib/karafka/web/ui/public/stylesheets/libs/tailwind.css \
12
+ -o lib/karafka/web/ui/public/stylesheets/libs/tailwind.min.css
13
+
14
+ npx gulp
15
+
16
+ # We remove the intermediate tailwind file because its already bundled with gulp
17
+ rm lib/karafka/web/ui/public/stylesheets/libs/tailwind.min.css
18
+
19
+ compress_file() {
20
+ local input_file="$1"
21
+ local output_dir
22
+ output_dir=$(dirname "$input_file")
23
+ local base_name
24
+ base_name=$(basename "$input_file")
25
+
26
+ # Check if input file exists
27
+ if [ ! -f "$input_file" ]; then
28
+ echo "Input file not found: $input_file"
29
+ return 1
30
+ fi
31
+
32
+ # Compress with Brotli
33
+ brotli -k -q 11 "$input_file" -o "$output_dir/$base_name.br"
34
+ if [ $? -ne 0 ]; then
35
+ echo "Brotli compression failed"
36
+ return 1
37
+ fi
38
+
39
+ # Compress with Gzip
40
+ gzip -k -9 "$input_file" -c > "$output_dir/$base_name.gz"
41
+ if [ $? -ne 0 ]; then
42
+ echo "Gzip compression failed"
43
+ return 1
44
+ fi
45
+ }
46
+
47
+ compress_file "lib/karafka/web/ui/public/stylesheets/application.min.css"
48
+ compress_file "lib/karafka/web/ui/public/javascripts/application.min.js"
49
+
50
+ compress_file "lib/karafka/web/ui/public/stylesheets/libs/highlight_light.min.css"
51
+ compress_file "lib/karafka/web/ui/public/stylesheets/libs/highlight_dark.min.css"
data/bin/release ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Compiles assets in the release mode and creates the web gem
4
+
5
+ KARAFKA_RELEASE=true ./bin/build_assets
6
+ gem build karafka-web.gemspec
@@ -9,3 +9,21 @@ en:
9
9
  commanding.pause_timeout_format: needs to be an integer bigger than 0
10
10
  key_must_be_a_symbol: All keys under the kafka settings scope need to be symbols
11
11
  commanding.kafka_format: needs to be a filled hash
12
+ ui.search.matchers_must_have_name_and_call: 'must respond to #name and its instance to #call'
13
+ ui.search.matchers_format: must be an array with matchers
14
+ ui.search.matchers_name_must_be_valid: all matchers names must be non-empty strings
15
+ ui.search.limits_format: all limits need to be integers bigger than 0
16
+ ui.search.timeout_format: must be at least 1 ms
17
+ ui.policies.messages_format: cannot be nil
18
+ ui.policies.requests_format: cannot be nil
19
+
20
+ search_form:
21
+ missing: needs to be present
22
+ timestamp_key_must_be_large_enough: 'must be a Kafka message timestamp with ms precision'
23
+ matcher_format: must match the existing matchers names
24
+ limit_format: must be one of the predefined limits
25
+ phrase_format: must be a non-empty string
26
+ offset_type_format: must be latest, offset or a timestamp
27
+ offset_format: needs to be an integer bigger than 0
28
+ partitions_format: needs to include "all" or partitions ids
29
+ timestamp_format: must be a Kafka message timestamp with ms precision
data/docker-compose.yml CHANGED
@@ -3,7 +3,7 @@ version: '2'
3
3
  services:
4
4
  kafka:
5
5
  container_name: kafka
6
- image: confluentinc/cp-kafka:7.6.1
6
+ image: confluentinc/cp-kafka:7.7.0
7
7
 
8
8
  ports:
9
9
  - 9092:9092
data/gulpfile.js ADDED
@@ -0,0 +1,73 @@
1
+ const gulp = require('gulp');
2
+ const concat = require('gulp-concat');
3
+ const uglify = require('gulp-uglify');
4
+ const through2 = require('through2');
5
+ const path = require('path');
6
+ const cleanCSS = require('gulp-clean-css');
7
+ const sourcemaps = require('gulp-sourcemaps');
8
+
9
+ // Check if we are in development mode
10
+ const isDev = process.env.KARAFKA_RELEASE !== 'true';
11
+
12
+ // Define JavaScript source files
13
+ const jsFiles = [
14
+ 'lib/karafka/web/ui/public/javascripts/libs/**/*.js',
15
+ 'lib/karafka/web/ui/public/javascripts/charts/**/*.js',
16
+ 'lib/karafka/web/ui/public/javascripts/components/**/*.js',
17
+ 'lib/karafka/web/ui/public/javascripts/application.js'
18
+ ];
19
+
20
+ // Define CSS source files
21
+ const cssFiles = [
22
+ 'lib/karafka/web/ui/public/stylesheets/libs/datepicker.min.css',
23
+ 'lib/karafka/web/ui/public/stylesheets/libs/tailwind.min.css',
24
+ 'lib/karafka/web/ui/public/stylesheets/application.css'
25
+ ];
26
+
27
+ // Custom transform stream to add file location comments for JavaScript
28
+ function addFileLocation() {
29
+ return through2.obj(function (file, enc, cb) {
30
+ if (file.isBuffer()) {
31
+ const fileLocationComment = `/*! Source: ${path.relative(__dirname, file.path)} */\n\n`;
32
+ const contents = Buffer.concat([Buffer.from(fileLocationComment), file.contents]);
33
+ file.contents = contents;
34
+ }
35
+ cb(null, file);
36
+ });
37
+ }
38
+
39
+ // JavaScript task
40
+ gulp.task('scripts', function() {
41
+ return gulp.src(jsFiles)
42
+ .pipe(isDev ? sourcemaps.init() : through2.obj()) // Initialize sourcemaps in dev
43
+ .pipe(addFileLocation()) // Add file location comments
44
+ .pipe(concat('application.min.js'))
45
+ .pipe(uglify({
46
+ output: {
47
+ comments: function(node, comment) {
48
+ const text = comment.value;
49
+ const type = comment.type;
50
+ if (type == "comment2") {
51
+ // Preserve comments starting with `/*!` or `/**`
52
+ return /@preserve|@license|@cc_on|^\!/.test(text);
53
+ }
54
+ return false;
55
+ }
56
+ }
57
+ }))
58
+ .pipe(isDev ? sourcemaps.write('.') : through2.obj()) // Write sourcemaps in dev
59
+ .pipe(gulp.dest('lib/karafka/web/ui/public/javascripts'));
60
+ });
61
+
62
+ // CSS task
63
+ gulp.task('styles', function() {
64
+ return gulp.src(cssFiles)
65
+ .pipe(isDev ? sourcemaps.init() : through2.obj()) // Initialize sourcemaps in dev
66
+ .pipe(concat('application.min.css'))
67
+ .pipe(cleanCSS({ level: 2 })) // Minify CSS
68
+ .pipe(isDev ? sourcemaps.write('.') : through2.obj()) // Write sourcemaps in dev
69
+ .pipe(gulp.dest('lib/karafka/web/ui/public/stylesheets'));
70
+ });
71
+
72
+ // Define default task to run both scripts and styles tasks
73
+ gulp.task('default', gulp.series('scripts', 'styles'));
data/karafka-web.gemspec CHANGED
@@ -14,10 +14,10 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = 'https://karafka.io'
15
15
  spec.summary = 'Karafka ecosystem Web UI interface'
16
16
  spec.description = 'Karafka ecosystem plug-and-play Web UI'
17
- spec.licenses = %w[LGPL-3.0 Commercial]
17
+ spec.licenses = %w[LGPL-3.0-only Commercial]
18
18
 
19
19
  spec.add_dependency 'erubi', '~> 1.4'
20
- spec.add_dependency 'karafka', '>= 2.4.0', '< 2.5.0'
20
+ spec.add_dependency 'karafka', '>= 2.4.7', '< 2.5.0'
21
21
  spec.add_dependency 'karafka-core', '>= 2.4.0', '< 2.5.0'
22
22
  spec.add_dependency 'roda', '~> 3.68', '>= 3.69'
23
23
  spec.add_dependency 'tilt', '~> 2.0'
@@ -26,6 +26,11 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.required_ruby_version = '>= 3.0.0'
28
28
 
29
+ if $PROGRAM_NAME.end_with?('gem')
30
+ spec.signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
31
+ end
32
+
33
+ spec.cert_chain = %w[certs/cert_chain.pem]
29
34
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
30
35
  spec.executables = %w[karafka-web]
31
36
  spec.require_paths = %w[lib]
@@ -76,6 +76,11 @@ module Karafka
76
76
  # Reports the metrics collected in the consumer sampler
77
77
  setting :reporter, default: Tracking::Consumers::Reporter.new
78
78
 
79
+ # Minimum number of messages to produce to produce them in sync mode
80
+ # This acts as a small back-off not to overload the system in case we would have
81
+ # extremely big number of errors and reports happening
82
+ setting :sync_threshold, default: 50
83
+
79
84
  # Samples for fetching and storing metrics samples about the consumer process
80
85
  setting :sampler, default: Tracking::Consumers::Sampler.new
81
86
 
@@ -139,11 +144,6 @@ module Karafka
139
144
  )
140
145
 
141
146
  setting :visibility do
142
- # Allows to manage visibility of payload, headers and message key in the UI
143
- # In some cases you may want to limit what is being displayed due to the type of data you
144
- # are dealing with
145
- setting :filter, default: Ui::Models::VisibilityFilter.new
146
-
147
147
  # Should we display internal topics of Kafka. The once starting with `__`
148
148
  # By default we do not display them as they are not usable from regular users perspective
149
149
  setting :internal_topics, default: false
@@ -162,17 +162,16 @@ module Karafka
162
162
  # transaction that will cause given consumer group to halt processing and wait
163
163
  setting :lso_threshold, default: 5 * 60 * 1_000
164
164
 
165
- # Allows to manage visibility of payload, headers and message key in the UI
166
- # In some cases you may want to limit what is being displayed due to the type of data you
167
- # are dealing with
168
- setting :visibility_filter, default: Ui::Models::VisibilityFilter.new
169
-
170
165
  # Consider any topic matching those names as a DLQ topic for the DLQ view
171
166
  # Web UI uses auto DLQ discovery based on routing but this may not be fully operable when
172
167
  # using a multi-app setup. This config allows to add extra topics if needed without having
173
168
  # to explicitly define routing
174
169
  setting :dlq_patterns, default: [/(dlq)|(dead_letter)/i]
175
170
 
171
+ # Maximum in-memory size of payload that we will render. Anything bigger than this by
172
+ # default will not be displayed not to hang the browser. 512KB of serialized data is a lot.
173
+ setting :max_visible_payload_size, default: 524_288
174
+
176
175
  # Specific kafka settings that are tuned to operate within the Web UI interface.
177
176
  #
178
177
  # Please do not change them unless you know what you are doing as their misconfiguration
@@ -10,6 +10,8 @@ module Karafka
10
10
  # This layer is not for users extensive feedback, thus we can easily use the minimum
11
11
  # error messaging there is.
12
12
  def configure
13
+ return super if block_given?
14
+
13
15
  super do |config|
14
16
  config.error_messages = YAML.safe_load(
15
17
  File.read(
@@ -34,6 +34,7 @@ module Karafka
34
34
  required(:reporter) { |val| !val.nil? }
35
35
  required(:sampler) { |val| !val.nil? }
36
36
  required(:listeners) { |val| val.is_a?(Array) }
37
+ required(:sync_threshold) { |val| val.is_a?(Integer) && val.positive? }
37
38
  end
38
39
 
39
40
  nested(:producers) do
@@ -57,6 +58,7 @@ module Karafka
57
58
 
58
59
  required(:cache) { |val| !val.nil? }
59
60
  required(:per_page) { |val| val.is_a?(Integer) && val >= 1 && val <= 100 }
61
+ required(:max_visible_payload_size) { |val| val.is_a?(Integer) && val >= 1 }
60
62
 
61
63
  required(:dlq_patterns) do |val|
62
64
  val.is_a?(Array) &&
@@ -64,7 +66,6 @@ module Karafka
64
66
  end
65
67
 
66
68
  nested(:visibility) do
67
- required(:filter) { |val| !val.nil? }
68
69
  required(:internal_topics) { |val| [true, false].include?(val) }
69
70
  required(:active_topics_cluster_lags_only) { |val| [true, false].include?(val) }
70
71
  end
@@ -11,6 +11,15 @@ module Karafka
11
11
  # This should never happen and if you see this, please open an issue.
12
12
  ContractError = Class.new(BaseError)
13
13
 
14
+ # Raised when you try to configure Web UI but Karafka was not yet configured and is not in
15
+ # a state to accept Web UI integration.
16
+ #
17
+ # If you are seeing this error, it means you tried to configure and setup the Web UI before
18
+ # you configured Karafka. In case of a "split-setup" where you divided your `karafka.rb`
19
+ # into separate files, likely you are requiring the web-ui component prior to the one that
20
+ # configures Karafka
21
+ KarafkaNotInitializedError = Class.new(BaseError)
22
+
14
23
  # Errors specific to management
15
24
  module Management
16
25
  # Similar to processing error with the same name, it is raised when a critical
@@ -62,6 +71,9 @@ module Karafka
62
71
 
63
72
  # Raised whe a given feature is available for Pro but not pro used
64
73
  ProOnlyError = Class.new(BaseError)
74
+
75
+ # Raised when we want to stop the flow and render 403
76
+ ForbiddenError = Class.new(BaseError)
65
77
  end
66
78
  end
67
79
  end
@@ -6,7 +6,7 @@ module Karafka
6
6
  # to how Rails does that.
7
7
  class Inflector < Zeitwerk::GemInflector
8
8
  # Checks if given path is a migration one
9
- MIGRATION_ABSPATH_REGEXP = /migrations\/[0-9]+_(.*)/
9
+ MIGRATION_ABSPATH_REGEXP = /migrations\/[a-z_]+\/[0-9]+_(.*)/
10
10
 
11
11
  # Checks if it is a migration file
12
12
  MIGRATION_BASENAME_REGEXP = /\A[0-9]+_(.*)/
@@ -10,6 +10,8 @@ module Karafka
10
10
  class Enable < Base
11
11
  # Enables routing consumer group and subscribes Web-UI listeners
12
12
  def call
13
+ ensure_karafka_initialized!
14
+
13
15
  # Prevent double enabling
14
16
  return if ::Karafka::Web.config.enabled
15
17
 
@@ -27,6 +29,15 @@ module Karafka
27
29
 
28
30
  private
29
31
 
32
+ # We should not allow for enabling of Karafka Web when Karafka is not configured.
33
+ # Karafka needs to be loaded and configured before Web can be configured because Web is
34
+ # using Karafka configuration
35
+ def ensure_karafka_initialized!
36
+ return unless Karafka::App.config.internal.status.initializing?
37
+
38
+ raise Web::Errors::KarafkaNotInitializedError, 'Please initialize Karafka first'
39
+ end
40
+
30
41
  # Enables tracking if it was not explicitly disabled by the user
31
42
  def setup_tracking_activity
32
43
  return unless ::Karafka::Web.config.tracking.active.nil?