Skip to content

Commit

Permalink
Add prometheus view to ad hoc metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacov committed Aug 21, 2017
1 parent 800b3ea commit 1fc036f
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,21 @@ angular.module('miq.util').factory('metricsHttpFactory', function() {
var ends = dash.timeFilter.date.valueOf(); // javascript time is in milisec
var diff = dash.timeFilter.time_range * dash.timeFilter.range_count * NUMBER_OF_MILLISEC_IN_HOUR; // time_range is in hours
var starts = ends - diff;
var bucket_duration = parseInt(diff / NUMBER_OF_MILLISEC_IN_SEC / numberOfBucketsInChart); // bucket duration is in seconds
var bucketDuration = parseInt(diff / NUMBER_OF_MILLISEC_IN_SEC / numberOfBucketsInChart); // bucket duration is in seconds

// make sure bucket duration is not smaller then minBucketDurationInSecondes seconds
if (bucket_duration < dash.minBucketDurationInSecondes) {
bucket_duration = dash.minBucketDurationInSecondes;
if (bucketDuration < dash.minBucketDurationInSecondes) {
bucketDuration = dash.minBucketDurationInSecondes;
}

// hawkular time is in milisec (hawkular bucket_duration is in seconds)
var params = '&query=get_data&type=' + currentItem.type + '&metric_id=' + currentItem.id + '&ends=' + ends +
'&starts=' + starts + '&bucket_duration=' + bucket_duration + 's';
// hawkular time is in milisec (hawkular bucketDuration is in seconds)
var params = '&query=get_data&ends=' + ends + '&starts=' + starts + '&bucket_duration=' + bucketDuration + 's';

// uniqe metric id for prometheus is the sum of all _tags_
params += '&tags=' + JSON.stringify(currentItem.tags);

// uniqe metric id for hawkular is the _type_ and _id_ of the metric
params += '&type=' + currentItem.type + '&metric_id=' + currentItem.id;

$http.get(dash.url + params)
.then(function(response) {
Expand Down
8 changes: 7 additions & 1 deletion app/controllers/container_dashboard_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ def collect_data(provider_id)
end

def collect_live_data(provider_id, query)
HawkularProxyService.new(provider_id, self).data(query)
ems = ExtManagementSystem.find(provider_id)

if ems && ems.connection_configurations.prometheus.try(:endpoint)
PrometheusProxyService.new(provider_id, self).data(query)
else
HawkularProxyService.new(provider_id, self).data(query)
end
end

menu_section :cnt
Expand Down
18 changes: 11 additions & 7 deletions app/services/hawkular_proxy_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ class HawkularProxyService

TENANT_LABEL_MAX_LEN = 25
TENANT_LABEL_SPECIAL_CASES = {
"_system" => "System",
"_ops" => "Operations",
"default" => "Default",
"admin" => "Admin",
"openshift-infra" => "OpenShift Infra"
"_system" => "System",
"_ops" => "Operations",
"default" => "Default",
"admin" => "Admin",
"openshift-infra" => "OpenShift Infra",
"kubernetes-nodes" => "Kubernetes Nodes",
"kubernetes-apiserver" => "Kubernetes API server",
"kubernetes-service-endpoints" => "Kubernetes Service",
}.freeze

def initialize(provider_id, controller)
@db_name = "Hawkular"
@provider_id = provider_id
@controller = controller

@params = controller.params
@ems = ManageIQ::Providers::ContainerManager.find(@provider_id) unless @provider_id.blank?
@ems = ExtManagementSystem.find(@provider_id.to_i) unless @provider_id.blank?
@tenant = @params['tenant'] || '_system'

@cli = ManageIQ::Providers::Kubernetes::ContainerManager::MetricsCapture::HawkularClient.new(@ems, @tenant)
Expand Down Expand Up @@ -78,7 +82,7 @@ def data(query)
rescue StandardError => e
{
:parameters => params,
:error => ActionView::Base.full_sanitizer.sanitize(e.to_s) + " " + _("(Please check your Hawkular server)")
:error => ActionView::Base.full_sanitizer.sanitize(e.message) + " " + _("(Please check your #{@db_name} server)")
}
end

Expand Down
135 changes: 135 additions & 0 deletions app/services/prometheus_proxy_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
class PrometheusProxyService < HawkularProxyService
SPECIAL_TAGS = %w(descriptor_name units metric_type type_id).freeze

def initialize(provider_id, controller)
@db_name = "Prometheus"
@provider_id = provider_id
@controller = controller
@ems = ExtManagementSystem.find(@provider_id.to_i) unless @provider_id.blank?
@hostname = @ems.hostname

@params = controller.params
@tenant = @params['tenant'] || 'kubernetes-nodes'

cli = ManageIQ::Providers::Kubernetes::ContainerManager::MetricsCapture::PrometheusClient.new(@ems, @tenant)
@conn = cli.prometheus_client
end

def metric_definitions(params)
tags = params[:tags]
tags_str = if tags.present?
tags.map { |x, y| ",#{x}=~\"#{y}\"" }.join
else
""
end
limit = params[:limit].to_i

response = @conn.get(
"query_range",
:query => "{job=\"#{@tenant}\"#{tags_str}}",
:start => params[:ends] / 1000 - 10 * 12 * 60,
:end => params[:ends] / 1000,
:step => "600s"
)

list = JSON.parse(response.body)["data"]["result"]

list = list.each_with_index.map do |o, i|
metric = o['metric']
values = o['values']

metric['descriptor_name'] = metric['__name__']
metric['units'] = 'bytes' if metric['__name__'].include?('_bytes')
metric['units'] = 'seconds' if metric['__name__'].include?('_seconds')
metric['units'] = 'milliseconds' if metric['__name__'].include?('_milliseconds')
metric['metric_type'] = metric['type']

if metric['container_name'].nil?
metric['type'] = 'machine'
metric['type_id'] = metric['instance']
elsif metric['container_name'] == "POD"
metric['type'] = 'pod'
metric['type_id'] = metric['pod_name']
else
metric['type'] = 'container'
metric['type_id'] = metric['container_name']
end

{
"id" => "#{metric['__name__']}/#{metric['type_id']}[#{i}]",
"type" => "gauge",
"tags" => metric,
"data" => values.map { |v| { :timestamp => v[0] * 1000, :value => v[1] } }
}
end

list.sort { |a, b| a["id"].downcase <=> b["id"].downcase }[0...limit]
end

def metric_tags(params)
definitions = metric_definitions(params.merge(:tags => {:job => @tenant}))
tags = definitions.map { |x| x["tags"].keys }.flatten.uniq

tags.map do |tag|
{ :tag => tag, :options => metric_tags_options(tag) }
end
end

def get_data(_id, params)
tags = params[:tags]
tags_str = if tags.present?
tags.delete("type")
tags["type"] = tags["metric_type"] if tags["metric_type"]
tags.except(*SPECIAL_TAGS).map { |x, y| ",#{x}=\"#{y}\"" }.join
else
""
end

response = @conn.get(
"query_range",
:query => "{job=\"#{@tenant}\"#{tags_str}}",
:start => params[:starts] / 1000,
:end => params[:ends] / 1000,
:step => params[:bucketDuration]
)
result = JSON.parse(response.body)["data"]["result"]

data = if result.length == 1
result[0]['values'].map { |v| { :start => v[0] * 1000, :avg => v[1], :empty => "false" } }
else
[]
end
data << { :start => params[:starts] - 1, :empty => "true" }
data << { :start => params[:ends] + 1, :empty => "true" }

data
end

def tenants(_limit)
jobs = metric_tags_options("job")

jobs.map { |id| { :label => labelize(id), :value => id } }
end

def add_last_readings(metrics)
metrics
end

def metric_tags_options(tag)
timestamp = DateTime.now.utc.to_i
response = @conn.get("label/#{tag}/values", :_ => timestamp)

options = JSON.parse(response.body)["data"]
options.sort
end

# may be nil
def prometheus_endpoint
@ems.connection_configurations.prometheus.try(:endpoint)
end

def prometheus_uri
prometheus_endpoint_empty = prometheus_endpoint.try(:hostname).blank?
prometheus_endpoint_empty ? @ems.hostname : prometheus_endpoint.hostname
end
end
2 changes: 1 addition & 1 deletion app/views/ems_container/ad_hoc/_list_view_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
%button.btn.btn-primary{"type" => "button",
"ng-disabled" => "!dash.tenantChanged",
"ng-click" => "dash.refreshTenant()"}
= _("Set Hawkular Tenant")
= _("Set Context")
.ad-hoc-toolbar.filters-selector{"pf-toolbar" => "", "id" => "filters-selector", "config" => "dash.toolbarConfig"}
%actions
Expand Down

0 comments on commit 1fc036f

Please sign in to comment.