[QENG-4075] Allow specifying 'graphs:' for dashboard

Prior to this the dashboard front-end would use the configuration settings
for `graphite[:server]`/`graphite[:prefix]` to locate a graphite server
to use for rendering graphs.

Now that we have multiple possible metrics backends, the front-end graph
host for the dashboard could be entirely different from the back-end metrics
server that we publish to (if any).

This decouples those settings:

 - use `graphs[:server]` / `graphs[:prefix]` for the graphite-compatible web front-end to use for dashboard display graphs
 - fall back to `graphite[:server]`/`graphite[:prefix]` if `graphs` is not specified, in order to support legacy `vmpooler.yaml` configurations.

Note that since `statsd` takes precedence over `graphite`, it's possible to specify both `statsd` (for publishing) and `graphite` (for reading). We still prefer `graphs` over `graphite`.

Updated the example `vmpooler.yaml` config file.
This commit is contained in:
Rick Bradley 2016-07-12 15:22:13 -05:00
parent 2f500715f0
commit c49c252f8f
2 changed files with 79 additions and 19 deletions

View file

@ -1,9 +1,57 @@
module Vmpooler module Vmpooler
class API class API
class Dashboard < Sinatra::Base class Dashboard < Sinatra::Base
# handle to the App's configuration information
def config
@config ||= Vmpooler::API.settings.config
end
# configuration setting for server hosting graph URLs to view
def graph_server
return @graph_server if @graph_server
if config[:graphs]
return false unless config[:graphs]['server']
@graph_server = config[:graphs]['server']
elsif config[:graphite]
return false unless config[:graphite]['server']
@graph_server = config[:graphite]['server']
else
false
end
end
# configuration setting for URL prefix for graphs to view
def graph_prefix
return @graph_prefix if @graph_prefix
if config[:graphs]
return false unless config[:graphs]['prefix']
@graph_prefix = config[:graphs]['prefix']
elsif config[:graphite]
return false unless config[:graphite]['prefix']
@graph_prefix = config[:graphite]['prefix']
else
false
end
end
# what is the base URL for viewable graphs?
def graph_url
return false unless graph_server && graph_prefix
@graph_url ||= "http://#{graph_server}/render?target=#{graph_prefix}"
end
# return a full URL to a viewable graph for a given metrics target (graphite syntax)
def graph_link(target = "")
return "" unless graph_url
graph_url + target
end
get '/dashboard/stats/vmpooler/pool/?' do get '/dashboard/stats/vmpooler/pool/?' do
content_type :json content_type :json
result = {} result = {}
Vmpooler::API.settings.config[:pools].each do |pool| Vmpooler::API.settings.config[:pools].each do |pool|
@ -13,13 +61,11 @@ module Vmpooler
end end
if params[:history] if params[:history]
if Vmpooler::API.settings.config[:graphite]['server'] if graph_url
history ||= {} history ||= {}
begin begin
buffer = open( buffer = open(graph_link('.qready.*&from=-1hour&format=json')).read
'http://' + Vmpooler::API.settings.config[:graphite]['server'] + '/render?target=' + Vmpooler::API.settings.config[:graphite]['prefix'] + '.ready.*&from=-1hour&format=json'
).read
history = JSON.parse(buffer) history = JSON.parse(buffer)
history.each do |pool| history.each do |pool|
@ -52,59 +98,47 @@ module Vmpooler
end end
end end
end end
JSON.pretty_generate(result) JSON.pretty_generate(result)
end end
get '/dashboard/stats/vmpooler/running/?' do get '/dashboard/stats/vmpooler/running/?' do
content_type :json content_type :json
result = {} result = {}
Vmpooler::API.settings.config[:pools].each do |pool| Vmpooler::API.settings.config[:pools].each do |pool|
running = Vmpooler::API.settings.redis.scard('vmpooler__running__' + pool['name']) running = Vmpooler::API.settings.redis.scard('vmpooler__running__' + pool['name'])
pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)\-/ pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)\-/
result[pool['major']] ||= {} result[pool['major']] ||= {}
result[pool['major']]['running'] = result[pool['major']]['running'].to_i + running.to_i result[pool['major']]['running'] = result[pool['major']]['running'].to_i + running.to_i
end end
if params[:history] if params[:history]
if Vmpooler::API.settings.config[:graphite]['server'] if graph_url
begin begin
buffer = open( buffer = open(graph_link('.running.*&from=-1hour&format=json')).read
'http://' + Vmpooler::API.settings.config[:graphite]['server'] + '/render?target=' + Vmpooler::API.settings.config[:graphite]['prefix'] + '.running.*&from=-1hour&format=json'
).read
JSON.parse(buffer).each do |pool| JSON.parse(buffer).each do |pool|
if pool['target'] =~ /.*\.(.*)$/ if pool['target'] =~ /.*\.(.*)$/
pool['name'] = Regexp.last_match[1] pool['name'] = Regexp.last_match[1]
pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)\-/ pool['major'] = Regexp.last_match[1] if pool['name'] =~ /^(\w+)\-/
result[pool['major']]['history'] ||= Array.new result[pool['major']]['history'] ||= Array.new
for i in 0..pool['datapoints'].length for i in 0..pool['datapoints'].length
if if
pool['datapoints'][i] && pool['datapoints'][i] &&
pool['datapoints'][i][0] pool['datapoints'][i][0]
pool['last'] = pool['datapoints'][i][0] pool['last'] = pool['datapoints'][i][0]
result[pool['major']]['history'][i] ||= 0 result[pool['major']]['history'][i] ||= 0
result[pool['major']]['history'][i] = result[pool['major']]['history'][i].to_i + pool['datapoints'][i][0].to_i result[pool['major']]['history'][i] = result[pool['major']]['history'][i].to_i + pool['datapoints'][i][0].to_i
else else
result[pool['major']]['history'][i] = result[pool['major']]['history'][i].to_i + pool['last'].to_i result[pool['major']]['history'][i] = result[pool['major']]['history'][i].to_i + pool['last'].to_i
end end
end end
end end
end end
rescue rescue
end end
end end
end end
JSON.pretty_generate(result) JSON.pretty_generate(result)
end end
end end

View file

@ -54,6 +54,32 @@
server: 'redis.company.com' server: 'redis.company.com'
# :graphs:
#
# This section contains the server and prefix information for a graphite-
# compatible web front-end where graphs may be viewed. This is used by the
# vmpooler dashboard to retrieve statistics and graphs for a given instance.
#
# NOTE: This is not the endpoint for publishing metrics data. See `graphite:`
# and `statsd:` below.
#
# NOTE: If `graphs:` is not set, for legacy compatibility, `graphite:` will be
# consulted for `server`/`prefix` information to use in locating a
# graph server for our dashboard. `graphs:` is recommended over
# `graphite:`
#
#
# Available configuration parameters:
#
#
# - server
# The FQDN hostname of the statsd daemon.
# (required)
#
# - prefix
# The prefix to use while storing statsd data.
# (optional; default: 'vmpooler')
# :statsd: # :statsd:
# #
# This section contains the connection information required to store # This section contains the connection information required to store