Skip to content

Commit

Permalink
Merge 7d27513 into 73a9699
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasponce committed Nov 22, 2017
2 parents 73a9699 + 7d27513 commit 9b3c068
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 2 deletions.
12 changes: 10 additions & 2 deletions lib/hawkular/hawkular_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
require 'hawkular/alerts/alerts_api'
require 'hawkular/tokens/tokens_api'
require 'hawkular/operations/operations_api'
require 'hawkular/prometheus/prometheus_api'
require 'hawkular/base_client'

module Hawkular
class Client
attr_reader :inventory, :alerts, :operations, :tokens, :state
attr_reader :inventory, :alerts, :operations, :tokens, :state, :prometheus

def initialize(hash)
hash[:credentials] ||= {}
Expand All @@ -23,9 +24,10 @@ def method_missing(name, *args, &block)
when /^alerts_/ then alerts
when /^operations_/ then operations
when /^tokens_/ then tokens
when /^prometheus_/ then prometheus
else
fail Hawkular::ArgumentError, "unknown method prefix `#{name}`, allowed prefixes:"\
'`inventory_`, `alerts_`, `operations_`, `tokens_`'
'`inventory_`, `alerts_`, `operations_`, `tokens_`, `prometheus_`'
end
method = name.to_s.sub(/^[^_]+_/, '')
delegate_client.__send__(method, *args, &block)
Expand Down Expand Up @@ -56,6 +58,12 @@ def tokens
@state[:options])
end

def prometheus
@prometheus ||= Prometheus::Client.new(@state[:entrypoint],
@state[:credentials],
@state[:options])
end

private

# this is in a dedicated method, because constructor opens the websocket connection to make the handshake
Expand Down
10 changes: 10 additions & 0 deletions lib/hawkular/inventory/entities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class Metric
attr_reader :family
# @return [String] Unit of the metric
attr_reader :unit
# @return [String] Expression of the metric (Prometheus expression)
attr_reader :expression
# @return [Hash<String,String>] Labels of this metric (Prometheus labels)
attr_reader :labels
# @return [Hash<String,String>] Properties of this metric
Expand All @@ -16,8 +18,16 @@ def initialize(hash)
@name = hash['displayName']
@family = hash['family']
@unit = hash['unit']
@expression = hash['expression']
@labels = hash['labels'] || {}
@properties = hash['properties'] || {}
@_hash = hash.dup
end

# Returns a hash representation of the metric type
# @return [Hash<String,Object>] hash of the metric type
def to_h
@_hash.dup
end
end

Expand Down
59 changes: 59 additions & 0 deletions lib/hawkular/prometheus/prometheus_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'hawkular/base_client'
require 'hawkular/inventory/entities'
require 'ostruct'

module Hawkular::Prometheus
class Alerter < Hawkular::BaseClient
def initialize(entrypoint, credentials = {}, options = {})
@entrypoint = normalize_entrypoint_url entrypoint, 'hawkular/alerter'
super(@entrypoint, credentials, options)
end

def prometheus_entrypoint
rest_client('/prometheus/endpoint').get
end
end

# Interface to talk with the Prometheus server used for Middleware Manager
# @param entrypoint [String] base url of Hawkular Services
class Client < Hawkular::BaseClient
def initialize(entrypoint, credentials = {}, options = {})
prometheus_entrypoint = Alerter.new(entrypoint, credentials, options).prometheus_entrypoint
@entrypoint = normalize_entrypoint_url prometheus_entrypoint, 'api/v1'
super(@entrypoint, credentials, options)
end

def query(metrics: [], time: nil)
results = []
metrics.each do |metric|
query = metric['expression']
response = http_get "/query?time=#{time}&query=#{query}"
result = response['data']['result'].empty? ? {} : response['data']['result'].first
result['metric'] = metric
results << result
end
puts "DELETEME p8s - query #{results}"
results
end

