karafka 1.4.12 → 2.2.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +10 -9
- data/.github/workflows/ci.yml +169 -31
- data/.rspec +4 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +716 -607
- data/CONTRIBUTING.md +10 -19
- data/Gemfile +7 -0
- data/Gemfile.lock +69 -92
- data/LICENSE +17 -0
- data/LICENSE-COMM +89 -0
- data/LICENSE-LGPL +165 -0
- data/README.md +48 -47
- data/bin/benchmarks +99 -0
- data/bin/create_token +22 -0
- data/bin/integrations +310 -0
- data/bin/karafka +5 -14
- data/bin/record_rss +50 -0
- data/bin/rspecs +6 -0
- data/bin/scenario +29 -0
- data/bin/stress_many +13 -0
- data/bin/stress_one +13 -0
- data/bin/verify_license_integrity +37 -0
- data/bin/wait_for_kafka +24 -0
- data/certs/cert_chain.pem +26 -0
- data/certs/karafka-pro.pem +11 -0
- data/config/locales/errors.yml +97 -0
- data/config/locales/pro_errors.yml +59 -0
- data/docker-compose.yml +19 -11
- data/karafka.gemspec +26 -22
- data/lib/active_job/karafka.rb +17 -0
- data/lib/active_job/queue_adapters/karafka_adapter.rb +32 -0
- data/lib/karafka/active_job/consumer.rb +49 -0
- data/lib/karafka/active_job/current_attributes/loading.rb +36 -0
- data/lib/karafka/active_job/current_attributes/persistence.rb +28 -0
- data/lib/karafka/active_job/current_attributes.rb +42 -0
- data/lib/karafka/active_job/dispatcher.rb +69 -0
- data/lib/karafka/active_job/job_extensions.rb +34 -0
- data/lib/karafka/active_job/job_options_contract.rb +32 -0
- data/lib/karafka/admin.rb +313 -0
- data/lib/karafka/app.rb +47 -23
- data/lib/karafka/base_consumer.rb +260 -29
- data/lib/karafka/cli/base.rb +67 -36
- data/lib/karafka/cli/console.rb +18 -12
- data/lib/karafka/cli/help.rb +24 -0
- data/lib/karafka/cli/info.rb +47 -12
- data/lib/karafka/cli/install.rb +23 -14
- data/lib/karafka/cli/server.rb +101 -44
- data/lib/karafka/cli/topics.rb +146 -0
- data/lib/karafka/cli.rb +24 -27
- data/lib/karafka/connection/client.rb +553 -90
- data/lib/karafka/connection/consumer_group_coordinator.rb +48 -0
- data/lib/karafka/connection/listener.rb +294 -38
- data/lib/karafka/connection/listeners_batch.rb +40 -0
- data/lib/karafka/connection/messages_buffer.rb +84 -0
- data/lib/karafka/connection/pauses_manager.rb +46 -0
- data/lib/karafka/connection/proxy.rb +98 -0
- data/lib/karafka/connection/raw_messages_buffer.rb +101 -0
- data/lib/karafka/connection/rebalance_manager.rb +105 -0
- data/lib/karafka/contracts/base.rb +17 -0
- data/lib/karafka/contracts/config.rb +130 -11
- data/lib/karafka/contracts/consumer_group.rb +32 -187
- data/lib/karafka/contracts/server_cli_options.rb +80 -19
- data/lib/karafka/contracts/topic.rb +65 -0
- data/lib/karafka/contracts.rb +1 -1
- data/lib/karafka/embedded.rb +36 -0
- data/lib/karafka/env.rb +46 -0
- data/lib/karafka/errors.rb +37 -21
- data/lib/karafka/helpers/async.rb +33 -0
- data/lib/karafka/helpers/colorize.rb +26 -0
- data/lib/karafka/helpers/multi_delegator.rb +2 -2
- data/lib/karafka/instrumentation/callbacks/error.rb +39 -0
- data/lib/karafka/instrumentation/callbacks/rebalance.rb +64 -0
- data/lib/karafka/instrumentation/callbacks/statistics.rb +51 -0
- data/lib/karafka/instrumentation/logger_listener.rb +303 -0
- data/lib/karafka/instrumentation/monitor.rb +13 -61
- data/lib/karafka/instrumentation/notifications.rb +79 -0
- data/lib/karafka/instrumentation/proctitle_listener.rb +7 -16
- data/lib/karafka/instrumentation/vendors/appsignal/base.rb +30 -0
- data/lib/karafka/instrumentation/vendors/appsignal/client.rb +122 -0
- data/lib/karafka/instrumentation/vendors/appsignal/dashboard.json +222 -0
- data/lib/karafka/instrumentation/vendors/appsignal/errors_listener.rb +30 -0
- data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +331 -0
- data/lib/karafka/instrumentation/vendors/datadog/dashboard.json +1 -0
- data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +155 -0
- data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +264 -0
- data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +176 -0
- data/lib/karafka/licenser.rb +78 -0
- data/lib/karafka/messages/batch_metadata.rb +52 -0
- data/lib/karafka/messages/builders/batch_metadata.rb +60 -0
- data/lib/karafka/messages/builders/message.rb +40 -0
- data/lib/karafka/messages/builders/messages.rb +36 -0
- data/lib/karafka/{params/params.rb → messages/message.rb} +20 -13
- data/lib/karafka/messages/messages.rb +71 -0
- data/lib/karafka/{params → messages}/metadata.rb +4 -6
- data/lib/karafka/messages/parser.rb +14 -0
- data/lib/karafka/messages/seek.rb +12 -0
- data/lib/karafka/patches/rdkafka/bindings.rb +122 -0
- data/lib/karafka/patches/rdkafka/opaque.rb +36 -0
- data/lib/karafka/pro/active_job/consumer.rb +47 -0
- data/lib/karafka/pro/active_job/dispatcher.rb +86 -0
- data/lib/karafka/pro/active_job/job_options_contract.rb +45 -0
- data/lib/karafka/pro/cleaner/errors.rb +27 -0
- data/lib/karafka/pro/cleaner/messages/message.rb +46 -0
- data/lib/karafka/pro/cleaner/messages/messages.rb +42 -0
- data/lib/karafka/pro/cleaner.rb +41 -0
- data/lib/karafka/pro/contracts/base.rb +23 -0
- data/lib/karafka/pro/contracts/server_cli_options.rb +111 -0
- data/lib/karafka/pro/encryption/cipher.rb +58 -0
- data/lib/karafka/pro/encryption/contracts/config.rb +79 -0
- data/lib/karafka/pro/encryption/errors.rb +27 -0
- data/lib/karafka/pro/encryption/messages/middleware.rb +46 -0
- data/lib/karafka/pro/encryption/messages/parser.rb +56 -0
- data/lib/karafka/pro/encryption/setup/config.rb +48 -0
- data/lib/karafka/pro/encryption.rb +47 -0
- data/lib/karafka/pro/iterator/expander.rb +95 -0
- data/lib/karafka/pro/iterator/tpl_builder.rb +155 -0
- data/lib/karafka/pro/iterator.rb +170 -0
- data/lib/karafka/pro/loader.rb +106 -0
- data/lib/karafka/pro/performance_tracker.rb +84 -0
- data/lib/karafka/pro/processing/collapser.rb +62 -0
- data/lib/karafka/pro/processing/coordinator.rb +147 -0
- data/lib/karafka/pro/processing/filters/base.rb +61 -0
- data/lib/karafka/pro/processing/filters/delayer.rb +70 -0
- data/lib/karafka/pro/processing/filters/expirer.rb +51 -0
- data/lib/karafka/pro/processing/filters/inline_insights_delayer.rb +78 -0
- data/lib/karafka/pro/processing/filters/throttler.rb +84 -0
- data/lib/karafka/pro/processing/filters/virtual_limiter.rb +52 -0
- data/lib/karafka/pro/processing/filters_applier.rb +105 -0
- data/lib/karafka/pro/processing/jobs/consume_non_blocking.rb +39 -0
- data/lib/karafka/pro/processing/jobs/revoked_non_blocking.rb +37 -0
- data/lib/karafka/pro/processing/jobs_builder.rb +50 -0
- data/lib/karafka/pro/processing/partitioner.rb +69 -0
- data/lib/karafka/pro/processing/scheduler.rb +75 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +70 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +76 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +72 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +76 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +66 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +70 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +69 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +66 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom_vp.rb +58 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +37 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +82 -0
- data/lib/karafka/pro/processing/strategies/aj/mom.rb +36 -0
- data/lib/karafka/pro/processing/strategies/aj/mom_vp.rb +52 -0
- data/lib/karafka/pro/processing/strategies/base.rb +26 -0
- data/lib/karafka/pro/processing/strategies/default.rb +105 -0
- data/lib/karafka/pro/processing/strategies/dlq/default.rb +137 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr.rb +61 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +75 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +71 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +43 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +69 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj.rb +64 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +65 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom_vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/dlq/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/ftr/default.rb +111 -0
- data/lib/karafka/pro/processing/strategies/ftr/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/default.rb +85 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +69 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +67 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom.rb +77 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom_vp.rb +38 -0
- data/lib/karafka/pro/processing/strategies/lrj/vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/mom/default.rb +46 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr.rb +53 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/mom/vp.rb +35 -0
- data/lib/karafka/pro/processing/strategies/vp/default.rb +124 -0
- data/lib/karafka/pro/processing/strategies.rb +22 -0
- data/lib/karafka/pro/processing/strategy_selector.rb +84 -0
- data/lib/karafka/pro/processing/virtual_offset_manager.rb +147 -0
- data/lib/karafka/pro/routing/features/active_job/builder.rb +45 -0
- data/lib/karafka/pro/routing/features/active_job.rb +26 -0
- data/lib/karafka/pro/routing/features/base.rb +24 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue/contracts/topic.rb +53 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue.rb +27 -0
- data/lib/karafka/pro/routing/features/delaying/config.rb +27 -0
- data/lib/karafka/pro/routing/features/delaying/contracts/topic.rb +41 -0
- data/lib/karafka/pro/routing/features/delaying/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/delaying.rb +29 -0
- data/lib/karafka/pro/routing/features/expiring/config.rb +27 -0
- data/lib/karafka/pro/routing/features/expiring/contracts/topic.rb +41 -0
- data/lib/karafka/pro/routing/features/expiring/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/expiring.rb +27 -0
- data/lib/karafka/pro/routing/features/filtering/config.rb +40 -0
- data/lib/karafka/pro/routing/features/filtering/contracts/topic.rb +44 -0
- data/lib/karafka/pro/routing/features/filtering/topic.rb +51 -0
- data/lib/karafka/pro/routing/features/filtering.rb +27 -0
- data/lib/karafka/pro/routing/features/inline_insights/config.rb +32 -0
- data/lib/karafka/pro/routing/features/inline_insights/contracts/topic.rb +41 -0
- data/lib/karafka/pro/routing/features/inline_insights/topic.rb +52 -0
- data/lib/karafka/pro/routing/features/inline_insights.rb +26 -0
- data/lib/karafka/pro/routing/features/long_running_job/config.rb +28 -0
- data/lib/karafka/pro/routing/features/long_running_job/contracts/topic.rb +40 -0
- data/lib/karafka/pro/routing/features/long_running_job/topic.rb +42 -0
- data/lib/karafka/pro/routing/features/long_running_job.rb +28 -0
- data/lib/karafka/pro/routing/features/patterns/builder.rb +38 -0
- data/lib/karafka/pro/routing/features/patterns/config.rb +54 -0
- data/lib/karafka/pro/routing/features/patterns/consumer_group.rb +72 -0
- data/lib/karafka/pro/routing/features/patterns/contracts/consumer_group.rb +62 -0
- data/lib/karafka/pro/routing/features/patterns/contracts/pattern.rb +46 -0
- data/lib/karafka/pro/routing/features/patterns/contracts/topic.rb +41 -0
- data/lib/karafka/pro/routing/features/patterns/detector.rb +71 -0
- data/lib/karafka/pro/routing/features/patterns/pattern.rb +95 -0
- data/lib/karafka/pro/routing/features/patterns/patterns.rb +35 -0
- data/lib/karafka/pro/routing/features/patterns/topic.rb +50 -0
- data/lib/karafka/pro/routing/features/patterns/topics.rb +53 -0
- data/lib/karafka/pro/routing/features/patterns.rb +33 -0
- data/lib/karafka/pro/routing/features/pausing/contracts/topic.rb +51 -0
- data/lib/karafka/pro/routing/features/pausing/topic.rb +44 -0
- data/lib/karafka/pro/routing/features/pausing.rb +25 -0
- data/lib/karafka/pro/routing/features/throttling/config.rb +32 -0
- data/lib/karafka/pro/routing/features/throttling/contracts/topic.rb +44 -0
- data/lib/karafka/pro/routing/features/throttling/topic.rb +69 -0
- data/lib/karafka/pro/routing/features/throttling.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +55 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +56 -0
- data/lib/karafka/pro/routing/features/virtual_partitions.rb +27 -0
- data/lib/karafka/pro.rb +13 -0
- data/lib/karafka/process.rb +24 -8
- data/lib/karafka/processing/coordinator.rb +181 -0
- data/lib/karafka/processing/coordinators_buffer.rb +62 -0
- data/lib/karafka/processing/executor.rb +155 -0
- data/lib/karafka/processing/executors_buffer.rb +72 -0
- data/lib/karafka/processing/expansions_selector.rb +22 -0
- data/lib/karafka/processing/inline_insights/consumer.rb +41 -0
- data/lib/karafka/processing/inline_insights/listener.rb +19 -0
- data/lib/karafka/processing/inline_insights/tracker.rb +128 -0
- data/lib/karafka/processing/jobs/base.rb +55 -0
- data/lib/karafka/processing/jobs/consume.rb +45 -0
- data/lib/karafka/processing/jobs/idle.rb +24 -0
- data/lib/karafka/processing/jobs/revoked.rb +22 -0
- data/lib/karafka/processing/jobs/shutdown.rb +23 -0
- data/lib/karafka/processing/jobs_builder.rb +28 -0
- data/lib/karafka/processing/jobs_queue.rb +150 -0
- data/lib/karafka/processing/partitioner.rb +24 -0
- data/lib/karafka/processing/result.rb +42 -0
- data/lib/karafka/processing/scheduler.rb +22 -0
- data/lib/karafka/processing/strategies/aj_dlq_mom.rb +44 -0
- data/lib/karafka/processing/strategies/aj_mom.rb +21 -0
- data/lib/karafka/processing/strategies/base.rb +52 -0
- data/lib/karafka/processing/strategies/default.rb +158 -0
- data/lib/karafka/processing/strategies/dlq.rb +88 -0
- data/lib/karafka/processing/strategies/dlq_mom.rb +49 -0
- data/lib/karafka/processing/strategies/mom.rb +29 -0
- data/lib/karafka/processing/strategy_selector.rb +47 -0
- data/lib/karafka/processing/worker.rb +93 -0
- data/lib/karafka/processing/workers_batch.rb +27 -0
- data/lib/karafka/railtie.rb +141 -0
- data/lib/karafka/routing/activity_manager.rb +84 -0
- data/lib/karafka/routing/builder.rb +45 -19
- data/lib/karafka/routing/consumer_group.rb +56 -20
- data/lib/karafka/routing/consumer_mapper.rb +1 -12
- data/lib/karafka/routing/features/active_job/builder.rb +33 -0
- data/lib/karafka/routing/features/active_job/config.rb +15 -0
- data/lib/karafka/routing/features/active_job/contracts/topic.rb +44 -0
- data/lib/karafka/routing/features/active_job/proxy.rb +14 -0
- data/lib/karafka/routing/features/active_job/topic.rb +33 -0
- data/lib/karafka/routing/features/active_job.rb +13 -0
- data/lib/karafka/routing/features/base/expander.rb +59 -0
- data/lib/karafka/routing/features/base.rb +71 -0
- data/lib/karafka/routing/features/dead_letter_queue/config.rb +19 -0
- data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +46 -0
- data/lib/karafka/routing/features/dead_letter_queue/topic.rb +41 -0
- data/lib/karafka/routing/features/dead_letter_queue.rb +16 -0
- data/lib/karafka/routing/features/declaratives/config.rb +18 -0
- data/lib/karafka/routing/features/declaratives/contracts/topic.rb +33 -0
- data/lib/karafka/routing/features/declaratives/topic.rb +44 -0
- data/lib/karafka/routing/features/declaratives.rb +14 -0
- data/lib/karafka/routing/features/inline_insights/config.rb +15 -0
- data/lib/karafka/routing/features/inline_insights/contracts/topic.rb +27 -0
- data/lib/karafka/routing/features/inline_insights/topic.rb +31 -0
- data/lib/karafka/routing/features/inline_insights.rb +40 -0
- data/lib/karafka/routing/features/manual_offset_management/config.rb +15 -0
- data/lib/karafka/routing/features/manual_offset_management/contracts/topic.rb +27 -0
- data/lib/karafka/routing/features/manual_offset_management/topic.rb +35 -0
- data/lib/karafka/routing/features/manual_offset_management.rb +18 -0
- data/lib/karafka/routing/proxy.rb +22 -21
- data/lib/karafka/routing/router.rb +24 -10
- data/lib/karafka/routing/subscription_group.rb +110 -0
- data/lib/karafka/routing/subscription_groups_builder.rb +65 -0
- data/lib/karafka/routing/topic.rb +87 -24
- data/lib/karafka/routing/topics.rb +46 -0
- data/lib/karafka/runner.rb +52 -0
- data/lib/karafka/serialization/json/deserializer.rb +7 -15
- data/lib/karafka/server.rb +113 -37
- data/lib/karafka/setup/attributes_map.rb +348 -0
- data/lib/karafka/setup/config.rb +256 -175
- data/lib/karafka/status.rb +54 -7
- data/lib/karafka/templates/example_consumer.rb.erb +16 -0
- data/lib/karafka/templates/karafka.rb.erb +33 -55
- data/lib/karafka/time_trackers/base.rb +14 -0
- data/lib/karafka/time_trackers/pause.rb +122 -0
- data/lib/karafka/time_trackers/poll.rb +69 -0
- data/lib/karafka/version.rb +1 -1
- data/lib/karafka.rb +91 -17
- data/renovate.json +9 -0
- data.tar.gz.sig +0 -0
- metadata +330 -168
- metadata.gz.sig +0 -0
- data/MIT-LICENCE +0 -18
- data/certs/mensfeld.pem +0 -25
- data/config/errors.yml +0 -41
- data/lib/karafka/assignment_strategies/round_robin.rb +0 -13
- data/lib/karafka/attributes_map.rb +0 -63
- data/lib/karafka/backends/inline.rb +0 -16
- data/lib/karafka/base_responder.rb +0 -226
- data/lib/karafka/cli/flow.rb +0 -48
- data/lib/karafka/cli/missingno.rb +0 -19
- data/lib/karafka/code_reloader.rb +0 -67
- data/lib/karafka/connection/api_adapter.rb +0 -158
- data/lib/karafka/connection/batch_delegator.rb +0 -55
- data/lib/karafka/connection/builder.rb +0 -23
- data/lib/karafka/connection/message_delegator.rb +0 -36
- data/lib/karafka/consumers/batch_metadata.rb +0 -10
- data/lib/karafka/consumers/callbacks.rb +0 -71
- data/lib/karafka/consumers/includer.rb +0 -64
- data/lib/karafka/consumers/responders.rb +0 -24
- data/lib/karafka/consumers/single_params.rb +0 -15
- data/lib/karafka/contracts/consumer_group_topic.rb +0 -19
- data/lib/karafka/contracts/responder_usage.rb +0 -54
- data/lib/karafka/fetcher.rb +0 -42
- data/lib/karafka/helpers/class_matcher.rb +0 -88
- data/lib/karafka/helpers/config_retriever.rb +0 -46
- data/lib/karafka/helpers/inflector.rb +0 -26
- data/lib/karafka/instrumentation/stdout_listener.rb +0 -140
- data/lib/karafka/params/batch_metadata.rb +0 -26
- data/lib/karafka/params/builders/batch_metadata.rb +0 -30
- data/lib/karafka/params/builders/params.rb +0 -38
- data/lib/karafka/params/builders/params_batch.rb +0 -25
- data/lib/karafka/params/params_batch.rb +0 -60
- data/lib/karafka/patches/ruby_kafka.rb +0 -47
- data/lib/karafka/persistence/client.rb +0 -29
- data/lib/karafka/persistence/consumers.rb +0 -45
- data/lib/karafka/persistence/topics.rb +0 -48
- data/lib/karafka/responders/builder.rb +0 -36
- data/lib/karafka/responders/topic.rb +0 -55
- data/lib/karafka/routing/topic_mapper.rb +0 -53
- data/lib/karafka/serialization/json/serializer.rb +0 -31
- data/lib/karafka/setup/configurators/water_drop.rb +0 -36
- data/lib/karafka/templates/application_responder.rb.erb +0 -11
@@ -0,0 +1,303 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Instrumentation
|
5
|
+
# Default listener that hooks up to our instrumentation and uses its events for logging
|
6
|
+
# It can be removed/replaced or anything without any harm to the Karafka app flow.
|
7
|
+
class LoggerListener
|
8
|
+
# Log levels that we use in this particular listener
|
9
|
+
USED_LOG_LEVELS = %i[
|
10
|
+
debug
|
11
|
+
info
|
12
|
+
warn
|
13
|
+
error
|
14
|
+
fatal
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
private_constant :USED_LOG_LEVELS
|
18
|
+
|
19
|
+
# Logs each messages fetching attempt
|
20
|
+
#
|
21
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
22
|
+
def on_connection_listener_fetch_loop(event)
|
23
|
+
listener = event[:caller]
|
24
|
+
debug "[#{listener.id}] Polling messages..."
|
25
|
+
end
|
26
|
+
|
27
|
+
# Logs about messages that we've received from Kafka
|
28
|
+
#
|
29
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
30
|
+
def on_connection_listener_fetch_loop_received(event)
|
31
|
+
listener = event[:caller]
|
32
|
+
time = event[:time]
|
33
|
+
messages_count = event[:messages_buffer].size
|
34
|
+
|
35
|
+
message = "[#{listener.id}] Polled #{messages_count} messages in #{time}ms"
|
36
|
+
|
37
|
+
# We don't want the "polled 0" in dev as it would spam the log
|
38
|
+
# Instead we publish only info when there was anything we could poll and fail over to the
|
39
|
+
# zero notifications when in debug mode
|
40
|
+
messages_count.zero? ? debug(message) : info(message)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Prints info about the fact that a given job has started
|
44
|
+
#
|
45
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
46
|
+
def on_worker_process(event)
|
47
|
+
job = event[:job]
|
48
|
+
job_type = job.class.to_s.split('::').last
|
49
|
+
consumer = job.executor.topic.consumer
|
50
|
+
topic = job.executor.topic.name
|
51
|
+
partition = job.executor.partition
|
52
|
+
info "[#{job.id}] #{job_type} job for #{consumer} on #{topic}/#{partition} started"
|
53
|
+
end
|
54
|
+
|
55
|
+
# Prints info about the fact that a given job has finished
|
56
|
+
#
|
57
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
58
|
+
def on_worker_processed(event)
|
59
|
+
job = event[:job]
|
60
|
+
time = event[:time]
|
61
|
+
job_type = job.class.to_s.split('::').last
|
62
|
+
consumer = job.executor.topic.consumer
|
63
|
+
topic = job.executor.topic.name
|
64
|
+
partition = job.executor.partition
|
65
|
+
info <<~MSG.tr("\n", ' ').strip!
|
66
|
+
[#{job.id}] #{job_type} job for #{consumer}
|
67
|
+
on #{topic}/#{partition} finished in #{time}ms
|
68
|
+
MSG
|
69
|
+
end
|
70
|
+
|
71
|
+
# Prints info about a consumer pause occurrence. Irrelevant if user or system initiated.
|
72
|
+
#
|
73
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
74
|
+
# @note There may be no offset provided in case user wants to pause on the consecutive offset
|
75
|
+
# position. This can be beneficial when not wanting to purge the buffers.
|
76
|
+
def on_client_pause(event)
|
77
|
+
topic = event[:topic]
|
78
|
+
partition = event[:partition]
|
79
|
+
offset = event[:offset]
|
80
|
+
client = event[:caller]
|
81
|
+
|
82
|
+
info <<~MSG.tr("\n", ' ').strip!
|
83
|
+
[#{client.id}]
|
84
|
+
Pausing on topic #{topic}/#{partition}
|
85
|
+
on #{offset ? "offset #{offset}" : 'the consecutive offset'}
|
86
|
+
MSG
|
87
|
+
end
|
88
|
+
|
89
|
+
# Prints information about resuming of processing of a given topic partition
|
90
|
+
#
|
91
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
92
|
+
def on_client_resume(event)
|
93
|
+
topic = event[:topic]
|
94
|
+
partition = event[:partition]
|
95
|
+
client = event[:caller]
|
96
|
+
|
97
|
+
info <<~MSG.tr("\n", ' ').strip!
|
98
|
+
[#{client.id}] Resuming on topic #{topic}/#{partition}
|
99
|
+
MSG
|
100
|
+
end
|
101
|
+
|
102
|
+
# Prints info about retry of processing after an error
|
103
|
+
#
|
104
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
105
|
+
def on_consumer_consuming_retry(event)
|
106
|
+
topic = event[:topic]
|
107
|
+
partition = event[:partition]
|
108
|
+
offset = event[:offset]
|
109
|
+
consumer = event[:caller]
|
110
|
+
timeout = event[:timeout]
|
111
|
+
|
112
|
+
info <<~MSG.tr("\n", ' ').strip!
|
113
|
+
[#{consumer.id}] Retrying of #{consumer.class} after #{timeout} ms
|
114
|
+
on topic #{topic}/#{partition} from offset #{offset}
|
115
|
+
MSG
|
116
|
+
end
|
117
|
+
|
118
|
+
# Logs info about system signals that Karafka received and prints backtrace for threads in
|
119
|
+
# case of ttin
|
120
|
+
#
|
121
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
122
|
+
def on_process_notice_signal(event)
|
123
|
+
info "Received #{event[:signal]} system signal"
|
124
|
+
|
125
|
+
# We print backtrace only for ttin
|
126
|
+
return unless event[:signal] == :SIGTTIN
|
127
|
+
|
128
|
+
# Inspired by Sidekiq
|
129
|
+
Thread.list.each do |thread|
|
130
|
+
tid = (thread.object_id ^ ::Process.pid).to_s(36)
|
131
|
+
|
132
|
+
warn "Thread TID-#{tid} #{thread['label']}"
|
133
|
+
|
134
|
+
if thread.backtrace
|
135
|
+
warn thread.backtrace.join("\n")
|
136
|
+
else
|
137
|
+
warn '<no backtrace available>'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Logs info that we're running Karafka app.
|
143
|
+
#
|
144
|
+
# @param _event [Karafka::Core::Monitoring::Event] event details including payload
|
145
|
+
def on_app_running(_event)
|
146
|
+
info "Running in #{RUBY_DESCRIPTION}"
|
147
|
+
info "Running Karafka #{Karafka::VERSION} server"
|
148
|
+
|
149
|
+
return if Karafka.pro?
|
150
|
+
|
151
|
+
info 'See LICENSE and the LGPL-3.0 for licensing details'
|
152
|
+
end
|
153
|
+
|
154
|
+
# @param _event [Karafka::Core::Monitoring::Event] event details including payload
|
155
|
+
def on_app_quieting(_event)
|
156
|
+
info 'Switching to quiet mode. New messages will not be processed'
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param _event [Karafka::Core::Monitoring::Event] event details including payload
|
160
|
+
def on_app_quiet(_event)
|
161
|
+
info 'Reached quiet mode. No messages will be processed anymore'
|
162
|
+
end
|
163
|
+
|
164
|
+
# Logs info that we're going to stop the Karafka server.
|
165
|
+
#
|
166
|
+
# @param _event [Karafka::Core::Monitoring::Event] event details including payload
|
167
|
+
def on_app_stopping(_event)
|
168
|
+
info 'Stopping Karafka server'
|
169
|
+
end
|
170
|
+
|
171
|
+
# Logs info that we stopped the Karafka server.
|
172
|
+
#
|
173
|
+
# @param _event [Karafka::Core::Monitoring::Event] event details including payload
|
174
|
+
def on_app_stopped(_event)
|
175
|
+
info 'Stopped Karafka server'
|
176
|
+
end
|
177
|
+
|
178
|
+
# Logs info when we have dispatched a message the the DLQ
|
179
|
+
#
|
180
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
181
|
+
def on_dead_letter_queue_dispatched(event)
|
182
|
+
consumer = event[:caller]
|
183
|
+
topic = consumer.topic.name
|
184
|
+
message = event[:message]
|
185
|
+
offset = message.offset
|
186
|
+
dlq_topic = consumer.topic.dead_letter_queue.topic
|
187
|
+
partition = message.partition
|
188
|
+
|
189
|
+
info <<~MSG.tr("\n", ' ').strip!
|
190
|
+
[#{consumer.id}] Dispatched message #{offset}
|
191
|
+
from #{topic}/#{partition}
|
192
|
+
to DLQ topic: #{dlq_topic}
|
193
|
+
MSG
|
194
|
+
end
|
195
|
+
|
196
|
+
# Logs info about throttling event
|
197
|
+
#
|
198
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
199
|
+
def on_filtering_throttled(event)
|
200
|
+
consumer = event[:caller]
|
201
|
+
topic = consumer.topic.name
|
202
|
+
# Here we get last message before throttle
|
203
|
+
message = event[:message]
|
204
|
+
partition = message.partition
|
205
|
+
offset = message.offset
|
206
|
+
|
207
|
+
info <<~MSG.tr("\n", ' ').strip!
|
208
|
+
[#{consumer.id}] Throttled and will resume
|
209
|
+
from message #{offset}
|
210
|
+
on #{topic}/#{partition}
|
211
|
+
MSG
|
212
|
+
end
|
213
|
+
|
214
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
215
|
+
def on_filtering_seek(event)
|
216
|
+
consumer = event[:caller]
|
217
|
+
topic = consumer.topic.name
|
218
|
+
# Message to which we seek
|
219
|
+
message = event[:message]
|
220
|
+
partition = message.partition
|
221
|
+
offset = message.offset
|
222
|
+
|
223
|
+
info <<~MSG.tr("\n", ' ').strip!
|
224
|
+
[#{consumer.id}] Post-filtering seeking to message #{offset}
|
225
|
+
on #{topic}/#{partition}
|
226
|
+
MSG
|
227
|
+
end
|
228
|
+
|
229
|
+
# There are many types of errors that can occur in many places, but we provide a single
|
230
|
+
# handler for all of them to simplify error instrumentation.
|
231
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
232
|
+
def on_error_occurred(event)
|
233
|
+
type = event[:type]
|
234
|
+
error = event[:error]
|
235
|
+
details = (error.backtrace || []).join("\n")
|
236
|
+
|
237
|
+
case type
|
238
|
+
when 'consumer.consume.error'
|
239
|
+
error "Consumer consuming error: #{error}"
|
240
|
+
error details
|
241
|
+
when 'consumer.revoked.error'
|
242
|
+
error "Consumer on revoked failed due to an error: #{error}"
|
243
|
+
error details
|
244
|
+
when 'consumer.before_enqueue.error'
|
245
|
+
error "Consumer before enqueue failed due to an error: #{error}"
|
246
|
+
error details
|
247
|
+
when 'consumer.before_consume.error'
|
248
|
+
error "Consumer before consume failed due to an error: #{error}"
|
249
|
+
error details
|
250
|
+
when 'consumer.after_consume.error'
|
251
|
+
error "Consumer after consume failed due to an error: #{error}"
|
252
|
+
error details
|
253
|
+
when 'consumer.idle.error'
|
254
|
+
error "Consumer idle failed due to an error: #{error}"
|
255
|
+
error details
|
256
|
+
when 'consumer.shutdown.error'
|
257
|
+
error "Consumer on shutdown failed due to an error: #{error}"
|
258
|
+
error details
|
259
|
+
when 'worker.process.error'
|
260
|
+
fatal "Worker processing failed due to an error: #{error}"
|
261
|
+
fatal details
|
262
|
+
when 'connection.listener.fetch_loop.error'
|
263
|
+
error "Listener fetch loop error: #{error}"
|
264
|
+
error details
|
265
|
+
when 'runner.call.error'
|
266
|
+
fatal "Runner crashed due to an error: #{error}"
|
267
|
+
fatal details
|
268
|
+
when 'app.stopping.error'
|
269
|
+
error 'Forceful Karafka server stop'
|
270
|
+
when 'librdkafka.error'
|
271
|
+
error "librdkafka internal error occurred: #{error}"
|
272
|
+
error details
|
273
|
+
# Those can occur when emitted statistics are consumed by the end user and the processing
|
274
|
+
# of statistics fails. The statistics are emitted from librdkafka main loop thread and
|
275
|
+
# any errors there crash the whole thread
|
276
|
+
when 'statistics.emitted.error'
|
277
|
+
error "statistics.emitted processing failed due to an error: #{error}"
|
278
|
+
error details
|
279
|
+
# Those will only occur when retries in the client fail and when they did not stop after
|
280
|
+
# back-offs
|
281
|
+
when 'connection.client.poll.error'
|
282
|
+
error "Data polling error occurred: #{error}"
|
283
|
+
error details
|
284
|
+
when 'connection.client.rebalance_callback.error'
|
285
|
+
error "Rebalance callback error occurred: #{error}"
|
286
|
+
error details
|
287
|
+
when 'connection.client.unsubscribe.error'
|
288
|
+
error "Client unsubscribe error occurred: #{error}"
|
289
|
+
error details
|
290
|
+
else
|
291
|
+
# This should never happen. Please contact the maintainers
|
292
|
+
raise Errors::UnsupportedCaseError, event
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
USED_LOG_LEVELS.each do |log_level|
|
297
|
+
define_method log_level do |*args|
|
298
|
+
Karafka.logger.send(log_level, *args)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
@@ -1,69 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Karafka
|
4
|
-
# Namespace for all the things related with Karafka instrumentation process
|
5
4
|
module Instrumentation
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
# @note This class acts as a singleton because we are only permitted to have single monitor
|
12
|
-
# per running process (just as logger)
|
13
|
-
class Monitor < Dry::Monitor::Notifications
|
14
|
-
# List of events that we support in the system and to which a monitor client can hook up
|
15
|
-
# @note The non-error once support timestamp benchmarking
|
16
|
-
# @note Depending on Karafka extensions and additional engines, this might not be the
|
17
|
-
# complete list of all the events. Please use the #available_events on fully loaded
|
18
|
-
# Karafka system to determine all of the events you can use.
|
19
|
-
# Last 4 events are from WaterDrop but for convenience we use the same monitor for the
|
20
|
-
# whole karafka ecosystem
|
21
|
-
BASE_EVENTS = %w[
|
22
|
-
params.params.deserialize
|
23
|
-
params.params.deserialize.error
|
24
|
-
connection.listener.before_fetch_loop
|
25
|
-
connection.listener.fetch_loop
|
26
|
-
connection.listener.fetch_loop.error
|
27
|
-
connection.client.fetch_loop.error
|
28
|
-
connection.batch_delegator.call
|
29
|
-
connection.message_delegator.call
|
30
|
-
fetcher.call.error
|
31
|
-
backends.inline.process
|
32
|
-
process.notice_signal
|
33
|
-
consumers.responders.respond_with
|
34
|
-
async_producer.call.error
|
35
|
-
async_producer.call.retry
|
36
|
-
sync_producer.call.error
|
37
|
-
sync_producer.call.retry
|
38
|
-
app.initializing
|
39
|
-
app.initialized
|
40
|
-
app.running
|
41
|
-
app.stopping
|
42
|
-
app.stopping.error
|
43
|
-
app.stopped
|
44
|
-
].freeze
|
5
|
+
# Karafka instrumentation monitor that we use to publish events
|
6
|
+
# By default uses our internal notifications bus but can be used with
|
7
|
+
# `ActiveSupport::Notifications` as well
|
8
|
+
class Monitor < ::Karafka::Core::Monitoring::Monitor
|
9
|
+
attr_reader :notifications_bus
|
45
10
|
|
46
|
-
|
47
|
-
|
48
|
-
# @
|
49
|
-
def initialize
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
# Allows us to subscribe to events with a code that will be yielded upon events
|
55
|
-
# @param event_name_or_listener [String, Object] name of the event we want to subscribe to
|
56
|
-
# or a listener if we decide to go with object listener
|
57
|
-
def subscribe(event_name_or_listener)
|
58
|
-
return super unless event_name_or_listener.is_a?(String)
|
59
|
-
return super if available_events.include?(event_name_or_listener)
|
60
|
-
|
61
|
-
raise Errors::UnregisteredMonitorEventError, event_name_or_listener
|
62
|
-
end
|
63
|
-
|
64
|
-
# @return [Array<String>] names of available events to which we can subscribe
|
65
|
-
def available_events
|
66
|
-
__bus__.events.keys
|
11
|
+
# @param notifications_bus [Object] either our internal notifications bus or
|
12
|
+
# `ActiveSupport::Notifications`
|
13
|
+
# @param namespace [String, nil] namespace for events or nil if no namespace
|
14
|
+
def initialize(
|
15
|
+
notifications_bus = ::Karafka::Instrumentation::Notifications.new,
|
16
|
+
namespace = nil
|
17
|
+
)
|
18
|
+
super(notifications_bus, namespace)
|
67
19
|
end
|
68
20
|
end
|
69
21
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
# Namespace for all the things related with Karafka instrumentation process
|
5
|
+
module Instrumentation
|
6
|
+
# Monitor is used to hookup external monitoring services to monitor how Karafka works
|
7
|
+
# It provides a standardized API for checking incoming messages/enqueueing etc
|
8
|
+
# Since it is a pub-sub based on dry-monitor, you can use as many subscribers/loggers at the
|
9
|
+
# same time, which means that you might have for example file logging and NewRelic at the same
|
10
|
+
# time
|
11
|
+
# @note This class acts as a singleton because we are only permitted to have single monitor
|
12
|
+
# per running process (just as logger)
|
13
|
+
class Notifications < Karafka::Core::Monitoring::Notifications
|
14
|
+
# List of events that we support in the system and to which a monitor client can hook up
|
15
|
+
# @note The non-error once support timestamp benchmarking
|
16
|
+
# @note Depending on Karafka extensions and additional engines, this might not be the
|
17
|
+
# complete list of all the events. Please use the #available_events on fully loaded
|
18
|
+
# Karafka system to determine all of the events you can use.
|
19
|
+
EVENTS = %w[
|
20
|
+
active_job.consume
|
21
|
+
active_job.consumed
|
22
|
+
|
23
|
+
app.initialized
|
24
|
+
app.running
|
25
|
+
app.quieting
|
26
|
+
app.quiet
|
27
|
+
app.stopping
|
28
|
+
app.stopped
|
29
|
+
app.terminated
|
30
|
+
|
31
|
+
client.pause
|
32
|
+
client.resume
|
33
|
+
|
34
|
+
connection.listener.before_fetch_loop
|
35
|
+
connection.listener.fetch_loop
|
36
|
+
connection.listener.fetch_loop.received
|
37
|
+
|
38
|
+
connection.client.poll.error
|
39
|
+
connection.client.unsubscribe.error
|
40
|
+
|
41
|
+
rebalance.partitions_assign
|
42
|
+
rebalance.partitions_assigned
|
43
|
+
rebalance.partitions_revoke
|
44
|
+
rebalance.partitions_revoked
|
45
|
+
|
46
|
+
consumer.consume
|
47
|
+
consumer.consumed
|
48
|
+
consumer.consuming.pause
|
49
|
+
consumer.consuming.retry
|
50
|
+
consumer.idle
|
51
|
+
consumer.revoke
|
52
|
+
consumer.revoked
|
53
|
+
consumer.shutting_down
|
54
|
+
consumer.shutdown
|
55
|
+
|
56
|
+
dead_letter_queue.dispatched
|
57
|
+
|
58
|
+
filtering.throttled
|
59
|
+
filtering.seek
|
60
|
+
|
61
|
+
process.notice_signal
|
62
|
+
|
63
|
+
statistics.emitted
|
64
|
+
|
65
|
+
worker.process
|
66
|
+
worker.processed
|
67
|
+
worker.completed
|
68
|
+
|
69
|
+
error.occurred
|
70
|
+
].freeze
|
71
|
+
|
72
|
+
# @return [Karafka::Instrumentation::Monitor] monitor instance for system instrumentation
|
73
|
+
def initialize
|
74
|
+
super
|
75
|
+
EVENTS.each { |event| register_event(event) }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -4,22 +4,13 @@ module Karafka
|
|
4
4
|
module Instrumentation
|
5
5
|
# Listener that sets a proc title with a nice descriptive value
|
6
6
|
class ProctitleListener
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# @param _event [Dry::Events::Event] event details including payload
|
15
|
-
def on_app_running(_event)
|
16
|
-
setproctitle('running')
|
17
|
-
end
|
18
|
-
|
19
|
-
# Updates proc title to a stopping one
|
20
|
-
# @param _event [Dry::Events::Event] event details including payload
|
21
|
-
def on_app_stopping(_event)
|
22
|
-
setproctitle('stopping')
|
7
|
+
Status::STATES.each_key do |state|
|
8
|
+
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
9
|
+
# Updates proc title to an appropriate state
|
10
|
+
def on_app_#{state}(_event)
|
11
|
+
setproctitle('#{state}')
|
12
|
+
end
|
13
|
+
RUBY
|
23
14
|
end
|
24
15
|
|
25
16
|
private
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'client'
|
4
|
+
|
5
|
+
module Karafka
|
6
|
+
module Instrumentation
|
7
|
+
module Vendors
|
8
|
+
# Namespace for Appsignal instrumentation
|
9
|
+
module Appsignal
|
10
|
+
# Base for all the instrumentation listeners
|
11
|
+
class Base
|
12
|
+
include ::Karafka::Core::Configurable
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
# @param block [Proc] configuration block
|
16
|
+
def initialize(&block)
|
17
|
+
configure
|
18
|
+
setup(&block) if block
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param block [Proc] configuration block
|
22
|
+
# @note We define this alias to be consistent with `Karafka#setup`
|
23
|
+
def setup(&block)
|
24
|
+
configure(&block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
module Instrumentation
|
5
|
+
module Vendors
|
6
|
+
module Appsignal
|
7
|
+
# Appsignal client wrapper
|
8
|
+
# We wrap the native client so we can inject our own stub in specs when needed
|
9
|
+
#
|
10
|
+
# It also abstracts away the notion of transactions and their management
|
11
|
+
#
|
12
|
+
# @note This client is abstract, it has no notion of Karafka whatsoever
|
13
|
+
class Client
|
14
|
+
# Starts an appsignal transaction with a given action name
|
15
|
+
#
|
16
|
+
# @param action_name [String] action name. For processing this should be equal to
|
17
|
+
# consumer class + method name
|
18
|
+
def start_transaction(action_name)
|
19
|
+
transaction = ::Appsignal::Transaction.create(
|
20
|
+
SecureRandom.uuid,
|
21
|
+
::Appsignal::Transaction::BACKGROUND_JOB,
|
22
|
+
::Appsignal::Transaction::GenericRequest.new({})
|
23
|
+
)
|
24
|
+
|
25
|
+
transaction.set_action_if_nil(action_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Stops the current transaction (if any)
|
29
|
+
def stop_transaction
|
30
|
+
return unless transaction?
|
31
|
+
|
32
|
+
::Appsignal::Transaction.complete_current!
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sets metadata on a current transaction (if any)
|
36
|
+
#
|
37
|
+
# @param metadata_hash [Hash] hash with metadata we want to set
|
38
|
+
def metadata=(metadata_hash)
|
39
|
+
return unless transaction?
|
40
|
+
|
41
|
+
transaction = ::Appsignal::Transaction.current
|
42
|
+
|
43
|
+
stringify_hash(metadata_hash).each do |key, value|
|
44
|
+
transaction.set_metadata(key, value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Increments counter with the given value and tags
|
49
|
+
#
|
50
|
+
# @param key [String] key we want to use
|
51
|
+
# @param value [Integer] increment value
|
52
|
+
# @param tags [Hash] additional extra tags
|
53
|
+
def count(key, value, tags)
|
54
|
+
::Appsignal.increment_counter(
|
55
|
+
key,
|
56
|
+
value,
|
57
|
+
stringify_hash(tags)
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Sets gauge with the given value and tags
|
62
|
+
#
|
63
|
+
# @param key [String] key we want to use
|
64
|
+
# @param value [Integer] gauge value
|
65
|
+
# @param tags [Hash] additional extra tags
|
66
|
+
def gauge(key, value, tags)
|
67
|
+
::Appsignal.set_gauge(
|
68
|
+
key,
|
69
|
+
value,
|
70
|
+
stringify_hash(tags)
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Sends the error that occurred to Appsignal
|
75
|
+
#
|
76
|
+
# @param error [Object] error we want to ship to Appsignal
|
77
|
+
def send_error(error)
|
78
|
+
# If we have an active transaction we should use it instead of creating a generic one
|
79
|
+
# That way proper namespace and other data may be transferred
|
80
|
+
#
|
81
|
+
# In case there is no transaction, a new generic background job one will be used
|
82
|
+
if transaction?
|
83
|
+
transaction.set_error(error)
|
84
|
+
else
|
85
|
+
::Appsignal.send_error(error) do |transaction|
|
86
|
+
transaction.set_namespace(::Appsignal::Transaction::BACKGROUND_JOB)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Registers the probe under a given name
|
92
|
+
# @param name [Symbol] probe name
|
93
|
+
# @param probe [Proc] code to run every minute
|
94
|
+
def register_probe(name, probe)
|
95
|
+
::Appsignal::Minutely.probes.register(name, probe)
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
# @return [Boolean] do we have a transaction
|
101
|
+
def transaction?
|
102
|
+
::Appsignal::Transaction.current?
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [::Appsignal::Transaction, nil] transaction or nil if not started
|
106
|
+
def transaction
|
107
|
+
::Appsignal::Transaction.current
|
108
|
+
end
|
109
|
+
|
110
|
+
# Converts both keys and values of a hash into strings
|
111
|
+
# @param hash [Hash]
|
112
|
+
# @return [Hash]
|
113
|
+
def stringify_hash(hash)
|
114
|
+
hash
|
115
|
+
.transform_values(&:to_s)
|
116
|
+
.transform_keys!(&:to_s)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|