Skip to content

Commit

Permalink
Merge pull request #252 from jshaughn/hawkular-1328
Browse files Browse the repository at this point in the history
Hawkular 1328.
Support both live-metrics and live-alerting. Prometheus support.
  • Loading branch information
israel-hdez authored Dec 1, 2017
2 parents f0e020f + 71d4d8d commit 45d006c
Show file tree
Hide file tree
Showing 171 changed files with 5,109 additions and 4,504 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ Gemfile.lock
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc

# test config
spec/endpoint.yml

# IDE files
.project
.classpath
Expand Down
10 changes: 7 additions & 3 deletions .travis/start_hawkular_services.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ while [ "$CASSANDRA_STATUS" != "running" ] && [ $TOTAL_WAIT -lt 60 ]; do
echo "Waited $TOTAL_WAIT seconds for Cassandra to start."
done

# Start hawkular-metrics
docker-compose up -d hawkular-metrics

# Update hawkular javaagent configuration to make it suitable for tests.
docker-compose create hawkular
DOCKER_HAWKULAR_ID=`docker-compose ps -q hawkular`
docker-compose create hawkular-services
DOCKER_HAWKULAR_ID=`docker-compose ps -q hawkular-services`
export DOCKER_`docker inspect -f '{{range $index, $value := .Config.Env}}{{println $value}}{{end}}' $DOCKER_HAWKULAR_ID | grep JBOSS_HOME`

docker cp ${DOCKER_HAWKULAR_ID}:${DOCKER_JBOSS_HOME}/standalone/configuration/hawkular-javaagent-config.yaml hawkular-javaagent-config.yaml
Expand All @@ -31,4 +34,5 @@ rm hawkular-javaagent-config.yaml
# Ensure the volume exists and has correct permissions.
mkdir -p /tmp/opt/hawkular/server
chown 1000:1000 -R /tmp/opt/hawkular
docker-compose start hawkular
docker-compose start hawkular-services

