From 9b9151833f640eb461bfdf82e13a930c0f9c77a3 Mon Sep 17 00:00:00 2001 From: Nasar Khan Date: Tue, 10 Dec 2024 16:34:06 -0500 Subject: [PATCH] refactor metrics capture to its own mixin --- .../container_manager/metrics_capture.rb | 123 +---------------- .../metrics_capture_mixin.rb | 126 ++++++++++++++++++ 2 files changed, 127 insertions(+), 122 deletions(-) create mode 100644 app/models/manageiq/providers/kubernetes/container_manager/metrics_capture_mixin.rb diff --git a/app/models/manageiq/providers/kubernetes/container_manager/metrics_capture.rb b/app/models/manageiq/providers/kubernetes/container_manager/metrics_capture.rb index c3e50809eb..590e5396ee 100644 --- a/app/models/manageiq/providers/kubernetes/container_manager/metrics_capture.rb +++ b/app/models/manageiq/providers/kubernetes/container_manager/metrics_capture.rb @@ -1,51 +1,6 @@ module ManageIQ::Providers class Kubernetes::ContainerManager::MetricsCapture < ContainerManager::MetricsCapture - class CollectionFailure < RuntimeError; end - class NoMetricsFoundError < RuntimeError; end - - class TargetValidationError < RuntimeError - def log_severity - :error - end - end - - class TargetValidationWarning < RuntimeError - def log_severity - :warn - end - end - - INTERVAL = 60.seconds - - VIM_STYLE_COUNTERS = { - "cpu_usage_rate_average" => { - :counter_key => "cpu_usage_rate_average", - :instance => "", - :capture_interval => INTERVAL.to_s, - :precision => 1, - :rollup => "average", - :unit_key => "percent", - :capture_interval_name => "realtime" - }, - "mem_usage_absolute_average" => { - :counter_key => "mem_usage_absolute_average", - :instance => "", - :capture_interval => INTERVAL.to_s, - :precision => 1, - :rollup => "average", - :unit_key => "percent", - :capture_interval_name => "realtime" - }, - "net_usage_rate_average" => { - :counter_key => "net_usage_rate_average", - :instance => "", - :capture_interval => INTERVAL.to_s, - :precision => 1, - :rollup => "average", - :unit_key => "kilobytespersecond", - :capture_interval_name => "realtime" - } - } + include ManageIQ::Providers::Kubernetes::ContainerManager::MetricsCaptureMixin def capture_ems_targets(_options = {}) begin @@ -57,81 +12,5 @@ def capture_ems_targets(_options = {}) super end - - def prometheus_capture_context(target, start_time, end_time) - PrometheusCaptureContext.new(target, start_time, end_time, INTERVAL) - end - - def metrics_connection(ems) - ems.connection_configurations.prometheus - end - - def metrics_connection_valid?(ems) - metrics_connection(ems)&.authentication&.status == "Valid" - end - - def verify_metrics_connection!(ems) - raise TargetValidationError, "no provider for #{target_name}" if ems.nil? - - raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if metrics_connection(ems).nil? - raise TargetValidationWarning, "metrics authentication isn't valid for #{target_name}" unless metrics_connection_valid?(ems) - end - - def build_capture_context!(ems, target, start_time, end_time) - verify_metrics_connection!(ems) - # make start_time align to minutes - start_time = start_time.beginning_of_minute - - context = prometheus_capture_context(target, start_time, end_time) - raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if context.nil? - - context - end - - def perf_collect_metrics(interval_name, start_time = nil, end_time = nil) - start_time ||= 15.minutes.ago.beginning_of_minute.utc - ems = target.ext_management_system - - _log.info("Collecting metrics for #{target_name} [#{interval_name}] [#{start_time}] [#{end_time}]") - - begin - context = build_capture_context!(ems, target, start_time, end_time) - rescue TargetValidationError, TargetValidationWarning => e - _log.send(e.log_severity, "[#{target_name}] #{e.message}") - ems.try(:update, - :last_metrics_error => :invalid, - :last_metrics_update_date => Time.now.utc) - raise - end - - Benchmark.realtime_block(:collect_data) do - begin - context.collect_metrics - rescue NoMetricsFoundError => e - _log.warn("Metrics missing: [#{target_name}] #{e.message}") - rescue StandardError => e - _log.error("Metrics unavailable: [#{target_name}] #{e.message}") - ems.update(:last_metrics_error => :unavailable, - :last_metrics_update_date => Time.now.utc) if ems - raise - end - end - - ems.update(:last_metrics_error => nil, - :last_metrics_update_date => Time.now.utc, - :last_metrics_success_date => Time.now.utc) if ems - - [{target.ems_ref => VIM_STYLE_COUNTERS}, - {target.ems_ref => context.ts_values}] - end - - private - - def target_name - @target_name ||= begin - t = target || ems - "#{t.class.name.demodulize}(#{t.id})" - end - end end end diff --git a/app/models/manageiq/providers/kubernetes/container_manager/metrics_capture_mixin.rb b/app/models/manageiq/providers/kubernetes/container_manager/metrics_capture_mixin.rb new file mode 100644 index 0000000000..e5b3fbf2dd --- /dev/null +++ b/app/models/manageiq/providers/kubernetes/container_manager/metrics_capture_mixin.rb @@ -0,0 +1,126 @@ +module ManageIQ::Providers::Kubernetes::ContainerManager::MetricsCaptureMixin + class CollectionFailure < RuntimeError; end + class NoMetricsFoundError < RuntimeError; end + + class TargetValidationError < RuntimeError + def log_severity + :error + end + end + + class TargetValidationWarning < RuntimeError + def log_severity + :warn + end + end + + INTERVAL = 60.seconds + + VIM_STYLE_COUNTERS = { + "cpu_usage_rate_average" => { + :counter_key => "cpu_usage_rate_average", + :instance => "", + :capture_interval => INTERVAL.to_s, + :precision => 1, + :rollup => "average", + :unit_key => "percent", + :capture_interval_name => "realtime" + }, + "mem_usage_absolute_average" => { + :counter_key => "mem_usage_absolute_average", + :instance => "", + :capture_interval => INTERVAL.to_s, + :precision => 1, + :rollup => "average", + :unit_key => "percent", + :capture_interval_name => "realtime" + }, + "net_usage_rate_average" => { + :counter_key => "net_usage_rate_average", + :instance => "", + :capture_interval => INTERVAL.to_s, + :precision => 1, + :rollup => "average", + :unit_key => "kilobytespersecond", + :capture_interval_name => "realtime" + } + } + + def prometheus_capture_context(target, start_time, end_time) + PrometheusCaptureContext.new(target, start_time, end_time, INTERVAL) + end + + def metrics_connection(ems) + ems.connection_configurations.prometheus + end + + def metrics_connection_valid?(ems) + metrics_connection(ems)&.authentication&.status == "Valid" + end + + def verify_metrics_connection!(ems) + raise TargetValidationError, "no provider for #{target_name}" if ems.nil? + + raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if metrics_connection(ems).nil? + raise TargetValidationWarning, "metrics authentication isn't valid for #{target_name}" unless metrics_connection_valid?(ems) + end + + def build_capture_context!(ems, target, start_time, end_time) + verify_metrics_connection!(ems) + # make start_time align to minutes + start_time = start_time.beginning_of_minute + + context = prometheus_capture_context(target, start_time, end_time) + raise TargetValidationWarning, "no metrics endpoint found for #{target_name}" if context.nil? + + context + end + + def perf_collect_metrics(interval_name, start_time = nil, end_time = nil) + raise "No EMS defined" if target.ext_management_system.nil? + + start_time ||= 15.minutes.ago.beginning_of_minute.utc + ems = target.ext_management_system + + _log.info("Collecting metrics for #{target_name} [#{interval_name}] [#{start_time}] [#{end_time}]") + + begin + context = build_capture_context!(ems, target, start_time, end_time) + rescue TargetValidationError, TargetValidationWarning => e + _log.send(e.log_severity, "[#{target_name}] #{e.message}") + ems.try(:update, + :last_metrics_error => :invalid, + :last_metrics_update_date => Time.now.utc) + raise + end + + Benchmark.realtime_block(:collect_data) do + begin + context.collect_metrics + rescue NoMetricsFoundError => e + _log.warn("Metrics missing: [#{target_name}] #{e.message}") + rescue StandardError => e + _log.error("Metrics unavailable: [#{target_name}] #{e.message}") + ems.update(:last_metrics_error => :unavailable, + :last_metrics_update_date => Time.now.utc) if ems + raise + end + end + + ems.update(:last_metrics_error => nil, + :last_metrics_update_date => Time.now.utc, + :last_metrics_success_date => Time.now.utc) if ems + + [{target.ems_ref => VIM_STYLE_COUNTERS}, + {target.ems_ref => context.ts_values}] + end + + private + + def target_name + @target_name ||= begin + t = target || ems + "#{t.class.name.demodulize}(#{t.id})" + end + end +end