g5k-graph 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +32 -0
  3. data/bin/g5k-graph +62 -0
  4. data/lib/grid5000/graph.rb +99 -0
  5. metadata +74 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Cyril Rohr, INRIA Rennes - Bretagne Atlantique
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # g5k-graph
2
+ A tool to help generate graphs for your Grid'5000 metrics.
3
+
4
+ ## Installation
5
+
6
+ gem install g5k-graph
7
+
8
+ ## Usage
9
+
10
+ g5k-graph -h
11
+
12
+ * Description
13
+ g5k-graph - Graph your Grid'5000 metrics.
14
+ * Usage
15
+ g5k-graph [options] < list-of-nodes
16
+ * Options
17
+ -f, --from= The timeseries start time, in seconds since EPOCH [default=1303113485]
18
+ -t, --to= The timeseries end time, in seconds since EPOCH [default=1303114080]
19
+ -r, --resolution= The timeseries resolution, in seconds [default=15]
20
+ -m, --metrics= The comma-separated list of metrics to fetch [default=mem_free,cpu_idle,bytes_in,bytes_out]
21
+ -o, --output= Where to write the timeseries data and graphs [default=/Volumes/backup/dev/g5k-graph/data]
22
+ -h, --help Show this message
23
+
24
+ Example:
25
+
26
+ g5k-graph --metrics mem_free,custom_metric -o /tmp -r 360 < $OAR_NODE_FILE
27
+
28
+ This tools takes a list of nodes on STDIN, and a set of options, and outputs a graph for each metric that you gave.
29
+ It fetches the timeseries from the [Grid'5000 API](https://api.grid5000.fr/) with the `cURL` tool, and as such you may need to have a proper `~/.netrc` setup for the authentication to work (see the curl-tutorial at <http://grid5000.github.com/tutorials/>).
30
+
31
+ ## Authors
32
+ * Cyril Rohr <cyril.rohr@inria.fr>
data/bin/g5k-graph ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'grid5000/graph'
4
+
5
+ require 'optparse'
6
+
7
+ @options = {
8
+ :from => Time.now.to_i-600,
9
+ :resolution => 15,
10
+ :metrics => ['mem_free', 'cpu_idle', 'bytes_in', 'bytes_out'],
11
+ :to => (Time.now.to_i/15*15),
12
+ :output => File.expand_path("./data")
13
+ }
14
+
15
+ option_parser = OptionParser.new do |opts|
16
+ opts.banner = <<BANNER
17
+ * Description
18
+ g5k-graph #{Grid5000::Graph::VERSION} - Graph your Grid'5000 metrics.
19
+ * Usage
20
+ g5k-graph [options] < list-of-nodes
21
+ * Options
22
+ BANNER
23
+
24
+ opts.on("-f=", "--from=", "The timeseries start time, in seconds since EPOCH [default=#{@options[:from]}]") do |v|
25
+ @options[:from] = v.to_i
26
+ end
27
+ opts.on("-t=", "--to=", "The timeseries end time, in seconds since EPOCH [default=#{@options[:to]}]") do |v|
28
+ @options[:to] = v.to_i
29
+ end
30
+ opts.on("-r=", "--resolution=", "The timeseries resolution, in seconds [default=#{@options[:resolution]}]") do |v|
31
+ @options[:resolution] = v.to_i
32
+ end
33
+ opts.on("-m=", "--metrics=", "The comma-separated list of metrics to fetch [default=#{@options[:metrics].join(",")}]") do |v|
34
+ @options[:metrics] = v.split(",")
35
+ end
36
+ opts.on("-o=", "--output=", "Where to write the timeseries data and graphs [default=#{@options[:output]}]") do |v|
37
+ @options[:output] = File.expand_path(v)
38
+ end
39
+ opts.on_tail("-h", "--help", "Show this message") do
40
+ puts opts
41
+ exit
42
+ end
43
+
44
+ end
45
+
46
+ option_parser.parse!
47
+
48
+
49
+ begin
50
+ Grid5000::Graph.check_environment!
51
+
52
+ nodes = []
53
+ while node = gets() do
54
+ nodes.push(node.chomp) unless node.strip.empty?
55
+ end
56
+
57
+ Grid5000::Graph.new(nodes, @options).graph!
58
+ exit 0
59
+ rescue Grid5000::Graph::Error => e
60
+ STDERR.puts "#{e.class.name}: #{e.message}"
61
+ exit 1
62
+ end
@@ -0,0 +1,99 @@
1
+ module Grid5000
2
+ class Graph
3
+ VERSION = "0.1.0"
4
+
5
+ class Error < StandardError; end
6
+
7
+ attr_reader :options, :nodes
8
+
9
+ def initialize(nodes, options = {})
10
+ @nodes = nodes
11
+ @options = options
12
+ @colors = {}
13
+ end
14
+
15
+ class << self
16
+ def check_environment!
17
+ `which rrdtool`
18
+ raise(Error, "It looks like you do not have the `rrdtool` binary in your path. Please try to install it first.") if $?.exitstatus != 0
19
+ `which unzip`
20
+ raise(Error, "It looks like you do not have the `unzip` binary in your path. Please try to install it first.") if $?.exitstatus != 0
21
+ true
22
+ end
23
+ end
24
+
25
+ def graph!
26
+ raise(Error, "No nodes given") if nodes.empty?
27
+
28
+ if nodes.all?{|n| n =~ /\.\w+\.grid5000\.fr$/}
29
+ fetch_timeseries
30
+ graph_timeseries
31
+ else
32
+ raise(Error, "One of the given nodes is not correct: #{nodes.inspect}")
33
+ end
34
+
35
+ end
36
+
37
+ def fetch_timeseries
38
+ nodes_by_site = nodes.group_by{|n|
39
+ n.split(".")[1]
40
+ }
41
+ nodes_by_site.keys.each do |site|
42
+ cmd = "curl -kn \"https://api.grid5000.fr/2.0/grid5000"+
43
+ "/sites/#{site}/metrics/{#{options[:metrics].join(",")}}/timeseries.zip"+
44
+ "?only=#{nodes_by_site[site].join(",")}"+
45
+ "&from=#{options[:from]}"+
46
+ "&to=#{options[:to]}"+
47
+ "&resolution=#{options[:resolution]}\""+
48
+ " -o \"#{File.join(options[:output], "#{site}-#1-timeseries.zip")}\""
49
+ puts cmd
50
+ system cmd
51
+ end
52
+ end
53
+
54
+ def graph_timeseries
55
+ Dir.chdir(options[:output]) do |dir|
56
+ Dir["*.zip"].each do |zip|
57
+ system "unzip #{zip}"
58
+ end
59
+ commands = {}
60
+ Dir["*.grid5000.fr/*.xml"].each do |xml|
61
+ dirname = File.dirname(xml)
62
+ metric = File.basename(xml, ".xml")
63
+ node = File.basename(dirname).split(".").first
64
+ commands[metric] ||= "rrdtool graph #{metric}.png --title #{metric} -s #{options[:from]}"
65
+ puts "Restoring #{metric}..."
66
+ rrd = "#{File.join(dirname, metric)}.rrd"
67
+ File.unlink rrd if File.exist?(rrd)
68
+ system "rrdtool restore #{xml} #{rrd}"
69
+ # generate random color
70
+ color = color(node)
71
+ commands[metric] += " DEF:#{node}=#{rrd}:sum:AVERAGE LINE2:#{node}##{color}:#{node}"
72
+ end
73
+ commands.each do |metric, cmd|
74
+ puts "Executing #{cmd}"
75
+ system cmd
76
+ end
77
+ puts "The following graphs have been generated in #{dir.inspect}:"
78
+ puts Dir["*.png"].join("\n")
79
+ end
80
+ end
81
+
82
+ # FIXME: a bit too verbose
83
+ def color(id)
84
+ if @colors.has_key?(id)
85
+ @colors[id]
86
+ else
87
+ c = "%06x" % (rand * 0xffffff)
88
+ if @colors.values.find{|v| v == c}
89
+ # find another color
90
+ color(id)
91
+ else
92
+ @colors[id] = c
93
+ @colors[id]
94
+ end
95
+ end
96
+ end
97
+
98
+ end
99
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: g5k-graph
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Cyril Rohr
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-18 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Graph your Grid'5000 metrics
23
+ email:
24
+ - cyril.rohr@gmail.com
25
+ executables:
26
+ - g5k-graph
27
+ extensions: []
28
+
29
+ extra_rdoc_files:
30
+ - LICENSE
31
+ - README.md
32
+ files:
33
+ - bin/g5k-graph
34
+ - lib/grid5000/graph.rb
35
+ - LICENSE
36
+ - README.md
37
+ has_rdoc: true
38
+ homepage: http://github.com/crohr/g5k-graph
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ hash: 31
52
+ segments:
53
+ - 1
54
+ - 8
55
+ version: "1.8"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 9
62
+ segments:
63
+ - 1
64
+ - 3
65
+ version: "1.3"
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.5.2
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Graph your Grid'5000 metrics
73
+ test_files: []
74
+