4 changes: 2 additions & 2 deletions .travis/wait_for_services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
is_ready: -> (response) { response.code == '200' }
},
'metrics' => {
url: 'http://localhost:8080/hawkular/metrics/status',
url: 'http://localhost:8081/hawkular/metrics/status',
is_ready: -> (response) { response.code == '200' && JSON.parse(response.body)['MetricsService'] == 'STARTED' }
},
'alerts' => {
url: 'http://localhost:8080/hawkular/alerts/status',
is_ready: -> (response) { response.code == '200' && JSON.parse(response.body)['status'] == 'STARTED' }
is_ready: -> (response) { response.code == '200' && JSON.parse(response.body)['status'] == 'UP' }
},
'inventory' => {
url: 'http://localhost:8080/hawkular/inventory/status',
Expand Down
1 change: 0 additions & 1 deletion README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ Check each resource API for a detailed description of what methods are available
Integration tests are recorded and played against cassettes recorded with VCR
(http://www.relishapp.com/vcr/vcr/docs)

* Edit the endpoint properties in the file +spec/endpoint.yml+ (user, password and host name) if needed
* From command line run
rake spec
* To run the tests against a live server, set +VCR_OFF+ to +1+ as in
Expand Down
21 changes: 16 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
hawkular:
image: "hawkular/hawkular-services:latest"
hawkular-metrics:
# !! TODO consider changing this from rubensvp
image: "rubensvp/hawkular-metrics:latest"
ports:
- "8080:8080"
- "8443:8443"
- "9990:9990"
- "8081:8080"
- "8444:8443"
- "9991:9990"
links:
- myCassandra
volumes:
Expand All @@ -15,3 +16,13 @@ myCassandra:
image: cassandra:3.0.12
environment:
- CASSANDRA_START_RPC=true
hawkular-services:
# !! WARNING !! FIXME !! TODO !!
# Reset to hawkular/hawkular-services:latest when services 1275 work is merged to master
image: "hawkular/hawkular-services:hawkular-1275"
ports:
- "8080:8080"
- "8443:8443"
- "9990:9990"
volumes:
- /tmp/opt/hawkular/server:/opt/data
7 changes: 5 additions & 2 deletions lib/hawkular/alerts/alerts_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ def to_h
class Condition
attr_accessor :condition_id, :type, :operator, :threshold
attr_accessor :trigger_mode, :data_id, :data2_id, :data2_multiplier
attr_accessor :alerter_id, :expression
attr_reader :condition_set_size, :condition_set_index, :trigger_id

def initialize(cond_hash)
Expand All @@ -461,7 +462,8 @@ def initialize(cond_hash)
@data2_id = cond_hash['data2Id']
@data2_multiplier = cond_hash['data2Multiplier']
@trigger_id = cond_hash['triggerId']
@interval = cond_hash['interval']
@alerter_id = cond_hash['alerterId']
@expression = cond_hash['expression']
end

def to_h
Expand All @@ -476,7 +478,8 @@ def to_h
cond_hash['data2Id'] = @data2_id
cond_hash['data2Multiplier'] = @data2_multiplier
cond_hash['triggerId'] = @trigger_id
cond_hash['interval'] = @interval
cond_hash['alerterId'] = @alerter_id
cond_hash['expression'] = @expression
cond_hash
end
end
Expand Down
20 changes: 10 additions & 10 deletions lib/hawkular/hawkular_client.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
require 'hawkular/inventory/inventory_api'
require 'hawkular/metrics/metrics_client'
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, :metrics, :alerts, :operations, :tokens, :state
attr_reader :inventory, :alerts, :operations, :tokens, :state, :prometheus

def initialize(hash)
hash[:credentials] ||= {}
Expand All @@ -21,13 +21,13 @@ def initialize(hash)
def method_missing(name, *args, &block)
delegate_client = case name
when /^inventory_/ then inventory
when /^metrics_/ then metrics
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_`, `metrics_`,`alerts_`,`operations_`, `tokens_`'
'`inventory_`, `alerts_`, `operations_`, `tokens_`, `prometheus_`'
end
method = name.to_s.sub(/^[^_]+_/, '')
delegate_client.__send__(method, *args, &block)
Expand All @@ -39,12 +39,6 @@ def inventory
@state[:options])
end

def metrics
@metrics ||= Metrics::Client.new("#{@state[:entrypoint]}/hawkular/metrics",
@state[:credentials],
@state[:options])
end

def alerts
@alerts ||= Alerts::Client.new("#{@state[:entrypoint]}/hawkular/alerts",
@state[:credentials],
Expand All @@ -64,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
38 changes: 21 additions & 17 deletions lib/hawkular/inventory/entities.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
# It contains class definitions that are used by the inventory REST client
module Hawkular::Inventory
class Metric
# @return [String] Name of the metric
# @return [String] Provider Name of the metric
attr_reader :name
# @return [String] Type of the metric
attr_reader :type
# @return [String] Display Name of the metric
attr_reader :display_name
# @return [String] Family of the metric (Prometheus family name)
attr_reader :family
# @return [String] Promql expression for fetching the time series
attr_reader :expression
# @return [String] Unit of the metric
attr_reader :unit
# @return [Hash<String,String>] Labels of this metric (Prometheus labels)
attr_reader :labels
# @return [Hash<String,String>] Properties of this metric
attr_reader :properties

def initialize(hash)
@name = hash['name']
@type = hash['type']
@name = hash['displayName']
@display_name = hash['displayName']
@family = hash['family']
@expression = hash['expression']
@unit = hash['unit']
@labels = hash['labels'] || {}
@properties = hash['properties'] || {}
@_hash = hash.dup
end

def hawkular_id
@properties.fetch('hawkular.metric.id')
end

def hawkular_type
@properties.fetch('hawkular.metric.type')
end

def hawkular_type_id
@properties.fetch('hawkular.metric.typeId')
# 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 Expand Up @@ -117,8 +121,8 @@ def metrics(recursive = false)
children(recursive).collect(&:metrics).flat_map(&:itself).concat(@metrics)
end

def metrics_by_type(type)
@metrics.select { |m| m.type == type }
def metrics_by_family(family)
@metrics.select { |m| m.family == family }
end

def ==(other)
Expand Down
60 changes: 60 additions & 0 deletions lib/hawkular/prometheus/prometheus_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
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?start=#{time}&query=#{query}"
result = response['data']['result'].empty? ? {} : response['data']['result'].first
result['metric'] = metric
results << result
end
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
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}"
if response['data']['result'].empty?
[]
else
response['data']['result'].first['values']
end
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'
26 changes: 0 additions & 26 deletions spec/endpoint.yml

This file was deleted.

3 changes: 2 additions & 1 deletion spec/integration/alerts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,8 @@ module Hawkular::Alerts::RSpec
@client = Hawkular::Alerts::Client.new(ALERTS_BASE, creds, options)
end

it 'Should create and fire a trigger' do
# FIXME: disabled because involves hawkular-metrics
xit 'Should create and fire a trigger' do
email_props = { to: '[email protected]',
from: '[email protected]' }
begin
Expand Down
Loading

0 comments on commit 45d006c

Please sign in to comment.