-
Notifications
You must be signed in to change notification settings - Fork 0
/
graph.rb
103 lines (91 loc) · 3 KB
/
graph.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
require 'fileutils'
module Grid5000
class Graph
VERSION = "0.2.0"
class Error < StandardError; end
attr_reader :options, :nodes
def initialize(nodes, options = {})
@nodes = nodes
@options = options
@colors = {}
end
class << self
def check_environment!
`which rrdtool`
raise(Error, "It looks like you do not have the `rrdtool` binary in your path. Please try to install it first.") if $?.exitstatus != 0
`which unzip`
raise(Error, "It looks like you do not have the `unzip` binary in your path. Please try to install it first.") if $?.exitstatus != 0
true
end
end
def graph!
raise(Error, "No nodes given") if nodes.empty?
if nodes.all?{|n| n =~ /\.\w+\.grid5000\.fr$/}
FileUtils.rm_rf options[:output] if options[:empty]
FileUtils.mkdir_p options[:output]
fetch_timeseries
graph_timeseries
else
raise(Error, "One of the given nodes is not correct: #{nodes.inspect}")
end
end
def fetch_timeseries
nodes_by_site = nodes.group_by{|n|
n.split(".")[1]
}
nodes_by_site.keys.each do |site|
cmd = "curl -kn \"https://api.grid5000.fr/2.0/grid5000"+
"/sites/#{site}/metrics/{#{options[:metrics].join(",")}}/timeseries.zip"+
"?only=#{nodes_by_site[site].join(",")}"+
"&from=#{options[:from]}"+
"&to=#{options[:to]}"+
"&resolution=#{options[:resolution]}\""+
" -o \"#{File.join(options[:output], "#{site}-#1-timeseries.zip")}\""
puts cmd
system cmd
end
end
def graph_timeseries
Dir.chdir(options[:output]) do |dir|
Dir["*.zip"].each do |zip|
system "unzip -o #{zip}"
end
commands = {}
Dir["*.grid5000.fr/*.xml"].each do |xml|
dirname = File.dirname(xml)
metric = File.basename(xml, ".xml")
node = File.basename(dirname).split(".").first
commands[metric] ||= "rrdtool graph #{metric}.png --title #{metric} -s #{options[:from]}"
puts "Restoring #{metric}..."
rrd = "#{File.join(dirname, metric)}.rrd"
File.unlink rrd if File.exist?(rrd)
system "rrdtool restore #{xml} #{rrd}"
# generate random color
color = color(node)
commands[metric] += " DEF:#{node}=#{rrd}:sum:AVERAGE LINE2:#{node}##{color}:#{node}"
end
commands.each do |metric, cmd|
puts "Executing #{cmd}"
system cmd
end
puts "The following graphs have been generated in #{dir.inspect}:"
puts Dir["*.png"].join("\n")
end
end
# FIXME: a bit too verbose
def color(id)
if @colors.has_key?(id)
@colors[id]
else
c = "%06x" % (rand * 0xffffff)
if @colors.values.find{|v| v == c}
# find another color
color(id)
else
@colors[id] = c
@colors[id]
end
end
end
end
end