1# frozen_string_literal: true 2 3module PodLogs 4 class ElasticsearchService < PodLogs::BaseService 5 steps :check_arguments, 6 :get_raw_pods, 7 :get_pod_names, 8 :check_times, 9 :check_search, 10 :check_cursor, 11 :pod_logs, 12 :filter_return_keys 13 14 self.reactive_cache_worker_finder = ->(id, _cache_key, namespace, params) { new(::Clusters::Cluster.find(id), namespace, params: params) } 15 16 private 17 18 def valid_params 19 super + %w(search start_time end_time cursor) 20 end 21 22 def success_return_keys 23 super + %i(cursor) 24 end 25 26 def get_raw_pods(result) 27 client = cluster&.elasticsearch_client 28 return error(_('Unable to connect to Elasticsearch')) unless client 29 30 result[:raw_pods] = ::Gitlab::Elasticsearch::Logs::Pods.new(client).pods(namespace) 31 32 success(result) 33 rescue Elasticsearch::Transport::Transport::ServerError => e 34 ::Gitlab::ErrorTracking.track_exception(e) 35 36 error(_('Elasticsearch returned status code: %{status_code}') % { 37 # ServerError is the parent class of exceptions named after HTTP status codes, eg: "Elasticsearch::Transport::Transport::Errors::NotFound" 38 # there is no method on the exception other than the class name to determine the type of error encountered. 39 status_code: e.class.name.split('::').last 40 }) 41 end 42 43 def check_times(result) 44 result[:start_time] = params['start_time'] if params.key?('start_time') && Time.iso8601(params['start_time']) 45 result[:end_time] = params['end_time'] if params.key?('end_time') && Time.iso8601(params['end_time']) 46 47 success(result) 48 rescue ArgumentError 49 error(_('Invalid start or end time format')) 50 end 51 52 def check_search(result) 53 result[:search] = params['search'] if params.key?('search') 54 55 return error(_('Invalid search parameter')) if result[:search] && !result[:search].is_a?(String) 56 57 success(result) 58 end 59 60 def check_cursor(result) 61 result[:cursor] = params['cursor'] if params.key?('cursor') 62 63 return error(_('Invalid cursor parameter')) if result[:cursor] && !result[:cursor].is_a?(String) 64 65 success(result) 66 end 67 68 def pod_logs(result) 69 client = cluster&.elasticsearch_client 70 return error(_('Unable to connect to Elasticsearch')) unless client 71 72 response = ::Gitlab::Elasticsearch::Logs::Lines.new(client).pod_logs( 73 namespace, 74 pod_name: result[:pod_name], 75 container_name: result[:container_name], 76 search: result[:search], 77 start_time: result[:start_time], 78 end_time: result[:end_time], 79 cursor: result[:cursor], 80 chart_above_v2: cluster.elastic_stack_adapter.chart_above_v2? 81 ) 82 83 result.merge!(response) 84 85 success(result) 86 rescue Elasticsearch::Transport::Transport::ServerError => e 87 ::Gitlab::ErrorTracking.track_exception(e) 88 89 error(_('Elasticsearch returned status code: %{status_code}') % { 90 # ServerError is the parent class of exceptions named after HTTP status codes, eg: "Elasticsearch::Transport::Transport::Errors::NotFound" 91 # there is no method on the exception other than the class name to determine the type of error encountered. 92 status_code: e.class.name.split('::').last 93 }) 94 rescue ::Gitlab::Elasticsearch::Logs::Lines::InvalidCursor 95 error(_('Invalid cursor value provided')) 96 end 97 end 98end 99