diff options
Diffstat (limited to 'lib/gitlab/prometheus_client.rb')
-rw-r--r-- | lib/gitlab/prometheus_client.rb | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/lib/gitlab/prometheus_client.rb b/lib/gitlab/prometheus_client.rb index 45828c77a33..f13156f898e 100644 --- a/lib/gitlab/prometheus_client.rb +++ b/lib/gitlab/prometheus_client.rb @@ -6,6 +6,14 @@ module Gitlab Error = Class.new(StandardError) QueryError = Class.new(Gitlab::PrometheusClient::Error) + # Target number of data points for `query_range`. + # Please don't exceed the limit of 11000 data points + # See https://github.com/prometheus/prometheus/blob/91306bdf24f5395e2601773316945a478b4b263d/web/api/v1/api.go#L347 + QUERY_RANGE_DATA_POINTS = 600 + + # Minimal value of the `step` parameter for `query_range` in seconds. + QUERY_RANGE_MIN_STEP = 60 + attr_reader :rest_client, :headers def initialize(rest_client) @@ -16,6 +24,19 @@ module Gitlab json_api_get('query', query: '1') end + def proxy(type, args) + path = api_path(type) + get(path, args) + rescue RestClient::ExceptionWithResponse => ex + if ex.response + ex.response + else + raise PrometheusClient::Error, "Network connection error" + end + rescue RestClient::Exception + raise PrometheusClient::Error, "Network connection error" + end + def query(query, time: Time.now) get_result('vector') do json_api_get('query', query: query, time: time.to_f) @@ -23,12 +44,18 @@ module Gitlab end def query_range(query, start: 8.hours.ago, stop: Time.now) + start = start.to_f + stop = stop.to_f + step = self.class.compute_step(start, stop) + get_result('matrix') do - json_api_get('query_range', - query: query, - start: start.to_f, - end: stop.to_f, - step: 1.minute.to_i) + json_api_get( + 'query_range', + query: query, + start: start, + end: stop, + step: step + ) end end @@ -40,24 +67,24 @@ module Gitlab json_api_get('series', 'match': matches, start: start.to_f, end: stop.to_f) end + def self.compute_step(start, stop) + diff = stop - start + + step = (diff / QUERY_RANGE_DATA_POINTS).ceil + + [QUERY_RANGE_MIN_STEP, step].max + end + private - def json_api_get(type, args = {}) - path = ['api', 'v1', type].join('/') - get(path, args) - rescue JSON::ParserError - raise PrometheusClient::Error, 'Parsing response failed' - rescue Errno::ECONNREFUSED - raise PrometheusClient::Error, 'Connection refused' + def api_path(type) + ['api', 'v1', type].join('/') end - def get(path, args) - response = rest_client[path].get(params: args) + def json_api_get(type, args = {}) + path = api_path(type) + response = get(path, args) handle_response(response) - rescue SocketError - raise PrometheusClient::Error, "Can't connect to #{rest_client.url}" - rescue OpenSSL::SSL::SSLError - raise PrometheusClient::Error, "#{rest_client.url} contains invalid SSL data" rescue RestClient::ExceptionWithResponse => ex if ex.response handle_exception_response(ex.response) @@ -68,8 +95,18 @@ module Gitlab raise PrometheusClient::Error, "Network connection error" end + def get(path, args) + rest_client[path].get(params: args) + rescue SocketError + raise PrometheusClient::Error, "Can't connect to #{rest_client.url}" + rescue OpenSSL::SSL::SSLError + raise PrometheusClient::Error, "#{rest_client.url} contains invalid SSL data" + rescue Errno::ECONNREFUSED + raise PrometheusClient::Error, 'Connection refused' + end + def handle_response(response) - json_data = JSON.parse(response.body) + json_data = parse_json(response.body) if response.code == 200 && json_data['status'] == 'success' json_data['data'] || {} else @@ -81,7 +118,7 @@ module Gitlab if response.code == 200 && response['status'] == 'success' response['data'] || {} elsif response.code == 400 - json_data = JSON.parse(response.body) + json_data = parse_json(response.body) raise PrometheusClient::QueryError, json_data['error'] || 'Bad data received' else raise PrometheusClient::Error, "#{response.code} - #{response.body}" @@ -92,5 +129,11 @@ module Gitlab data = yield data['result'] if data['resultType'] == expected_type end + + def parse_json(response_body) + JSON.parse(response_body) + rescue JSON::ParserError + raise PrometheusClient::Error, 'Parsing response failed' + end end end |