karafka-web 0.10.4 → 0.11.0.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +54 -176
- data/Gemfile +4 -0
- data/Gemfile.lock +87 -43
- data/LICENSE +6 -2
- data/bin/verify_kafka_warnings +35 -0
- data/bin/verify_topics_naming +35 -0
- data/config/locales/pro_errors.yml +1 -0
- data/docker-compose.yml +1 -1
- data/gulpfile.js +0 -2
- data/karafka-web.gemspec +2 -2
- data/lib/karafka/web/config.rb +80 -9
- data/lib/karafka/web/contracts/config.rb +44 -5
- data/lib/karafka/web/errors.rb +10 -12
- data/lib/karafka/web/management/actions/create_initial_states.rb +6 -6
- data/lib/karafka/web/management/actions/create_topics.rb +30 -64
- data/lib/karafka/web/management/actions/delete_topics.rb +5 -5
- data/lib/karafka/web/management/actions/enable.rb +5 -5
- data/lib/karafka/web/pro/commanding/commands/base.rb +37 -13
- data/lib/karafka/web/pro/commanding/commands/consumers/quiet.rb +33 -0
- data/lib/karafka/web/pro/commanding/commands/consumers/stop.rb +32 -0
- data/lib/karafka/web/pro/commanding/commands/consumers/trace.rb +37 -0
- data/lib/karafka/web/pro/commanding/commands/partitions/pause.rb +30 -0
- data/lib/karafka/web/pro/commanding/commands/partitions/resume.rb +30 -0
- data/lib/karafka/web/pro/commanding/commands/partitions/seek.rb +30 -0
- data/lib/karafka/web/pro/commanding/config.rb +6 -10
- data/lib/karafka/web/pro/commanding/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/commanding/dispatcher.rb +45 -24
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/base.rb +67 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/pause.rb +44 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/resume.rb +29 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/commands/seek.rb +86 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/executor.rb +56 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/listener.rb +55 -0
- data/lib/karafka/web/pro/commanding/handlers/partitions/tracker.rb +62 -0
- data/lib/karafka/web/pro/commanding/listener.rb +4 -12
- data/lib/karafka/web/pro/commanding/manager.rb +36 -24
- data/lib/karafka/web/pro/commanding/matcher.rb +7 -17
- data/lib/karafka/web/pro/commanding/request.rb +39 -0
- data/lib/karafka/web/pro/commanding.rb +2 -10
- data/lib/karafka/web/pro/loader.rb +13 -10
- data/lib/karafka/web/pro/ui/app.rb +31 -390
- data/lib/karafka/web/pro/ui/controllers/base_controller.rb +8 -10
- data/lib/karafka/web/pro/ui/controllers/cluster_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/consumers/base_controller.rb +21 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/commanding_controller.rb +148 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/commands_controller.rb +96 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/consumers_controller.rb +99 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/controls_controller.rb +36 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/jobs_controller.rb +57 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/partitions/base_controller.rb +86 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/partitions/offsets_controller.rb +75 -0
- data/lib/karafka/web/pro/ui/controllers/consumers/partitions/pauses_controller.rb +110 -0
- data/lib/karafka/web/pro/ui/controllers/dashboard_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/dlq_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/errors_controller.rb +3 -11
- data/lib/karafka/web/pro/ui/controllers/explorer/base_controller.rb +21 -0
- data/lib/karafka/web/pro/ui/controllers/explorer/explorer_controller.rb +215 -0
- data/lib/karafka/web/pro/ui/controllers/explorer/messages_controller.rb +145 -0
- data/lib/karafka/web/pro/ui/controllers/explorer/search_controller.rb +68 -0
- data/lib/karafka/web/pro/ui/controllers/health_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/jobs_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/recurring_tasks_controller.rb +12 -13
- data/lib/karafka/web/pro/ui/controllers/routing_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/base_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/explorer_controller.rb +8 -16
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/messages_controller.rb +9 -15
- data/lib/karafka/web/pro/ui/controllers/scheduled_messages/schedules_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/status_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/support_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/controllers/topics/base_controller.rb +21 -0
- data/lib/karafka/web/pro/ui/controllers/topics/configs_controller.rb +86 -0
- data/lib/karafka/web/pro/ui/controllers/topics/distributions_controller.rb +91 -0
- data/lib/karafka/web/pro/ui/controllers/topics/offsets_controller.rb +55 -0
- data/lib/karafka/web/pro/ui/controllers/topics/replications_controller.rb +37 -0
- data/lib/karafka/web/pro/ui/controllers/topics/topics_controller.rb +101 -0
- data/lib/karafka/web/pro/ui/controllers/ux_controller.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/branding/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/branding/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/branding.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/features.rb +53 -0
- data/lib/karafka/web/pro/ui/lib/patterns_detector.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/messages.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies/requests.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/policies.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/safe_runner.rb +5 -0
- data/lib/karafka/web/pro/ui/lib/search/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/contracts/config.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/contracts/form.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/matchers/base.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/matchers/raw_header_includes.rb +10 -11
- data/lib/karafka/web/pro/ui/lib/search/matchers/raw_key_includes.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/matchers/raw_payload_includes.rb +23 -11
- data/lib/karafka/web/pro/ui/lib/search/normalizer.rb +2 -10
- data/lib/karafka/web/pro/ui/lib/search/runner.rb +3 -11
- data/lib/karafka/web/pro/ui/lib/search.rb +2 -10
- data/lib/karafka/web/pro/ui/routes/base.rb +19 -0
- data/lib/karafka/web/pro/ui/routes/cluster.rb +37 -0
- data/lib/karafka/web/pro/ui/routes/consumers.rb +145 -0
- data/lib/karafka/web/pro/ui/routes/dashboard.rb +25 -0
- data/lib/karafka/web/pro/ui/routes/dlq.rb +24 -0
- data/lib/karafka/web/pro/ui/routes/errors.rb +39 -0
- data/lib/karafka/web/pro/ui/routes/explorer.rb +118 -0
- data/lib/karafka/web/pro/ui/routes/health.rb +47 -0
- data/lib/karafka/web/pro/ui/routes/jobs.rb +33 -0
- data/lib/karafka/web/pro/ui/routes/recurring_tasks.rb +59 -0
- data/lib/karafka/web/pro/ui/routes/routing.rb +31 -0
- data/lib/karafka/web/pro/ui/routes/scheduled_messages.rb +75 -0
- data/lib/karafka/web/pro/ui/routes/status.rb +24 -0
- data/lib/karafka/web/pro/ui/routes/support.rb +24 -0
- data/lib/karafka/web/pro/ui/routes/topics.rb +90 -0
- data/lib/karafka/web/pro/ui/routes/ux.rb +24 -0
- data/lib/karafka/web/pro/ui/views/cluster/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/_broker.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/_config.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/_tabs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/cluster/index.erb +4 -1
- data/lib/karafka/web/pro/ui/views/cluster/show.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_backtrace.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/commands/_breadcrumbs.erb +24 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_command.erb +22 -6
- data/lib/karafka/web/pro/ui/views/consumers/commands/_command_details.erb +4 -0
- data/lib/karafka/web/pro/ui/views/consumers/commands/_empty.erb +6 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_incompatible_schema.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_metadata.erb +4 -1
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/_table.erb +5 -2
- data/lib/karafka/web/pro/ui/views/{commands → consumers/commands}/index.erb +7 -4
- data/lib/karafka/web/pro/ui/views/consumers/commands/show.erb +32 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/_breadcrumbs.erb +46 -0
- data/lib/karafka/web/pro/ui/views/consumers/{_consumer.erb → consumers/_consumer.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/consumers/{_consumer_performance.erb → consumers/_consumer_performance.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/consumers/consumers/_tabs.erb +38 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_commands.erb +80 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_consumer_group.erb +11 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_metrics.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_no_subscriptions.erb +10 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_partition.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/consumers/consumer/_partition_edit_options.erb +33 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_stopped.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_subscription_group.erb +7 -3
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → consumers/consumer}/_tabs.erb +7 -4
- data/lib/karafka/web/pro/ui/views/consumers/consumers/details.erb +15 -0
- data/lib/karafka/web/pro/ui/views/consumers/{index.erb → consumers/index.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/consumers/{performance.erb → consumers/performance.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/consumers/consumers/subscriptions.erb +24 -0
- data/lib/karafka/web/pro/ui/views/consumers/controls/_breadcrumbs.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/{_consumer_controls.erb → controls/_controls.erb} +10 -7
- data/lib/karafka/web/pro/ui/views/consumers/{controls.erb → controls/index.erb} +8 -5
- data/lib/karafka/web/pro/ui/views/consumers/jobs/_breadcrumbs.erb +36 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → jobs}/_job.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/{consumer → jobs}/_no_jobs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/consumers/{pending_jobs.erb → jobs/pending.erb} +7 -8
- data/lib/karafka/web/pro/ui/views/consumers/{running_jobs.erb → jobs/running.erb} +7 -8
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_basics.erb +77 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_breadcrumbs.erb +58 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_form.erb +109 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_not_running_error.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/_running_warning.erb +15 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/offsets/edit.erb +12 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_active_not_editable.erb +22 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_adjusting_warning.erb +27 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_breadcrumbs.erb +60 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_edit_form.erb +59 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_lrj_not_manageable.erb +24 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_new_form.erb +78 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/_not_running.erb +16 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/edit.erb +20 -0
- data/lib/karafka/web/pro/ui/views/consumers/partitions/pauses/new.erb +16 -0
- data/lib/karafka/web/pro/ui/views/dashboard/index.erb +4 -1
- data/lib/karafka/web/pro/ui/views/dlq/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/dlq/_no_topics.erb +3 -0
- data/lib/karafka/web/pro/ui/views/dlq/_topic.erb +4 -1
- data/lib/karafka/web/pro/ui/views/dlq/index.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_error.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_partition_option.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_selector.erb +3 -0
- data/lib/karafka/web/pro/ui/views/errors/_table.erb +4 -1
- data/lib/karafka/web/pro/ui/views/errors/index.erb +6 -3
- data/lib/karafka/web/pro/ui/views/errors/partition.erb +5 -2
- data/lib/karafka/web/pro/ui/views/errors/show.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{_breadcrumbs.erb → explorer/_breadcrumbs.erb} +7 -4
- data/lib/karafka/web/pro/ui/views/explorer/{_failed_deserialization.erb → explorer/_failed_deserialization.erb} +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{_filtered.erb → explorer/_filtered.erb} +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{_message.erb → explorer/_message.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/explorer/_no_topics.erb +4 -0
- data/lib/karafka/web/pro/ui/views/explorer/{_partition_option.erb → explorer/_partition_option.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/{_selector.erb → explorer/_selector.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/explorer/_topic.erb +13 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/index.erb +17 -0
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_metadata.erb +10 -7
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_payload.erb +6 -3
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_resources_utilization.erb +7 -4
- data/lib/karafka/web/pro/ui/views/explorer/{message → explorer/message}/_too_big_to_be_displayed.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{messages → explorer/messages}/_detail.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/messages/_headers.erb +51 -0
- data/lib/karafka/web/pro/ui/views/explorer/{messages → explorer/messages}/_key.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_cleaned.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_empty.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/{partition → explorer/partition}/_messages.erb +4 -1
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_time_selector.erb +16 -0
- data/lib/karafka/web/pro/ui/views/explorer/explorer/partition/_timestamp_selector.erb +33 -0
- data/lib/karafka/web/pro/ui/views/explorer/{partition.erb → explorer/partition.erb} +24 -17
- data/lib/karafka/web/pro/ui/views/explorer/{show.erb → explorer/show.erb} +17 -19
- data/lib/karafka/web/pro/ui/views/explorer/{topic → explorer/topic}/_actions.erb +5 -2
- data/lib/karafka/web/pro/ui/views/explorer/explorer/topic/_empty.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/{topic → explorer/topic}/_limited.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/{topic.erb → explorer/topic.erb} +7 -4
- data/lib/karafka/web/pro/ui/views/explorer/messages/_breadcrumbs.erb +32 -0
- data/lib/karafka/web/pro/ui/views/explorer/messages/forward.erb +143 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/_breadcrumbs.erb +4 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/_fix_errors.erb +6 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_metadata.erb +3 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/_no_results.erb +6 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_no_search_criteria.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_search_criteria.erb +3 -0
- data/lib/karafka/web/pro/ui/views/{search → explorer/search}/_search_modal.erb +5 -2
- data/lib/karafka/web/pro/ui/views/explorer/search/_timeout.erb +6 -0
- data/lib/karafka/web/pro/ui/views/explorer/search/index.erb +32 -0
- data/lib/karafka/web/pro/ui/views/health/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_no_data.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_partition.erb +16 -1
- data/lib/karafka/web/pro/ui/views/health/_partition_lags.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_partition_offset.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_partition_times.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/_table_metadata.erb +4 -1
- data/lib/karafka/web/pro/ui/views/health/_tabs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/changes.erb +4 -1
- data/lib/karafka/web/pro/ui/views/health/cluster_lags.erb +3 -0
- data/lib/karafka/web/pro/ui/views/health/lags.erb +5 -2
- data/lib/karafka/web/pro/ui/views/health/offsets.erb +4 -1
- data/lib/karafka/web/pro/ui/views/health/overview.erb +8 -3
- data/lib/karafka/web/pro/ui/views/jobs/_job.erb +4 -1
- data/lib/karafka/web/pro/ui/views/jobs/_no_jobs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/jobs/pending.erb +4 -1
- data/lib/karafka/web/pro/ui/views/jobs/running.erb +4 -1
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_actions.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_batch_actions.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_log.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_not_active.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_tabs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/_task.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/logs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/recurring_tasks/schedule.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/_consumer_group.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/_detail.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/_topic.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/index.erb +3 -0
- data/lib/karafka/web/pro/ui/views/routing/show.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_breadcrumbs.erb +6 -3
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_key.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_message.erb +4 -1
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/_messages.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/partition.erb +23 -16
- data/lib/karafka/web/pro/ui/views/scheduled_messages/explorer/topic.erb +6 -3
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_breadcrumbs.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/_no_groups.erb +3 -0
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/index.erb +4 -1
- data/lib/karafka/web/pro/ui/views/scheduled_messages/schedules/show.erb +3 -0
- data/lib/karafka/web/pro/ui/views/shared/_navigation.erb +25 -17
- data/lib/karafka/web/pro/ui/views/shared/_rdkafka_form_error_alert_box.erb +16 -0
- data/lib/karafka/web/pro/ui/views/shared/branding/_label.erb +3 -0
- data/lib/karafka/web/pro/ui/views/shared/branding/_notice.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_breadcrumbs.erb +34 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_config.erb +26 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_delete_button.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_edit_form.erb +50 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_edit_plan.erb +16 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/_edit_warning.erb +12 -0
- data/lib/karafka/web/pro/ui/views/topics/configs/edit.erb +16 -0
- data/lib/karafka/web/pro/ui/views/topics/{config.erb → configs/index.erb} +9 -3
- data/lib/karafka/web/pro/ui/views/topics/distributions/_add_partitions_button.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_badges.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_breadcrumbs.erb +28 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_chart.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_form.erb +47 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_hints.erb +15 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_edit_warnings.erb +14 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_empty_partitions.erb +4 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution → distributions}/_limited.erb +3 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/_partition.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/distributions/edit.erb +16 -0
- data/lib/karafka/web/pro/ui/views/topics/{distribution.erb → distributions/show.erb} +11 -7
- data/lib/karafka/web/pro/ui/views/topics/offsets/_breadcrumbs.erb +20 -0
- data/lib/karafka/web/pro/ui/views/topics/offsets/_partition.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/{offsets.erb → offsets/show.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/topics/replications/_breadcrumbs.erb +20 -0
- data/lib/karafka/web/pro/ui/views/topics/{_partition.erb → replications/_partition.erb} +4 -1
- data/lib/karafka/web/pro/ui/views/topics/{replication.erb → replications/show.erb} +6 -3
- data/lib/karafka/web/pro/ui/views/topics/topics/_breadcrumbs.erb +32 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_create_button.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_create_hints.erb +15 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_delete_form.erb +36 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_delete_hints.erb +15 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_delete_warning.erb +13 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/_new_form.erb +80 -0
- data/lib/karafka/web/pro/ui/views/topics/{_tabs.erb → topics/_tabs.erb} +7 -4
- data/lib/karafka/web/pro/ui/views/topics/topics/_topic.erb +12 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/edit.erb +10 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/index.erb +19 -0
- data/lib/karafka/web/pro/ui/views/topics/topics/new.erb +12 -0
- data/lib/karafka/web/processing/consumer.rb +7 -7
- data/lib/karafka/web/processing/consumers/aggregators/state.rb +14 -14
- data/lib/karafka/web/processing/consumers/metrics.rb +1 -1
- data/lib/karafka/web/processing/consumers/state.rb +1 -1
- data/lib/karafka/web/processing/publisher.rb +4 -4
- data/lib/karafka/web/tracking/consumers/contracts/partition.rb +1 -0
- data/lib/karafka/web/tracking/consumers/listeners/pausing.rb +2 -2
- data/lib/karafka/web/tracking/consumers/listeners/transactions.rb +44 -0
- data/lib/karafka/web/tracking/consumers/reporter.rb +2 -2
- data/lib/karafka/web/tracking/consumers/sampler.rb +81 -14
- data/lib/karafka/web/tracking/helpers/sysconf.rb +33 -0
- data/lib/karafka/web/tracking/producers/reporter.rb +1 -1
- data/lib/karafka/web/ui/app.rb +19 -112
- data/lib/karafka/web/ui/base.rb +58 -3
- data/lib/karafka/web/ui/controllers/base_controller.rb +43 -1
- data/lib/karafka/web/ui/controllers/cluster_controller.rb +5 -2
- data/lib/karafka/web/ui/controllers/errors_controller.rb +1 -1
- data/lib/karafka/web/ui/controllers/requests/execution_wrapper.rb +52 -0
- data/lib/karafka/web/ui/controllers/requests/hookable.rb +99 -0
- data/lib/karafka/web/ui/controllers/requests/params.rb +39 -1
- data/lib/karafka/web/ui/controllers/responses/redirect.rb +0 -5
- data/lib/karafka/web/ui/controllers/status_controller.rb +3 -0
- data/lib/karafka/web/ui/helpers/application_helper.rb +10 -1
- data/lib/karafka/web/ui/helpers/paths_helper.rb +54 -10
- data/lib/karafka/web/ui/lib/admin.rb +1 -1
- data/lib/karafka/web/ui/lib/cache.rb +135 -0
- data/lib/karafka/web/ui/models/broker.rb +1 -2
- data/lib/karafka/web/ui/models/cluster_info.rb +15 -21
- data/lib/karafka/web/ui/models/consumers_metrics.rb +1 -1
- data/lib/karafka/web/ui/models/consumers_state.rb +1 -1
- data/lib/karafka/web/ui/models/counters.rb +1 -1
- data/lib/karafka/web/ui/models/health.rb +9 -7
- data/lib/karafka/web/ui/models/process.rb +16 -0
- data/lib/karafka/web/ui/models/processes.rb +29 -8
- data/lib/karafka/web/ui/models/recurring_tasks/schedule.rb +1 -1
- data/lib/karafka/web/ui/models/status.rb +28 -9
- data/lib/karafka/web/ui/models/topic.rb +1 -2
- data/lib/karafka/web/ui/public/javascripts/application.js +8 -98
- data/lib/karafka/web/ui/public/javascripts/application.min.js +12 -4
- data/lib/karafka/web/ui/public/javascripts/application.min.js.br +0 -0
- data/lib/karafka/web/ui/public/javascripts/application.min.js.gz +0 -0
- data/lib/karafka/web/ui/public/javascripts/components/action_confirmation_manager.js +30 -0
- data/lib/karafka/web/ui/public/javascripts/components/alerts.js +39 -0
- data/lib/karafka/web/ui/public/javascripts/components/button_lock_manager.js +50 -0
- data/lib/karafka/web/ui/public/javascripts/components/live_poll.js +71 -19
- data/lib/karafka/web/ui/public/javascripts/components/message_republish_manager.js +50 -0
- data/lib/karafka/web/ui/public/javascripts/components/page_title_tracker.js +21 -0
- data/lib/karafka/web/ui/public/javascripts/components/partition_redirect_manager.js +21 -0
- data/lib/karafka/web/ui/public/javascripts/components/time_ago_manager.js +25 -0
- data/lib/karafka/web/ui/public/javascripts/components/timestamp_selector.js +30 -0
- data/lib/karafka/web/ui/public/javascripts/libs/datepicker.js +2 -2
- data/lib/karafka/web/ui/public/stylesheets/application.css +30 -0
- data/lib/karafka/web/ui/public/stylesheets/application.min.css +5122 -13
- data/lib/karafka/web/ui/public/stylesheets/application.min.css.br +0 -0
- data/lib/karafka/web/ui/public/stylesheets/application.min.css.gz +0 -0
- data/lib/karafka/web/ui/public/stylesheets/libs/highlight_dark.min.css.gz +0 -0
- data/lib/karafka/web/ui/public/stylesheets/libs/highlight_light.min.css.gz +0 -0
- data/lib/karafka/web/ui/public/stylesheets/libs/tailwind.css +507 -214
- data/lib/karafka/web/ui/routes/assets.rb +53 -0
- data/lib/karafka/web/ui/routes/base.rb +36 -0
- data/lib/karafka/web/ui/routes/cluster.rb +28 -0
- data/lib/karafka/web/ui/routes/consumers.rb +35 -0
- data/lib/karafka/web/ui/routes/dashboard.rb +20 -0
- data/lib/karafka/web/ui/routes/errors.rb +26 -0
- data/lib/karafka/web/ui/routes/jobs.rb +28 -0
- data/lib/karafka/web/ui/routes/pro_only.rb +27 -0
- data/lib/karafka/web/ui/routes/routing.rb +26 -0
- data/lib/karafka/web/ui/routes/status.rb +19 -0
- data/lib/karafka/web/ui/routes/support.rb +19 -0
- data/lib/karafka/web/ui/routes/ux.rb +19 -0
- data/lib/karafka/web/ui/views/cluster/_partition.erb +2 -2
- data/lib/karafka/web/ui/views/cluster/brokers.erb +1 -1
- data/lib/karafka/web/ui/views/consumers/_breadcrumbs.erb +7 -1
- data/lib/karafka/web/ui/views/consumers/_consumer.erb +1 -1
- data/lib/karafka/web/ui/views/consumers/_no_consumers.erb +2 -2
- data/lib/karafka/web/ui/views/consumers/_tabs.erb +4 -4
- data/lib/karafka/web/ui/views/consumers/index.erb +1 -1
- data/lib/karafka/web/ui/views/dashboard/_feature_pro.erb +1 -1
- data/lib/karafka/web/ui/views/dashboard/_not_enough_data.erb +2 -2
- data/lib/karafka/web/ui/views/dashboard/_ranges_selector.erb +1 -1
- data/lib/karafka/web/ui/views/dashboard/index.erb +6 -49
- data/lib/karafka/web/ui/views/errors/_detail.erb +3 -3
- data/lib/karafka/web/ui/views/errors/index.erb +1 -1
- data/lib/karafka/web/ui/views/jobs/_job.erb +1 -1
- data/lib/karafka/web/ui/views/jobs/pending.erb +1 -1
- data/lib/karafka/web/ui/views/jobs/running.erb +1 -1
- data/lib/karafka/web/ui/views/layout.erb +7 -5
- data/lib/karafka/web/ui/views/shared/_become_pro.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_brand.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_breadcrumbs.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_content.erb +1 -1
- data/lib/karafka/web/ui/views/shared/_controls.erb +10 -3
- data/lib/karafka/web/ui/views/shared/_custom_nav.erb +9 -0
- data/lib/karafka/web/ui/views/shared/_flashes.erb +3 -5
- data/lib/karafka/web/ui/views/shared/_header.erb +25 -2
- data/lib/karafka/web/ui/views/shared/_navigation.erb +17 -15
- data/lib/karafka/web/ui/views/shared/alerts/_error.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_info.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_primary.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_secondary.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_success.erb +8 -0
- data/lib/karafka/web/ui/views/shared/alerts/_warning.erb +8 -0
- data/lib/karafka/web/ui/views/shared/exceptions/not_allowed.erb +4 -0
- data/lib/karafka/web/ui/views/shared/exceptions/not_found.erb +5 -1
- data/lib/karafka/web/ui/views/shared/exceptions/pro_only.erb +4 -0
- data/lib/karafka/web/ui/views/shared/icons/_arrow_left.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_arrow_up_tray.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_clock.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_pencil.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_pencil_square.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_play_pause.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_plus.erb +3 -0
- data/lib/karafka/web/ui/views/shared/icons/_trash.erb +3 -0
- data/lib/karafka/web/ui/views/status/failures/_live_reporting.erb +1 -1
- data/lib/karafka/web/ui/views/status/failures/_partitions.erb +3 -3
- data/lib/karafka/web/ui/views/status/failures/_state_calculation.erb +2 -2
- data/lib/karafka/web/ui/views/status/info/_components.erb +6 -6
- data/lib/karafka/web/ui/views/status/show.erb +15 -0
- data/lib/karafka/web/ui/views/status/warnings/_consumers_schemas.erb +31 -0
- data/lib/karafka/web/ui/views/ux/_icons.erb +1 -1
- data/lib/karafka/web/version.rb +1 -1
- data/lib/karafka/web.rb +3 -0
- data/package-lock.json +776 -1208
- data/package.json +3 -4
- data/postcss.config.js +1 -2
- data/renovate.json +13 -1
- data/tailwind.config.js +0 -4
- data.tar.gz.sig +0 -0
- metadata +225 -106
- metadata.gz.sig +0 -0
- data/lib/karafka/web/pro/commanding/commands/quiet.rb +0 -34
- data/lib/karafka/web/pro/commanding/commands/stop.rb +0 -34
- data/lib/karafka/web/pro/commanding/commands/trace.rb +0 -41
- data/lib/karafka/web/pro/ui/controllers/commanding_controller.rb +0 -118
- data/lib/karafka/web/pro/ui/controllers/commands_controller.rb +0 -96
- data/lib/karafka/web/pro/ui/controllers/consumers_controller.rb +0 -138
- data/lib/karafka/web/pro/ui/controllers/explorer_controller.rb +0 -220
- data/lib/karafka/web/pro/ui/controllers/messages_controller.rb +0 -107
- data/lib/karafka/web/pro/ui/controllers/search_controller.rb +0 -73
- data/lib/karafka/web/pro/ui/controllers/topics_controller.rb +0 -130
- data/lib/karafka/web/pro/ui/views/commands/_breadcrumbs.erb +0 -21
- data/lib/karafka/web/pro/ui/views/commands/_command_details.erb +0 -1
- data/lib/karafka/web/pro/ui/views/commands/_empty.erb +0 -3
- data/lib/karafka/web/pro/ui/views/commands/show.erb +0 -33
- data/lib/karafka/web/pro/ui/views/consumers/_breadcrumbs.erb +0 -55
- data/lib/karafka/web/pro/ui/views/consumers/_tabs.erb +0 -33
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_commands.erb +0 -72
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_consumer_group.erb +0 -8
- data/lib/karafka/web/pro/ui/views/consumers/consumer/_no_subscriptions.erb +0 -7
- data/lib/karafka/web/pro/ui/views/consumers/details.erb +0 -13
- data/lib/karafka/web/pro/ui/views/consumers/subscriptions.erb +0 -25
- data/lib/karafka/web/pro/ui/views/explorer/_no_topics.erb +0 -1
- data/lib/karafka/web/pro/ui/views/explorer/_topic.erb +0 -10
- data/lib/karafka/web/pro/ui/views/explorer/index.erb +0 -14
- data/lib/karafka/web/pro/ui/views/explorer/messages/_headers.erb +0 -33
- data/lib/karafka/web/pro/ui/views/explorer/partition/_cleaned.erb +0 -3
- data/lib/karafka/web/pro/ui/views/explorer/partition/_empty.erb +0 -3
- data/lib/karafka/web/pro/ui/views/explorer/topic/_empty.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/_breadcrumbs.erb +0 -1
- data/lib/karafka/web/pro/ui/views/search/_fix_errors.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/_no_results.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/_timeout.erb +0 -3
- data/lib/karafka/web/pro/ui/views/search/index.erb +0 -29
- data/lib/karafka/web/pro/ui/views/topics/_breadcrumbs.erb +0 -45
- data/lib/karafka/web/pro/ui/views/topics/_partition_offsets.erb +0 -10
- data/lib/karafka/web/pro/ui/views/topics/_topic.erb +0 -9
- data/lib/karafka/web/pro/ui/views/topics/distribution/_empty_partitions.erb +0 -1
- data/lib/karafka/web/pro/ui/views/topics/distribution/_partition.erb +0 -10
- data/lib/karafka/web/pro/ui/views/topics/index.erb +0 -14
- data/lib/karafka/web/ui/lib/ttl_cache.rb +0 -82
@@ -36,7 +36,7 @@ module Karafka
|
|
36
36
|
def add(report, offset)
|
37
37
|
super(report)
|
38
38
|
increment_total_counters(report)
|
39
|
-
|
39
|
+
add_state(report, offset)
|
40
40
|
# We always evict after counters updates because we want to use expired (stopped)
|
41
41
|
# data for counters as it was valid previously. This can happen only when web consumer
|
42
42
|
# had a lag and is catching up.
|
@@ -46,6 +46,19 @@ module Karafka
|
|
46
46
|
refresh_current_stats
|
47
47
|
end
|
48
48
|
|
49
|
+
# Registers or updates the given process state based on the report
|
50
|
+
#
|
51
|
+
# @param report [Hash]
|
52
|
+
# @param offset [Integer]
|
53
|
+
def add_state(report, offset)
|
54
|
+
process_id = report[:process][:id]
|
55
|
+
|
56
|
+
state[:processes][process_id] = {
|
57
|
+
dispatched_at: report[:dispatched_at],
|
58
|
+
offset: offset
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
49
62
|
# @return [Array<Hash, Float>] aggregated current stats value and time from which this
|
50
63
|
# aggregation comes from
|
51
64
|
#
|
@@ -84,19 +97,6 @@ module Karafka
|
|
84
97
|
end
|
85
98
|
end
|
86
99
|
|
87
|
-
# Registers or updates the given process state based on the report
|
88
|
-
#
|
89
|
-
# @param report [Hash]
|
90
|
-
# @param offset [Integer]
|
91
|
-
def update_process_state(report, offset)
|
92
|
-
process_id = report[:process][:id]
|
93
|
-
|
94
|
-
state[:processes][process_id] = {
|
95
|
-
dispatched_at: report[:dispatched_at],
|
96
|
-
offset: offset
|
97
|
-
}
|
98
|
-
end
|
99
|
-
|
100
100
|
# Evicts expired processes from the current state
|
101
101
|
# We consider processes dead if they do not report often enough
|
102
102
|
# @note We do not evict based on states (stopped), because we want to report the
|
@@ -12,7 +12,7 @@ module Karafka
|
|
12
12
|
# @return [Hash] latest (current) aggregated metrics state
|
13
13
|
def current!
|
14
14
|
metrics_message = ::Karafka::Admin.read_topic(
|
15
|
-
Karafka::Web.config.topics.consumers.metrics,
|
15
|
+
Karafka::Web.config.topics.consumers.metrics.name,
|
16
16
|
0,
|
17
17
|
# We need to take more in case there would be transactions running.
|
18
18
|
# In theory we could take two but this compensates for any involuntary
|
@@ -12,7 +12,7 @@ module Karafka
|
|
12
12
|
# @return [Hash] last (current) aggregated processes state
|
13
13
|
def current!
|
14
14
|
state_message = ::Karafka::Admin.read_topic(
|
15
|
-
Karafka::Web.config.topics.consumers.states,
|
15
|
+
Karafka::Web.config.topics.consumers.states.name,
|
16
16
|
0,
|
17
17
|
# We need to take more in case there would be transactions running.
|
18
18
|
# In theory we could take two but this compensates for any involuntary
|
@@ -36,17 +36,17 @@ module Karafka
|
|
36
36
|
def prepare_data(consumers_state, consumers_metrics)
|
37
37
|
[
|
38
38
|
{
|
39
|
-
topic: Karafka::Web.config.topics.consumers.states,
|
39
|
+
topic: Karafka::Web.config.topics.consumers.states.name,
|
40
40
|
payload: Zlib::Deflate.deflate(consumers_state.to_json),
|
41
41
|
# This will ensure that the consumer states are compacted
|
42
|
-
key: Karafka::Web.config.topics.consumers.states,
|
42
|
+
key: Karafka::Web.config.topics.consumers.states.name,
|
43
43
|
partition: 0,
|
44
44
|
headers: { 'zlib' => 'true' }
|
45
45
|
},
|
46
46
|
{
|
47
|
-
topic: Karafka::Web.config.topics.consumers.metrics,
|
47
|
+
topic: Karafka::Web.config.topics.consumers.metrics.name,
|
48
48
|
payload: Zlib::Deflate.deflate(consumers_metrics.to_json),
|
49
|
-
key: Karafka::Web.config.topics.consumers.metrics,
|
49
|
+
key: Karafka::Web.config.topics.consumers.metrics.name,
|
50
50
|
partition: 0,
|
51
51
|
headers: { 'zlib' => 'true' }
|
52
52
|
}
|
@@ -28,6 +28,7 @@ module Karafka
|
|
28
28
|
required(:ls_offset) { |val| val.is_a?(Integer) }
|
29
29
|
required(:ls_offset_d) { |val| val.is_a?(Integer) }
|
30
30
|
required(:ls_offset_fd) { |val| val.is_a?(Integer) && val >= 0 }
|
31
|
+
required(:transactional) { |val| [true, false].include?(val) }
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -8,10 +8,10 @@ module Karafka
|
|
8
8
|
# Tracks pausing and un-pausing of topics partitions for both user requested and
|
9
9
|
# automatic events.
|
10
10
|
class Pausing < Base
|
11
|
-
#
|
11
|
+
# Tracks the pause start
|
12
12
|
#
|
13
13
|
# @param event [Karafka::Core::Monitoring::Event]
|
14
|
-
def
|
14
|
+
def on_client_pause(event)
|
15
15
|
track do |sampler|
|
16
16
|
sampler.pauses[pause_id(event)] = {
|
17
17
|
timeout: event[:timeout],
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Web
|
5
|
+
module Tracking
|
6
|
+
module Consumers
|
7
|
+
module Listeners
|
8
|
+
# Tracks data related to transactions
|
9
|
+
# seek offsets are needed because when consumer offsets are committed in transactions,
|
10
|
+
# librdkafka does not publish the lags in a regular way (they are set to -1) and we need
|
11
|
+
# to compute them via enrichment of information.
|
12
|
+
class Transactions < Base
|
13
|
+
# Tracking of things needed to support transactional consumers post successful
|
14
|
+
# transaction.
|
15
|
+
#
|
16
|
+
# @param event [Karafka::Core::Monitoring::Event]
|
17
|
+
def on_consumer_consuming_transaction(event)
|
18
|
+
consumer = event[:caller]
|
19
|
+
sg_id = consumer.topic.subscription_group.id
|
20
|
+
topic_name = consumer.topic.name
|
21
|
+
# We store it as a string because librdkafka also does that and its easier to align
|
22
|
+
# without casting it later
|
23
|
+
partition_id = consumer.partition
|
24
|
+
|
25
|
+
track do |sampler|
|
26
|
+
break unless sampler.subscription_groups.key?(sg_id)
|
27
|
+
|
28
|
+
seek_offset = consumer.coordinator.seek_offset
|
29
|
+
|
30
|
+
break if seek_offset.nil?
|
31
|
+
|
32
|
+
topics_scope = sampler.subscription_groups[sg_id][:topics]
|
33
|
+
p_scope = topics_scope[topic_name][partition_id]
|
34
|
+
|
35
|
+
p_scope[:transactional] = true
|
36
|
+
p_scope[:seek_offset] = seek_offset
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -63,7 +63,7 @@ module Karafka
|
|
63
63
|
# Report consumers statuses
|
64
64
|
messages = [
|
65
65
|
{
|
66
|
-
topic: ::Karafka::Web.config.topics.consumers.reports,
|
66
|
+
topic: ::Karafka::Web.config.topics.consumers.reports.name,
|
67
67
|
payload: Zlib::Deflate.deflate(report.to_json),
|
68
68
|
key: process_id,
|
69
69
|
partition: 0,
|
@@ -76,7 +76,7 @@ module Karafka
|
|
76
76
|
@error_contract.validate!(error)
|
77
77
|
|
78
78
|
{
|
79
|
-
topic: Karafka::Web.config.topics.errors,
|
79
|
+
topic: Karafka::Web.config.topics.errors.name,
|
80
80
|
payload: Zlib::Deflate.deflate(error.to_json),
|
81
81
|
# Always dispatch errors from the same process to the same partition
|
82
82
|
key: process_id,
|
@@ -15,7 +15,7 @@ module Karafka
|
|
15
15
|
# Current schema version
|
16
16
|
# This is used for detecting incompatible changes and not using outdated data during
|
17
17
|
# upgrades
|
18
|
-
SCHEMA_VERSION = '1.4.
|
18
|
+
SCHEMA_VERSION = '1.4.1'
|
19
19
|
|
20
20
|
# Counters that count events occurrences during the given window
|
21
21
|
COUNTERS_BASE = {
|
@@ -51,7 +51,17 @@ module Karafka
|
|
51
51
|
@subscription_groups = Hash.new do |h, sg_id|
|
52
52
|
h[sg_id] = {
|
53
53
|
id: sg_id,
|
54
|
-
polled_at: monotonic_now
|
54
|
+
polled_at: monotonic_now,
|
55
|
+
topics: Hash.new do |h1, topic|
|
56
|
+
h1[topic] = Hash.new do |h2, partition|
|
57
|
+
# We track those details in case we need to fill statistical gaps for
|
58
|
+
# transactional consumers
|
59
|
+
h2[partition] = {
|
60
|
+
seek_offset: -1,
|
61
|
+
transactional: false
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
55
65
|
}
|
56
66
|
end
|
57
67
|
|
@@ -223,11 +233,9 @@ module Karafka
|
|
223
233
|
def memory_size
|
224
234
|
@memory_size ||= case RUBY_PLATFORM
|
225
235
|
when /linux/
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
.to_s
|
230
|
-
.to_i
|
236
|
+
mem_info = File.read('/proc/meminfo')
|
237
|
+
mem_total_line = mem_info.match(/MemTotal:\s*(?<total>\d+)/)
|
238
|
+
mem_total_line['total'].to_i
|
231
239
|
when /darwin|bsd/
|
232
240
|
@shell
|
233
241
|
.call('sysctl -a')
|
@@ -245,7 +253,13 @@ module Karafka
|
|
245
253
|
# @return [Array<Float>] load averages for last 1, 5 and 15 minutes
|
246
254
|
def cpu_usage
|
247
255
|
case RUBY_PLATFORM
|
248
|
-
when /
|
256
|
+
when /linux/
|
257
|
+
File
|
258
|
+
.read('/proc/loadavg')
|
259
|
+
.split(' ')
|
260
|
+
.first(3)
|
261
|
+
.map(&:to_f)
|
262
|
+
when /darwin|bsd/
|
249
263
|
@shell
|
250
264
|
.call('w | head -1')
|
251
265
|
.strip
|
@@ -280,10 +294,21 @@ module Karafka
|
|
280
294
|
def memory_threads_ps
|
281
295
|
@memory_threads_ps = case RUBY_PLATFORM
|
282
296
|
when /linux/
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
297
|
+
page_size = Karafka::Web::Tracking::Helpers::Sysconf.page_size
|
298
|
+
status_file = "/proc/#{::Process.pid}/status"
|
299
|
+
|
300
|
+
pid = status_file.match(%r{/proc/(\d+)/status})[1]
|
301
|
+
|
302
|
+
# Extract thread count from /proc/<pid>/status
|
303
|
+
thcount = File.read(status_file)[/^Threads:\s+(\d+)/, 1].to_i
|
304
|
+
|
305
|
+
# Extract RSS from /proc/<pid>/statm (second field)
|
306
|
+
statm_file = "/proc/#{pid}/statm"
|
307
|
+
rss_pages = File.read(statm_file).split[1].to_i rescue 0
|
308
|
+
# page size is retrieved from Sysconf
|
309
|
+
rss_kb = (rss_pages * page_size) / 1024
|
310
|
+
|
311
|
+
[[rss_kb, thcount, pid.to_i]]
|
287
312
|
# thcount is not available on macos ps
|
288
313
|
# because of that we inject 0 as threads count similar to how
|
289
314
|
# we do on windows
|
@@ -308,9 +333,51 @@ module Karafka
|
|
308
333
|
# This should be always available, since the subscription group polled at time
|
309
334
|
# is first initialized before we start polling, there should be no case where
|
310
335
|
# we have statistics about a given subscription group but we do not have the
|
311
|
-
#
|
312
|
-
|
336
|
+
# sg reference
|
337
|
+
sg_tracking = subscription_groups.fetch(sg_id)
|
338
|
+
|
339
|
+
polled_at = sg_tracking.fetch(:polled_at)
|
313
340
|
sg_details[:state][:poll_age] = (monotonic_now - polled_at).round(2)
|
341
|
+
|
342
|
+
sg_details[:topics].each do |topic_name, topic_details|
|
343
|
+
topic_details[:partitions].each do |partition_id, partition_details|
|
344
|
+
# Always assume non-transactional as default. Will be overwritten by the
|
345
|
+
# consumer level details if collected
|
346
|
+
partition_details[:transactional] ||= false
|
347
|
+
|
348
|
+
# If we have stored offset or stored lag, it means it's not a transactional
|
349
|
+
# consumer at all so we can skip enrichment
|
350
|
+
next if partition_details[:lag_stored].positive?
|
351
|
+
next if partition_details[:stored_offset].positive?
|
352
|
+
next unless sg_tracking[:topics].key?(topic_name)
|
353
|
+
next unless sg_tracking[:topics][topic_name].key?(partition_id)
|
354
|
+
|
355
|
+
k_partition_details = sg_tracking[:topics][topic_name][partition_id]
|
356
|
+
|
357
|
+
# If seek offset was not yey set, nothing to enrich
|
358
|
+
next unless k_partition_details[:seek_offset].positive?
|
359
|
+
|
360
|
+
partition_details[:transactional] = k_partition_details[:transactional]
|
361
|
+
|
362
|
+
# Seek offset is always +1 from the last stored in Karafka
|
363
|
+
seek_offset = k_partition_details[:seek_offset]
|
364
|
+
stored_offset = seek_offset - 1
|
365
|
+
|
366
|
+
# In case of transactions we have to compute the lag ourselves
|
367
|
+
# -1 because ls offset (or high watermark) is last + 1
|
368
|
+
lag = partition_details[:ls_offset] - seek_offset
|
369
|
+
# This can happen if ls_offset is refreshed slower than our stored offset
|
370
|
+
# fetching from Karafka transactional layer
|
371
|
+
lag = 0 if lag.negative?
|
372
|
+
|
373
|
+
partition_details[:lag] = lag
|
374
|
+
partition_details[:lag_d] = 0
|
375
|
+
partition_details[:lag_stored] = lag
|
376
|
+
partition_details[:lag_stored_d] = 0
|
377
|
+
partition_details[:stored_offset] = stored_offset
|
378
|
+
partition_details[:committed_offset] = stored_offset
|
379
|
+
end
|
380
|
+
end
|
314
381
|
end
|
315
382
|
end
|
316
383
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Web
|
5
|
+
module Tracking
|
6
|
+
# Namespace for tracking related helpers
|
7
|
+
module Helpers
|
8
|
+
# Namespace for unix-based helper methods used to fetch OS details
|
9
|
+
module Sysconf
|
10
|
+
extend FFI::Library
|
11
|
+
|
12
|
+
case RUBY_PLATFORM
|
13
|
+
when /linux/
|
14
|
+
ffi_lib 'libc.so.6' # Standard C library on Linux
|
15
|
+
SC_PAGESIZE = 30 # _SC_PAGESIZE constant
|
16
|
+
when /darwin/
|
17
|
+
ffi_lib 'libSystem.B.dylib' # Standard C library on macOS
|
18
|
+
SC_PAGESIZE = 29 # _SC_PAGESIZE constant
|
19
|
+
end
|
20
|
+
|
21
|
+
attach_function :sysconf, [:int], :long
|
22
|
+
|
23
|
+
class << self
|
24
|
+
# @return [Integer]
|
25
|
+
def page_size
|
26
|
+
sysconf(SC_PAGESIZE)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -33,7 +33,7 @@ module Karafka
|
|
33
33
|
@error_contract.validate!(error)
|
34
34
|
|
35
35
|
{
|
36
|
-
topic: Karafka::Web.config.topics.errors,
|
36
|
+
topic: Karafka::Web.config.topics.errors.name,
|
37
37
|
payload: error.to_json,
|
38
38
|
# Always dispatch errors from the same process to the same partition
|
39
39
|
key: error[:process][:id]
|
data/lib/karafka/web/ui/app.rb
CHANGED
@@ -11,122 +11,29 @@ module Karafka
|
|
11
11
|
|
12
12
|
instance_exec(&CONTEXT_DETAILS)
|
13
13
|
|
14
|
+
# Sub-routes for given pieces of the Web UI
|
15
|
+
SUB_ROUTES = [
|
16
|
+
Routes::Assets,
|
17
|
+
Routes::Dashboard,
|
18
|
+
Routes::Consumers,
|
19
|
+
Routes::ProOnly,
|
20
|
+
Routes::Jobs,
|
21
|
+
Routes::Routing,
|
22
|
+
Routes::Cluster,
|
23
|
+
Routes::Errors,
|
24
|
+
Routes::Status,
|
25
|
+
Routes::Support,
|
26
|
+
Routes::Ux
|
27
|
+
].freeze
|
28
|
+
|
29
|
+
private_constant :SUB_ROUTES
|
30
|
+
|
14
31
|
route do |r|
|
15
32
|
r.root { r.redirect root_path('dashboard') }
|
16
33
|
|
17
|
-
|
18
|
-
# after upgrade
|
19
|
-
r.on 'assets', Karafka::Web::VERSION do
|
20
|
-
r.public
|
21
|
-
end
|
22
|
-
|
23
|
-
r.get 'dashboard' do
|
24
|
-
@breadcrumbs = false
|
25
|
-
controller = Controllers::DashboardController.new(params)
|
26
|
-
controller.index
|
27
|
-
end
|
28
|
-
|
29
|
-
r.on 'consumers' do
|
30
|
-
%w[
|
31
|
-
performance
|
32
|
-
controls
|
33
|
-
commands
|
34
|
-
].each do |path|
|
35
|
-
r.get path do |_process_id|
|
36
|
-
raise Errors::Ui::ProOnlyError
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
r.get String, 'subscriptions' do |_process_id|
|
41
|
-
raise Errors::Ui::ProOnlyError
|
42
|
-
end
|
43
|
-
|
44
|
-
r.get do
|
45
|
-
controller = Controllers::ConsumersController.new(params)
|
46
|
-
controller.index
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
%w[
|
51
|
-
health
|
52
|
-
explorer
|
53
|
-
dlq
|
54
|
-
].each do |route|
|
55
|
-
r.get route, [String, true], [String, true] do
|
56
|
-
raise Errors::Ui::ProOnlyError
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
r.on 'jobs' do
|
61
|
-
controller = Controllers::JobsController.new(params)
|
62
|
-
|
63
|
-
r.get 'running' do
|
64
|
-
controller.running
|
65
|
-
end
|
66
|
-
|
67
|
-
r.get 'pending' do
|
68
|
-
controller.pending
|
69
|
-
end
|
70
|
-
|
71
|
-
r.redirect root_path('jobs/running')
|
72
|
-
end
|
73
|
-
|
74
|
-
r.on 'routing' do
|
75
|
-
controller = Controllers::RoutingController.new(params)
|
76
|
-
|
77
|
-
r.get String do |topic_id|
|
78
|
-
controller.show(topic_id)
|
79
|
-
end
|
80
|
-
|
81
|
-
r.get do
|
82
|
-
controller.index
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
r.on 'cluster' do
|
87
|
-
controller = Controllers::ClusterController.new(params)
|
88
|
-
|
89
|
-
r.get 'brokers' do
|
90
|
-
controller.brokers
|
91
|
-
end
|
92
|
-
|
93
|
-
r.get 'replication' do
|
94
|
-
controller.replication
|
95
|
-
end
|
96
|
-
|
97
|
-
r.redirect root_path('cluster/brokers')
|
98
|
-
end
|
99
|
-
|
100
|
-
r.on 'topics' do
|
101
|
-
raise Errors::Ui::ProOnlyError
|
102
|
-
end
|
103
|
-
|
104
|
-
r.on 'errors' do
|
105
|
-
controller = Controllers::ErrorsController.new(params)
|
106
|
-
|
107
|
-
r.get Integer do |offset|
|
108
|
-
controller.show(offset)
|
109
|
-
end
|
110
|
-
|
111
|
-
r.get do
|
112
|
-
controller.index
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
r.get 'status' do
|
117
|
-
controller = Controllers::StatusController.new(params)
|
118
|
-
controller.show
|
119
|
-
end
|
120
|
-
|
121
|
-
r.get 'ux' do
|
122
|
-
controller = Controllers::UxController.new(params)
|
123
|
-
controller.show
|
124
|
-
end
|
34
|
+
SUB_ROUTES.each { |sub_route| sub_route.bind(self, r) }
|
125
35
|
|
126
|
-
|
127
|
-
controller = Controllers::SupportController.new(params)
|
128
|
-
controller.show
|
129
|
-
end
|
36
|
+
nil
|
130
37
|
end
|
131
38
|
end
|
132
39
|
end
|
data/lib/karafka/web/ui/base.rb
CHANGED
@@ -40,6 +40,7 @@ module Karafka
|
|
40
40
|
plugin :capture_erb
|
41
41
|
plugin :content_for
|
42
42
|
plugin :inject_erb
|
43
|
+
plugin :all_verbs
|
43
44
|
|
44
45
|
# Based on
|
45
46
|
# https://github.com/sidekiq/sidekiq/blob/ae6ca119/lib/sidekiq/web/application.rb#L8
|
@@ -70,7 +71,16 @@ module Karafka
|
|
70
71
|
# Map redirect flashes (if any) to Roda flash messages
|
71
72
|
result.flashes.each { |key, value| flash[key] = value }
|
72
73
|
|
73
|
-
|
74
|
+
path = case result.path
|
75
|
+
when :back
|
76
|
+
session[:current_path]
|
77
|
+
when :previous
|
78
|
+
session[:previous_path]
|
79
|
+
else
|
80
|
+
root_path(result.path)
|
81
|
+
end
|
82
|
+
|
83
|
+
response.redirect path || root_path
|
74
84
|
end
|
75
85
|
|
76
86
|
handle_block_result Controllers::Responses::File do |result|
|
@@ -109,9 +119,11 @@ module Karafka
|
|
109
119
|
|
110
120
|
before do
|
111
121
|
check_csrf!
|
122
|
+
store_paths_history(request, session)
|
112
123
|
end
|
113
124
|
|
114
125
|
plugin :class_matchers
|
126
|
+
plugin :symbol_matchers
|
115
127
|
|
116
128
|
# Time matcher with optional hours, minutes and seconds
|
117
129
|
TIME_MATCHER = %r{(\d{4}-\d{2}-\d{2}/?(\d{2})?(:\d{2})?(:\d{2})?)}
|
@@ -122,12 +134,22 @@ module Karafka
|
|
122
134
|
# @note In case the date-time is invalid, raise and render 404
|
123
135
|
# @note The time component is optional as `Time#parse` will fallback to lowest time
|
124
136
|
# available, so we can build only date based lookups
|
125
|
-
class_matcher(Time, TIME_MATCHER) do
|
126
|
-
[Time.parse(datetime)]
|
137
|
+
class_matcher(Time, TIME_MATCHER) do |*datetime|
|
138
|
+
[Time.parse(datetime[0])]
|
127
139
|
rescue ArgumentError
|
128
140
|
raise Errors::Ui::NotFoundError
|
129
141
|
end
|
130
142
|
|
143
|
+
# Partitions ids cannot be bigger than 32 bit C int. We use this matcher to ensure we
|
144
|
+
# only support that big partition numbers. Otherwise librdkafka would crash.
|
145
|
+
symbol_matcher :partition_id, /(\d{1,14})/ do |value|
|
146
|
+
int_value = value.to_i
|
147
|
+
|
148
|
+
raise Errors::Ui::NotFoundError unless int_value.between?(0, 2_147_483_647)
|
149
|
+
|
150
|
+
[int_value]
|
151
|
+
end
|
152
|
+
|
131
153
|
# Allows us to build current path with additional params + it merges existing params into
|
132
154
|
# the query data. Query data takes priority over request params.
|
133
155
|
# @param query_data [Hash] query params we want to add to the current path
|
@@ -145,6 +167,14 @@ module Karafka
|
|
145
167
|
[request.path, query_string].compact.join('?')
|
146
168
|
end
|
147
169
|
|
170
|
+
# Builds a consumer instance with all needed details
|
171
|
+
# @param consumer_class [Class]
|
172
|
+
def build(consumer_class)
|
173
|
+
Controllers::Requests::ExecutionWrapper.new(
|
174
|
+
consumer_class.new(params, session)
|
175
|
+
)
|
176
|
+
end
|
177
|
+
|
148
178
|
# Sets appropriate template variables based on the response object and renders the
|
149
179
|
# expected view
|
150
180
|
# @param response [Karafka::Web::Ui::Controllers::Responses::Data] response data object
|
@@ -162,6 +192,31 @@ module Karafka
|
|
162
192
|
def params
|
163
193
|
Controllers::Requests::Params.new(request.params)
|
164
194
|
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
# Stores history about visited paths. Useful for redirecting users back when needed.
|
199
|
+
# @param request [Karafka::Web::Ui::App::RodaRequest]
|
200
|
+
# @param session [Object] session object (Rails or Rack)
|
201
|
+
def store_paths_history(request, session)
|
202
|
+
# Code below tracks previous paths so we can use it to redirect users back
|
203
|
+
return unless request.get?
|
204
|
+
return unless request.env['HTTP_ACCEPT']&.include?('text/html')
|
205
|
+
|
206
|
+
requested_path = request.path
|
207
|
+
|
208
|
+
if session[:current_path].nil?
|
209
|
+
session[:current_path] = requested_path
|
210
|
+
|
211
|
+
return
|
212
|
+
end
|
213
|
+
|
214
|
+
return if request.path == session[:current_path]
|
215
|
+
|
216
|
+
# When navigating to a different page
|
217
|
+
session[:previous_path] = session[:current_path]
|
218
|
+
session[:current_path] = requested_path
|
219
|
+
end
|
165
220
|
end
|
166
221
|
end
|
167
222
|
end
|
@@ -8,6 +8,9 @@ module Karafka
|
|
8
8
|
# Base controller from which all the controllers should inherit.
|
9
9
|
class BaseController
|
10
10
|
include Web::Ui::Lib::Paginations
|
11
|
+
include Requests::Hookable
|
12
|
+
|
13
|
+
attr_reader :params, :session
|
11
14
|
|
12
15
|
# Alias for easier referencing
|
13
16
|
Models = Web::Ui::Models
|
@@ -19,9 +22,31 @@ module Karafka
|
|
19
22
|
|
20
23
|
self.sortable_attributes = []
|
21
24
|
|
25
|
+
# Detect that the state of the cache has changed
|
26
|
+
before do
|
27
|
+
cache.clear_if_needed(
|
28
|
+
session[:cache_hash],
|
29
|
+
session[:cache_timestamp].to_i
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
after do
|
34
|
+
next unless cache.exist?
|
35
|
+
|
36
|
+
session[:cache_hash] = cache.hash
|
37
|
+
session[:cache_timestamp] = cache.timestamp.to_i
|
38
|
+
end
|
39
|
+
|
22
40
|
# @param params [Karafka::Web::Ui::Controllers::Requests::Params] request parameters
|
23
|
-
|
41
|
+
# @param session [Request::Session] request session (Rails or other framework)
|
42
|
+
def initialize(params, session)
|
24
43
|
@params = params
|
44
|
+
@session = session
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Karafka::Web::Ui::Lib::Cache] per-process cache instance
|
48
|
+
def cache
|
49
|
+
Karafka::Web.config.ui.cache
|
25
50
|
end
|
26
51
|
|
27
52
|
private
|
@@ -50,6 +75,9 @@ module Karafka
|
|
50
75
|
|
51
76
|
attributes[:breadcrums_scope] = scope
|
52
77
|
|
78
|
+
@current_action_name = action.to_sym
|
79
|
+
@current_controller_name = base.join('-')
|
80
|
+
|
53
81
|
instance_variables.each do |iv|
|
54
82
|
next if iv.to_s.start_with?('@_')
|
55
83
|
next if iv.to_s.start_with?('@params')
|
@@ -72,6 +100,20 @@ module Karafka
|
|
72
100
|
Responses::Redirect.new(path, flashes)
|
73
101
|
end
|
74
102
|
|
103
|
+
# Wraps the provided arguments inside a message with a `<strong>` tag to simplify flash
|
104
|
+
# messages building.
|
105
|
+
#
|
106
|
+
# @param message [String] message with `?` to be replaced.
|
107
|
+
# @param args [Array<Object>] arguments to use to replace `?` with strong
|
108
|
+
# @return [String] formatted string
|
109
|
+
def format_flash(message, *args)
|
110
|
+
args.each do |arg|
|
111
|
+
message = message.sub('?', "<strong>#{arg}</strong>")
|
112
|
+
end
|
113
|
+
|
114
|
+
message
|
115
|
+
end
|
116
|
+
|
75
117
|
# Builds a file response object that will be used as a base to dispatch the file
|
76
118
|
#
|
77
119
|
# @param content [String] Payload we want to dispatch as a file
|