Feature #285 ยป diff-wip.patch
app/controllers/dashboard_controller.rb | ||
---|---|---|
end
|
||
private
|
||
def graphs
|
||
data ={
|
||
:labels => [ ['string', "State"], ['number', "Number of Hosts"] ],
|
||
:values => [ ["Active", @active_hosts],["Error", @bad_hosts ], ["Out Of Sync", @out_of_sync_hosts ], ["OK", @good_hosts] ]
|
||
}
|
||
options = { :title => "Puppet Clients Activity Overview"}#,
|
||
# :colors =>['#0000FF','#FF0000','#00FF00','#41A317'] }
|
||
@overview = setgraph(GoogleVisualr::PieChart.new, data, options)
|
||
def graphs
|
||
gdata = {}
|
||
gdata["OK"] = @good_hosts
|
||
gdata["Active"] = @active_hosts
|
||
gdata["Error"] = @bad_hosts
|
||
gdata["Out of Sync"] = @out_of_sync_hosts
|
||
data = {
|
||
:labels => [ ['datetime', "Time Ago In Minutes" ],['number', "Number Of Clients"]],
|
||
:values => Report.count_puppet_runs()
|
||
}
|
||
options = { :title => "Run Distribution in the last #{SETTINGS[:puppet_interval]} minutes", :min => 0 }
|
||
@run_distribution = setgraph(GoogleVisualr::ColumnChart.new, data, options)
|
||
values = Report.count_puppet_runs
|
||
@gdata = gdata.to_a.transpose[1]
|
||
@run_distribution = {}
|
||
@run_distribution["values"] = []
|
||
@run_distribution["legends"] = []
|
||
values.each do |run|
|
||
@run_distribution["legends"] << "\"#{run.first}\""
|
||
@run_distribution["values"] << run.last
|
||
end
|
||
@title = "Run Distribution in the last #{SETTINGS[:puppet_interval]} minutes"
|
||
data = @run_distribution["values"]
|
||
labels = @run_distribution["legends"]
|
||
start = Time.parse(labels.first).strftime("%m:%d:%Y")
|
||
finish = Time.parse(labels.last).strftime("%m:%d:%Y")
|
||
labels.map! { |lbl| lbl = Time.parse(lbl).strftime("%H:%M %p") }
|
||
@graphs = []
|
||
@graphs << ["pie", gdata.to_a.transpose, "Clients Activity Overview", 100, 95]
|
||
# for a pie chart the array to pass has to be composed of:
|
||
# text = pie - this defines the graph as a pie
|
||
# hash = a has of 2 arrays of the same size, data and labels
|
||
# text = title of the graph
|
||
# int = X position in the div
|
||
# int = Y position in the div
|
||
@graphs << ["bar", [data], @title, 460, 10]
|
||
# for a bar chart the array to pass has to be composed of:
|
||
# text = bar - this defines the chart as a bar chart
|
||
# array of arrays = 1 array per data to chart, even if its only 1 array you must make it an array of arrays
|
||
# text = title of the graph
|
||
# int = X position in the div
|
||
# int = Y position in the div
|
||
@graphs << ["text", labels, 29, 460, 170, 315]
|
||
# this type of graphs just draws text in the div
|
||
# its being used for the labels on bar charts
|
||
# text = text - this defines
|
||
# array = an array of labels to draw
|
||
# int = separation between the labels in X so the labels align bellow the bars
|
||
# int = X value for the first label
|
||
# int = Y value for the first label
|
||
# int = rotation in degrees for the labels
|
||
end
|
||
def prefetch_data
|
||
@total_hosts = Host.count
|
||
# hosts with errors in the last puppet run
|
||
@bad_hosts = Host.recent.with_error.count
|
||
# hosts with changes in the last puppet run
|
||
@active_hosts = Host.recent.with_changes.count
|
||
@good_hosts = Host.recent.successful.count
|
||
@percentage = (@good_hosts == 0 or @total_hosts == 0) ? 0 : @good_hosts *100 / @total_hosts
|
||
# all hosts with didn't run puppet in the <time interval> - regardless of their status
|
||
@out_of_sync_hosts = Host.out_of_sync.count
|
||
@intersting_reports = Report.with_changes.count
|
||
@disabled_hosts = Host.alerts_disabled.count
|
||
# the run interval to show in the dashboard graph
|
||
end
|
||
app/controllers/statistics_controller.rb | ||
---|---|---|
class StatisticsController < ApplicationController
|
||
def index
|
||
begin
|
||
@os_count = Host.count_distribution :operatingsystem
|
||
@arch_count = Host.count_distribution :architecture
|
||
@env_count = Host.count_distribution :environment
|
||
... | ... | |
@mem_free = FactValue.mem_average "memoryfree"
|
||
@swap_size = FactValue.mem_average "swapsize"
|
||
@swap_free = FactValue.mem_average "swapfree"
|
||
rescue Exception => e
|
||
logger.error e
|
||
render :text => "No Inventory data has been found - add some hosts and facts and try again", :layout => true
|
||
end
|
||
# rescue Exception => e
|
||
# logger.error e
|
||
# render :text => "No Inventory data has been found - add some hosts and facts and try again", :layout => true
|
||
end
|
||
end
|
app/helpers/application_helper.rb | ||
---|---|---|
# Methods added to this helper will be available to all templates in the application.
|
||
module ApplicationHelper
|
||
def graph(type,opts = {})
|
||
Gchart.send(type, {:size => '400x150', :bg => "E6DFCF", :format => "image_tag"}.merge(opts))
|
||
def graph(graphs) # data should be an array of arrays for individual graphs
|
||
div = %q{
|
||
var os = Raphael("os");
|
||
os.g.txtattr.font = "12px 'Fontin Sans', Fontin-Sans, sans-serif";
|
||
grin = function () {
|
||
this.sector.stop();
|
||
this.sector.scale(1.1, 1.1, this.cx, this.cy);
|
||
if (this.label) {
|
||
this.label[0].stop();
|
||
this.label[0].scale(1.5);
|
||
this.label[1].attr({"font-weight": 20});
|
||
}
|
||
},
|
||
grout = function () {
|
||
this.sector.animate({scale: [1, 1, this.cx, this.cy]}, 500, "bounce");
|
||
if (this.label) {
|
||
this.label[0].animate({scale: 1}, 500, "bounce");
|
||
this.label[1].attr({"font-weight": 400});
|
||
}
|
||
},
|
||
fin = function () {
|
||
this.flag = os.g.popup(this.bar.x, this.bar.y, this.bar.value || "0").insertBefore(this);
|
||
},
|
||
fout = function () {
|
||
this.flag.animate({opacity: 0}, 300, function () {this.remove();});
|
||
};
|
||
}
|
||
graphs.each do |graph|
|
||
type, data, title, gx, gy, legend = graph
|
||
case type
|
||
when "pie" then
|
||
labels,values = data[1], data[0]
|
||
# for some reason I am getting nill values in some of the hash which in turn makes the graph not show.
|
||
# data.each_pair do |l, d|
|
||
# labels << "#{l || "unknown"} - ( %% - ## )"
|
||
# values << d || 0
|
||
#end
|
||
div += "os.g.text(#{gx}, #{gy - 85}, \"#{title}\").attr({\"font-size\": 14, \"font-weight\": 800});\n"
|
||
div += "os.g.piechart(#{gx}, #{gy}, 75, #{values.inspect}, {legend: #{labels.inspect}, legendpos: \"east\"}).hover(grin, grout);\n"
|
||
when "bar" then
|
||
div += "os.g.text(#{gx + 150 }, #{gy}, \"#{title}\").attr({\"font-size\": 14, \"font-weight\": 800});\n"
|
||
div += "os.g.barchart(#{gx}, #{gy}, 300, 150, #{data.inspect}, {stacked: false, type: \"soft\"}).hover(fin, fout); \n"
|
||
when "text" then
|
||
# this is a total hack.. ugly.. and I am not happy with it..
|
||
data.each do |lbl|
|
||
div += "os.g.text(#{gx}, #{gy}, \"#{lbl.gsub('"', '')}\").attr({\"font-size\": 10}).rotate(#{legend});\n"
|
||
gx += title
|
||
end
|
||
end
|
||
end
|
||
div
|
||
end
|
||
def show_habtm associations
|
||
... | ... | |
end
|
||
end
|
||
# a simple helper to load the google JS only on pages which requires it
|
||
def gcharts_script
|
||
content_for :head do
|
||
"<script src=http://www.google.com/jsapi></script>"
|
||
end
|
||
end
|
||
def fact_name_select
|
||
param = params[:search]["#{@via}fact_name_id_eq"] if params[:search]
|
||
return param.to_i unless param.empty?
|
||
... | ... | |
observe_field('settings_dropdown', :function => "window.location.href = value;")
|
||
)
|
||
end
|
||
def gcharts_script
|
||
end
|
||
end
|
app/models/host.rb | ||
---|---|---|
belongs_to :owner, :polymorphic => true
|
||
named_scope :recent, lambda { |*args| {:conditions => ["last_report > ?", (args.first || (SETTINGS[:run_interval] + 5.minutes).ago)]} }
|
||
named_scope :out_of_sync, lambda { |*args| {:conditions => ["last_report < ? and enabled = ?", (args.first || (SETTINGS[:run_interval] + 5.minutes).ago), true]} }
|
||
named_scope :out_of_sync, lambda { |*args| {:conditions => ["last_report < ? and enabled != ?", (args.first || (SETTINGS[:run_interval] + 5.minutes).ago), false]} }
|
||
named_scope :with_fact, lambda { |fact,value|
|
||
unless fact.nil? or value.nil?
|
app/views/dashboard/index.html.erb | ||
---|---|---|
<% gcharts_script %>
|
||
<div id="dashboard">
|
||
<h1>Overview</h1>
|
||
<p>Generated at <%= Time.now.to_s(:short) %></p>
|
||
... | ... | |
<p>Out Of Sync Hosts <%= link_to @out_of_sync_hosts, :action => "OutOfSync" %></p>
|
||
<p>Hosts in Error State <%= link_to @bad_hosts, :action => "errors" %></p>
|
||
<p>Hosts With Alerts Disabled <%= link_to @disabled_hosts, :action => "disabled" %></p>
|
||
<div id='overview'></div>
|
||
<%= @overview.render('overview') %>
|
||
<div id='run_distribution'></div>
|
||
<%= @run_distribution.render('run_distribution') %>
|
||
</div>
|
||
<%= debug @gdata %>
|
||
<%= render 'common/pie', :data => @gdata %>
|
app/views/dashboard/index.html.erb.orig | ||
---|---|---|
<<<<<<< develop
|
||
<% gcharts_script %>
|
||
<div id="dashboard">
|
||
<h1>Overview</h1>
|
||
<p>Generated at <%= Time.now.to_s(:short) %></p>
|
||
<p>Good Host Reports in the last <%= SETTINGS[:puppet_interval] %> minutes <%= "#{@good_hosts} / #{@total_hosts}" %> hosts (<%=@percentage%>%) </p>
|
||
<h1>Summary</h1>
|
||
<p>Hosts that had performed modifications <%= link_to @active_hosts, :action => "active" %></p>
|
||
<p>Out Of Sync Hosts <%= link_to @out_of_sync_hosts, :action => "OutOfSync" %></p>
|
||
<p>Hosts in Error State <%= link_to @bad_hosts, :action => "errors" %></p>
|
||
<p>Hosts With Alerts Disabled <%= link_to @disabled_hosts, :action => "disabled" %></p>
|
||
</div>
|
||
=======
|
||
>>>>>>> HEAD~0
|
||
<% data = @run_distribution["values"] %>
|
||
<% labels = @run_distribution["legends"] %>
|
||
<% start = Time.parse(labels.first).strftime("%m:%d:%Y") %>
|
||
<% finish = Time.parse(labels.last).strftime("%m:%d:%Y") %>
|
||
<% labels.map! { |lbl| lbl = Time.parse(lbl).strftime("%H:%M %p") } %>
|
||
<% graphs = []
|
||
graphs << ["pie", @gdata, "Clients Activity Overview", 100, 95]
|
||
# for a pie chart the array to pass has to be composed of:
|
||
# text = pie - this defines the graph as a pie
|
||
# hash = a has of 2 arrays of the same size, data and labels
|
||
# text = title of the graph
|
||
# int = X position in the div
|
||
# int = Y position in the div
|
||
graphs << ["bar", [data], @title, 460, 10]
|
||
# for a bar chart the array to pass has to be composed of:
|
||
# text = bar - this defines the chart as a bar chart
|
||
# array of arrays = 1 array per data to chart, even if its only 1 array you must make it an array of arrays
|
||
# text = title of the graph
|
||
# int = X position in the div
|
||
# int = Y position in the div
|
||
graphs << ["text", labels, 29, 460, 170, 315]
|
||
# this type of graphs just draws text in the div
|
||
# its being used for the labels on bar charts
|
||
# text = text - this defines
|
||
# array = an array of labels to draw
|
||
# int = separation between the labels in X so the labels align bellow the bars
|
||
# int = X value for the first label
|
||
# int = Y value for the first label
|
||
# int = rotation in degrees for the labels
|
||
%>
|
||
<script type="text/javascript" charset="utf-8">
|
||
window.onload = function () {
|
||
<%= graph(graphs) -%>
|
||
};
|
||
</script>
|
||
<div id="container" class="autoclear">
|
||
<div class="dashboard" id="os"> </div>
|
||
<div style="clear: both;"></div>
|
||
</div>
|
app/views/layouts/standard.rhtml | ||
---|---|---|
<%= stylesheet_link_tag 'style' %>
|
||
<%= yield(:head) %>
|
||
<%= javascript_include_tag :defaults, :cache => true %>
|
||
<%= javascript_include_tag "raphael", "g.raphael", "g.pie", "g.line", "g.bar", :cache => true %>
|
||
</head>
|
||
<body>
|
||
<div id="header">
|
app/views/statistics/index.html.erb | ||
---|---|---|
<center>
|
||
<%=
|
||
graph("pie_3d" ,{:title => "OS Distribution", :data => @os_count.values,
|
||
:labels =>@os_count.keys})
|
||
-%>
|
||
<%=
|
||
graph("pie_3d" ,{:title => "Architecture Distribution", :data => @arch_count.values,
|
||
:labels =>@arch_count.keys})
|
||
-%>
|
||
<%=
|
||
graph("pie" ,{:title => "Environments Distribution", :data => @env_count.values,
|
||
:labels => @env_count.to_a.map{|x| x.join(" ")}, })
|
||
-%>
|
||
<%=
|
||
graph("pie_3d" ,{:title => "Num of Cpu's", :data => @cpu_count.values,
|
||
:labels =>@cpu_count.keys})
|
||
-%>
|
||
<%=
|
||
graph("pie_3d" ,{:title => "Hardware", :data => @model_count.values,
|
||
:labels =>@model_count.keys})
|
||
-%>
|
||
<%=
|
||
graph("pie_3d" ,{:title => "Class Distribution", :data => @klass_count.values,
|
||
:labels =>@klass_count.keys})
|
||
-%>
|
||
<%=
|
||
graph("bar", {:title => "Average memory usage", :data => [[@mem_free,@swap_free],[@mem_size,@swap_size]],
|
||
:axis_with_labels => ["x","x"],:bar_colors => ['FF0000', '00FF00'],:stacked => false,
|
||
:legend => ["Avg Free", "Avg Size"], :bar_width_and_spacing => 40,
|
||
:axis_labels => [['Memory|Swap'], ["#{@mem_free} GB/#{@mem_size} GB","#{@swap_free} GB/#{@swap_size} GB"]] })
|
||
-%>
|
||
</center>
|
||
<% graphs = []
|
||
graphs << ["pie", @os_count, "OS Distribution", 100, 95]
|
||
graphs << ["pie", @arch_count, "Architecture Distribution", 460, 95]
|
||
# graphs << ["pie", @env_count, "Environments Distribution", 820, 95]
|
||
graphs << ["pie", @cpu_count, "Num of Cpu's", 100, 275]
|
||
graphs << ["pie", @model_count, "Hardware", 460, 275]
|
||
graphs << ["pie", @klass_count, "Class Distribution", 820, 275]
|
||
graphs << ["bar", [[@mem_free,@swap_free],[@mem_size,@swap_size]], "Average Memory Usage in Gb", 330, 370, [["Avg Memory", "Avg Swap"]]]
|
||
-%>
|
||
<%= render 'common/graph', :graphs => graphs %>
|