def query_range(metrics: [], starts: nil, ends: nil, step: nil)
results = []
metrics.each do |metric|
query = metric['expression']
response = http_get "/query_range?start=#{starts}&end=#{ends}&step=#{step}&query=#{query}"
result = response['data']['result'].empty? ? {} : response['data']['result'].first
result['metric'] = metric
results << result
end
puts "DELETEME p8s - query_range #{results}"
results
end

def up_time(feed_id: nil, starts: nil, ends: nil, step: nil)
query = "up{feed_id=\"#{feed_id}\"}"
response = http_get "/query_range?start=#{starts}&end=#{ends}&step=#{step}&query=#{query}"
puts "DELETEME p8s - up_time feed_id #{feed_id} #{response['data']['result']}"
response['data']['result']
end
end
end
1 change: 1 addition & 0 deletions lib/hawkularclient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
require 'hawkular/alerts/alerts_api'
require 'hawkular/tokens/tokens_api'
require 'hawkular/operations/operations_api'
require 'hawkular/prometheus/prometheus_api'
require 'hawkular/base_client'
require 'hawkular/hawkular_client'
78 changes: 78 additions & 0 deletions spec/integration/prometheus_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require_relative '../vcr/vcr_setup'
require_relative '../spec_helper'

module Hawkular::Prometheus::RSpec
HAWKULAR_BASE = 'http://localhost:8080/'
creds = {}
options = {}

describe 'Prometheus/Queries' do
let(:cassette_name) do |example|
description = example.description
description
end

around(:each) do |example|
record('Prometheus/Queries', credentials, cassette_name, example: example)
end

before(:each) do
@client = Hawkular::Prometheus::Client.new(HAWKULAR_BASE, creds, options)
end

it 'Should fetch a metrics range' do
metrics = [{ 'displayName' => 'Heap Used',
'family' => 'jvm_memory_bytes_used',
'unit' => 'BYTES',
'expression' => 'jvm_memory_bytes_used{area="heap",feed_id="attilan"}',
'labels' => { area: 'heap', feed_id: 'attilan' } },
{ 'displayName' => 'NonHeap Used',
'family' => 'jvm_memory_bytes_used',
'unit' => 'BYTES',
'expression' => 'jvm_memory_bytes_used{area="nonheap",feed_id="attilan"}',
'labels' => { area: 'nonheap', feed_id: 'attilan' } }]

results = @client.query_range(metrics: metrics,
starts: '2017-11-21T09:00:00Z',
ends: '2017-11-21T11:00:00Z',
step: '5s')

first = results.first
second = results.last
expect(first['metric']['displayName']).to eq 'Heap Used'
expect(first['values'].size).to be > 0
expect(second['metric']['displayName']).to eq 'NonHeap Used'
expect(second['values'].size).to be > 0
end

it 'Should fetch a metrics instant' do
metrics = [{ 'displayName' => 'Heap Used',
'family' => 'jvm_memory_bytes_used',
'unit' => 'BYTES',
'expression' => 'jvm_memory_bytes_used{area="heap",feed_id="attilan"}',
'labels' => { area: 'heap', feed_id: 'attilan' } },
{ 'displayName' => 'NonHeap Used',
'family' => 'jvm_memory_bytes_used',
'unit' => 'BYTES',
'expression' => 'jvm_memory_bytes_used{area="nonheap",feed_id="attilan"}',
'labels' => { area: 'nonheap', feed_id: 'attilan' } }]

results = @client.query(metrics: metrics,
time: '2017-11-22T09:00:00Z')
first = results.first
second = results.last
expect(first['metric']['displayName']).to eq 'Heap Used'
expect(first['value'].size).to be > 0
expect(second['metric']['displayName']).to eq 'NonHeap Used'
expect(second['value'].size).to be > 0
end

it 'Should fetch up time' do
results = @client.up_time(feed_id: 'attilan',
starts: '2017-11-15T00:00:00Z',
ends: '2017-11-22T23:00:00Z',
step: '60m')
expect(results.size).to be > 0
end
end
end

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9b3c068

Please sign in to comment.