diff options
Diffstat (limited to 'lib/gitlab/prometheus_client.rb')
-rw-r--r-- | lib/gitlab/prometheus_client.rb | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/gitlab/prometheus_client.rb b/lib/gitlab/prometheus_client.rb new file mode 100644 index 00000000000..5b51a1779dd --- /dev/null +++ b/lib/gitlab/prometheus_client.rb @@ -0,0 +1,76 @@ +module Gitlab + PrometheusError = Class.new(StandardError) + + # Helper methods to interact with Prometheus network services & resources + class PrometheusClient + attr_reader :api_url + + def initialize(api_url:) + @api_url = api_url + end + + def ping + json_api_get('query', query: '1') + end + + def query(query, time: Time.now) + get_result('vector') do + json_api_get('query', query: query, time: time.to_f) + end + end + + def query_range(query, start: 8.hours.ago, stop: Time.now) + get_result('matrix') do + json_api_get('query_range', + query: query, + start: start.to_f, + end: stop.to_f, + step: 1.minute.to_i) + end + end + + private + + def json_api_get(type, args = {}) + get(join_api_url(type, args)) + rescue Errno::ECONNREFUSED + raise PrometheusError, 'Connection refused' + end + + def join_api_url(type, args = {}) + url = URI.parse(api_url) + rescue URI::Error + raise PrometheusError, "Invalid API URL: #{api_url}" + else + url.path = [url.path.sub(%r{/+\z}, ''), 'api', 'v1', type].join('/') + url.query = args.to_query + + url.to_s + end + + def get(url) + handle_response(HTTParty.get(url)) + rescue SocketError + raise PrometheusError, "Can't connect to #{url}" + rescue OpenSSL::SSL::SSLError + raise PrometheusError, "#{url} contains invalid SSL data" + rescue HTTParty::Error + raise PrometheusError, "Network connection error" + end + + def handle_response(response) + if response.code == 200 && response['status'] == 'success' + response['data'] || {} + elsif response.code == 400 + raise PrometheusError, response['error'] || 'Bad data received' + else + raise PrometheusError, "#{response.code} - #{response.body}" + end + end + + def get_result(expected_type) + data = yield + data['result'] if data['resultType'] == expected_type + end + end +end |