munin2graphite 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -14,7 +14,6 @@ gem "json", "~> 1.6.3"
14
14
  # Add dependencies to develop your gem here.
15
15
  # Include everything needed to run rake, tests, features, etc.
16
16
  group :development do
17
- gem "bundler", "~> 1.0.0"
18
- gem "jeweler", "~> 1.5.2"
17
+ gem "jeweler", "~> 1.8.4"
19
18
  gem "yard", "~> 0.6.0"
20
19
  end
data/README.markdown CHANGED
@@ -31,22 +31,15 @@ Imagine, for example, that we have two munin-nodes in two different servers (mun
31
31
  # This has to point to the carbon backend to submit metrics
32
32
  carbon_hostname=carbon.example.com
33
33
  carbon_port=2003
34
-
34
+
35
35
  # Graphite endpoint
36
- # This is needed to send graph data to graphite
37
- graphite_endpoint=http://graphite.example.com/
38
-
39
- # User and password of the graphite web UI
40
- graphite_user=test
41
- graphite_password=secret
36
+ # The url of the grphite-web application this is used to config the graphs
37
+ graphite_endpoint=http://graphite_webapp_hostname:port/
42
38
 
43
- # This is the prefix you want the on metrics
44
- graphite_metric_prefix=test.server
45
-
46
- # The prefix you want in the graphics, note that in the UI the grapichs are shown under the user name, so the user name is also added prfixed
47
- # to this prefix. That's why conveniently, I used 'test' (the user name) in the metric prefix
48
- graphite_graph_prefix=server
49
-
39
+ # prefix for the metrics usually, the user name have to be put as a prefix
40
+ graphite_prefix=prefix
41
+ graphite_user=test
42
+ graphite_password=XXXXX
50
43
 
51
44
  # The period for sending the metrics
52
45
  # its format is the one of rufus-scheduler
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.8
1
+ 0.2.0
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__),"..","lib")))
3
+ require 'rubygems'
4
+ require 'munin2graphite'
5
+
6
+ #if ARGV.last && File.stat(ARGV.last)
7
+ # Munin2Graphite::Config.config_file = ARGV.last
8
+ #else
9
+ Munin2Graphite::Config.config_file = "/etc/munin2graphite/munin2graphite.conf"
10
+ #end
11
+
12
+ Thread.abort_on_exception = true
13
+
14
+ scheduler = Munin2Graphite::Scheduler.new(Munin2Graphite::Config)
15
+ if ( ARGV.first == "graphs" )
16
+ scheduler.start1r_graphs
17
+ else
18
+ scheduler.start1r_metrics
19
+ end
@@ -14,14 +14,16 @@ carbon_hostname=localhost
14
14
  carbon_port=2003
15
15
 
16
16
  # Graphite endpoint
17
- # This is needed to send graph data to graphite
18
- graphite_endpoint=http://graphite/
17
+ # The url of the grphite-web application this is used to config the graphs
18
+ graphite_endpoint=http://graphite_webapp_hostname:port/
19
19
 
20
20
  # prefix for the metrics usually, the user name have to be put as a prefix
21
- graphite_metric_prefix=
22
- graphite_graph_prefix=
21
+ graphite_prefix=prefix
23
22
  graphite_user=test
24
- graphite_password=
23
+ graphite_password=XXXXX
24
+
25
+ # Prepend nodename to graph legend (default no)
26
+ # graph_legend_prepend=
25
27
 
26
28
  # The period for sending the metrics and the graph info
27
29
  # its format is the one of rufus-scheduler
data/lib/ast_node.rb CHANGED
@@ -4,6 +4,12 @@ class ASTNode
4
4
 
5
5
  attr_accessor :properties, :children, :parent , :root_node, :graph_properties
6
6
 
7
+ DEFAULT_GRAPH_PROPERTIES = {"hideLegend" => "false"}
8
+
9
+ # An array of proc functions to be applied on compile time, the first argument is the metric node and the second, the current string
10
+ # its result will be assigned to the compiled string
11
+ METRIC_PROC_FUNCTIONS = [ Proc.new { |metric,aux| metric.properties[:is_negative] ? aux : "cactiStyle(#{aux})" } ]
12
+
7
13
  def default_colors
8
14
  %w(#00CC00 #0066B3 #FF8000 #FFCC00 #330099 #990099 #CCFF00 #FF0000 #808080
9
15
  #008F00 #00487D #B35A00 #B38F00 #6B006B #8FB300 #B30000 #BEBEBE
@@ -16,7 +22,7 @@ class ASTNode
16
22
  @raw_data = raw_data
17
23
  @children = []
18
24
  @properties = {'graph_period' => "seconds","category" => "other"}
19
- @graph_properties = {}
25
+ @graph_properties = DEFAULT_GRAPH_PROPERTIES
20
26
  @graph_properties[:colorList] = default_colors
21
27
  @parent = nil
22
28
  end
@@ -189,7 +195,14 @@ class GraphPrintFormatGlobalDeclarationNode < GlobalDeclarationNode; end
189
195
  class FieldDeclarationNode < ASTNode
190
196
 
191
197
  def metric
192
- "#{root_node.properties['graphite_metric_prefix']}.#{root_node.properties['hostname'].split('.').first}.#{root_node.properties['category']}.#{root_node.properties['metric']}.#{children.first.metric}"
198
+ [
199
+ root_node.properties['graphite_user'],
200
+ root_node.properties['graphite_prefix'],
201
+ root_node.properties['hostname'].split('.').first,
202
+ root_node.properties['category'],
203
+ root_node.properties['metric'],
204
+ children.first.metric
205
+ ].reject{|i| i == "" }.compact.join(".")
193
206
  end
194
207
 
195
208
  def compile
@@ -200,15 +213,29 @@ class FieldDeclarationNode < ASTNode
200
213
  if self.root_node.properties[:logarithmic]
201
214
  # NOT IMPLEMENTED the logarithmic means that a logarithmic scale is to be used not that a log function has to be implemented aux = "log(#{aux},10)"
202
215
  end
216
+
203
217
  if self.properties[:stacked]
204
218
  aux = "stacked(#{aux})"
205
219
  end
220
+
221
+ if self.properties[:yMax] && !self.properties[:proccessed]
222
+ self.properties[:proccessed] = true
223
+ return self.compile
224
+ end
225
+
206
226
  if self.properties[:is_negative]
207
227
  aux = "scale(#{aux},-1)"
228
+ self.properties[:alias] = "" # legend is discarded in this case (munin does so)
208
229
  end
230
+
209
231
  if self.properties[:alias]
210
232
  aux = "alias(#{aux},'#{self.properties[:alias]}')"
211
233
  end
234
+
235
+ METRIC_PROC_FUNCTIONS.each do |proc|
236
+ aux = proc.call(self,aux)
237
+ end
238
+
212
239
  if self.properties[:hide]
213
240
  return nil
214
241
  else
@@ -266,7 +293,12 @@ class TypeFieldPropertyNode < FieldPropertyNode
266
293
  if @value == "DERIVE" || @value == "COUNTER"
267
294
  # The scaling is because of the minutes/(60*seconds)"
268
295
  #return "scale(nonNegativeDerivative(#{operand}),0.0166666666666667)"
269
- return "scaleToSeconds(nonNegativeDerivative(#{operand}),1)"
296
+
297
+ if parent.properties[:yMax]
298
+ return "scaleToSeconds(nonNegativeDerivative(#{operand},#{parent.properties[:yMax]}),1)"
299
+ else
300
+ return "scaleToSeconds(nonNegativeDerivative(#{operand}),1)"
301
+ end
270
302
  end
271
303
  operand
272
304
  end
@@ -292,8 +324,7 @@ end
292
324
 
293
325
  class MaxFieldPropertyNode < FieldPropertyNode
294
326
  def apply_function(operand)
295
- self.root_node.graph_properties[:yMax] ||= @value.to_i
296
- self.root_node.graph_properties[:yMax] = @value.to_i if self.root_node.graph_properties[:yMax] < @value.to_i
327
+ parent.properties[:yMax] = @value.to_i
297
328
  return operand
298
329
  end
299
330
  end
data/lib/graphite/base.rb CHANGED
@@ -1,25 +1,29 @@
1
1
  require 'net/http'
2
2
 
3
3
  module Graphite
4
- class Base
4
+ class Base
5
5
 
6
+ @@path = ""
6
7
 
7
8
  # connection instance (shared with every instance of the class)
8
9
  def self.connection
10
+ @@path = ""
9
11
  @init_header ||= {}
10
12
  @@connection ||= begin
11
- endpoint_uri = URI.parse(@@endpoint)
12
- @@path = endpoint_uri.path
13
- Net::HTTP.new(endpoint_uri.host, endpoint_uri.port)
14
- end
13
+ endpoint_uri = URI.parse(@@endpoint)
14
+ @@path = endpoint_uri.path
15
+ Net::HTTP.new(endpoint_uri.host, endpoint_uri.port)
16
+ end
15
17
  end
16
18
 
17
19
  # If the operation needs authentication you have to call this first
18
20
  def self.authenticate(user = @@user,password = @@password)
19
- response = self.connection.post(@@path + "account/login","nextPage=/&password=#{password}&username=#{user}")
21
+ url = @@path + "/account/login"
22
+ url.gsub!("//","/")
23
+ response = self.connection.post(url,"nextPage=/&password=#{password}&username=#{user}")
20
24
  @@init_header = {"Cookie" => response.get_fields('Set-Cookie').first}
21
25
  end
22
-
26
+
23
27
  def self.set_connection(endpoint,user = "",password = "")
24
28
  @@endpoint = endpoint
25
29
  @@user ||= user
@@ -28,7 +32,9 @@ module Graphite
28
32
 
29
33
  # Get
30
34
  def self.get(path,args)
31
- self.connection.get(@@path + path + "?" + args.map { |i,j| i.to_s + "=" + j }.join("&"),@@init_header)
35
+ mpath = (@@path + path).gsub("//","/")
36
+ self.connection.get(mpath + "?" + args.map { |i,j| i.to_s + "=" + j }.join("&"),@@init_header)
32
37
  end
38
+
33
39
  end
34
40
  end
@@ -55,7 +55,7 @@ module Munin2Graphite
55
55
  end
56
56
 
57
57
  def check_config
58
- fields={:carbon => [:hostname,:port],:graphite => [:endpoint,:metric_prefix,:user,:password],:scheduler => [:metrics_period,:graphs_period]}
58
+ fields={:carbon => [:hostname,:port],:graphite => [:endpoint,:prefix,:user,:password],:scheduler => [:metrics_period,:graphs_period]}
59
59
  fields.each do |k,v|
60
60
  v.each do |inner_field|
61
61
  field = "#{k}_#{inner_field}"
@@ -41,8 +41,8 @@ module Munin2Graphite
41
41
  raise "CategoryNotFound in #{config}"
42
42
  end
43
43
 
44
- def munin_config
45
- return @munin_config if @munin_config
44
+ def munin_config(reload = false)
45
+ return @munin_config if @munin_config && !reload
46
46
  @munin_config = {}
47
47
  @config.log.info("Obtaining metrics configuration")
48
48
  @munin_config[:workers] = []
@@ -52,8 +52,14 @@ module Munin2Graphite
52
52
  threads << Thread.new do
53
53
  current_config = {}
54
54
  config = @config.config_for_worker(worker)
55
- munin_worker = Munin::Node.new(config["munin_hostname"],config["munin_port"])
56
- nodes = config["munin_nodes"] ? config["munin_nodes"].split(",") : munin_worker.nodes
55
+ begin
56
+ munin_worker = Munin::Node.new(config["munin_hostname"],config["munin_port"])
57
+ nodes = config["munin_nodes"] ? config["munin_nodes"].split(",") : munin_worker.nodes
58
+ rescue Exception => e
59
+ config.log.error("Error when trying to connect to munin-node on #{config["munin_hostname"]}:#{config["munin_port"]}")
60
+ config.log.error("This node will be skipped")
61
+ exit
62
+ end
57
63
  current_config[:nodes] = {}
58
64
  semaphore_nodes = Mutex.new
59
65
  threads_nodes = []
@@ -69,6 +75,15 @@ module Munin2Graphite
69
75
  begin
70
76
  raw_config = munin.config(metric,true)[metric]
71
77
  category = category_from_config(raw_config)
78
+ # We prepend the worker name to the graph title for clarity
79
+ if config["graph_legend_prepend"] == "true"
80
+ nodename = config["graphite_name_schema"] == "worker" ? worker : node
81
+ if raw_config.match("graph_title ")
82
+ raw_config.gsub!("graph_title ","graph_itle #{nodename} ")
83
+ else
84
+ raw_config << "\ngraph_title #{nodename}"
85
+ end
86
+ end
72
87
  semaphore_nodes.synchronize do
73
88
  current_config[:nodes][node][:metrics][metric] = {
74
89
  :config => munin.config(metric)[metric],
@@ -103,13 +118,13 @@ module Munin2Graphite
103
118
  #
104
119
  # This is the loop of the metrics scheduling
105
120
  def obtain_metrics(worker = "global")
106
- config = @config.config_for_worker("global")
121
+ my_munin_config = munin_config.dup
107
122
  time = Time.now
108
123
  config = @config.config_for_worker(worker)
109
124
  config.log.info("Worker #{worker}")
110
- metric_base = config["graphite_metric_prefix"]
125
+ metric_base = [config["graphite_user"], config["graphite_prefix"]].reject{|i| i== ""}.compact.join(".")
111
126
 
112
- munin_config[worker][:nodes].each do |node,node_info|
127
+ my_munin_config[worker][:nodes].each do |node,node_info|
113
128
  node_name = metric_base + "." + node.split(".").first
114
129
  config.log.debug("Doing #{node_name}")
115
130
  values = {}
@@ -151,12 +166,12 @@ module Munin2Graphite
151
166
  carbon.send(string_to_send)
152
167
  carbon.flush
153
168
  carbon.close
154
- end if munin_config[worker]
169
+ end if my_munin_config[worker]
155
170
  @config.log.info("End getting metrics for worker #{worker}, elapsed time (#{Time.now - time}s)")
156
171
  end
157
172
 
158
173
  def obtain_graphs
159
- munin_config
174
+ munin_config(true)
160
175
  munin_config[:workers].each do |worker|
161
176
  time = Time.now
162
177
  config = @config.config_for_worker worker
@@ -194,6 +209,19 @@ module Munin2Graphite
194
209
  end
195
210
  end
196
211
 
212
+ def start1r_metrics
213
+ @config.log.info("One-run started: metrics")
214
+ workers.each do |worker|
215
+ config = @config.config_for_worker worker
216
+ metric_loop(worker)
217
+ end
218
+ end
219
+
220
+ def start1r_graphs
221
+ @config.log.info("One-run started: graphs")
222
+ obtain_graphs
223
+ end
224
+
197
225
  def start
198
226
  @config.log.info("Scheduler started")
199
227
  obtain_graphs
@@ -205,6 +233,14 @@ module Munin2Graphite
205
233
  @scheduler.every config["scheduler_metrics_period"] do
206
234
  metric_loop(worker)
207
235
  end
236
+
237
+ =begin
238
+ # Graph rereading is disabled by now there are concurrency problems
239
+ @scheduler.every config["scheduler_graphs_period"] do
240
+ obtain_graphs
241
+ end
242
+ =end
243
+
208
244
  end
209
245
  end
210
246
  end
data/lib/munin_graph.rb CHANGED
@@ -22,7 +22,7 @@ require 'graphite'
22
22
 
23
23
  ##
24
24
  # This class allows the transformation between graphite and munin config. It constructs an AST parsing the munin config information and
25
- # allows to output a valid graphic in graphite url format
25
+ # outputs a valid graphic in graphite url format
26
26
  # Jose Fernandez 2011
27
27
  #
28
28
  class MuninGraph
@@ -47,8 +47,13 @@ class MuninGraph
47
47
  graph.url = self.root.url
48
48
  self.root.properties[:category] ||= "other"
49
49
 
50
+ if @config["graphite_prefix"] == "" || !@config["graphite_prefix"] && @config["graphite_graph_prefix"] && @config["graphite_graph_prefix"] != ""
51
+ puts "DEPRECATION WARNING: parameter graphite_graph_prefix is not used anymore, please use graphite_prefix instead."
52
+ @config["graphite_prefix"] = @config["graphite_graph_prefix"]
53
+ end
54
+
50
55
  graph.name = "#{@config["hostname"]}.#{self.root.properties["category"]}.#{self.root.properties["metric"]}"
51
- graph.name = "#{@config["graphite_graph_prefix"]}.#{graph.name}" if @config["graphite_graph_prefix"] && @config["graphite_graph_prefix"] != ""
56
+ graph.name = "#{@config["graphite_prefix"]}.#{graph.name}" if @config["graphite_prefix"] && @config["graphite_prefix"] != ""
52
57
  return graph
53
58
  end
54
59
 
@@ -5,14 +5,14 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "munin2graphite"
8
- s.version = "0.1.8"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jose Fernandez (magec)"]
12
- s.date = "2012-08-13"
12
+ s.date = "2012-10-16"
13
13
  s.description = "This gem will install as a daemon and can be used to connect to a graphite and a carbon backend. It will not only post the data for the metrics but also create graphs into graphite, by means of a translation from munin-node."
14
14
  s.email = "jfernandezperez@gmail.com"
15
- s.executables = ["munin2gdash", "munin2graphite", "munin2graphite-daemon"]
15
+ s.executables = ["munin2graphite-daemon", "munin2gdash", "munin2graphite", "munin2graphite-1r"]
16
16
  s.extra_rdoc_files = [
17
17
  "LICENSE.txt",
18
18
  "README.markdown"
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "bin/munin2gdash",
27
27
  "bin/munin2graphite",
28
+ "bin/munin2graphite-1r",
28
29
  "bin/munin2graphite-daemon",
29
30
  "conf/munin2graphite.conf.example",
30
31
  "etc/munin2graphite/munin2graphite.conf.example",
@@ -43,6 +44,7 @@ Gem::Specification.new do |s|
43
44
  "munin2graphite.gemspec",
44
45
  "test/munin2graphite/config_test.rb",
45
46
  "test/test_config.rb",
47
+ "test/test_graphite.rb",
46
48
  "test/test_init.rb",
47
49
  "test/test_munin.rb",
48
50
  "test/test_munin_graph.rb",
@@ -52,17 +54,8 @@ Gem::Specification.new do |s|
52
54
  s.homepage = "http://github.com/magec/munin2graphite"
53
55
  s.licenses = ["MIT"]
54
56
  s.require_paths = ["lib"]
55
- s.rubygems_version = "1.8.10"
57
+ s.rubygems_version = "1.8.24"
56
58
  s.summary = "Allows to post both data and graphic info from munin to graphite (https://launchpad.net/graphite)"
57
- s.test_files = [
58
- "test/munin2graphite/config_test.rb",
59
- "test/test_config.rb",
60
- "test/test_init.rb",
61
- "test/test_munin.rb",
62
- "test/test_munin_graph.rb",
63
- "test/test_my_graph.rb",
64
- "test/test_scheduler.rb"
65
- ]
66
59
 
67
60
  if s.respond_to? :specification_version then
68
61
  s.specification_version = 3
@@ -73,8 +66,7 @@ Gem::Specification.new do |s|
73
66
  s.add_runtime_dependency(%q<parseconfig>, [">= 0"])
74
67
  s.add_runtime_dependency(%q<munin-ruby>, ["~> 0.2.1"])
75
68
  s.add_runtime_dependency(%q<json>, ["~> 1.6.3"])
76
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
77
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
69
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
78
70
  s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
79
71
  else
80
72
  s.add_dependency(%q<rufus-scheduler>, ["= 2.0.10"])
@@ -82,8 +74,7 @@ Gem::Specification.new do |s|
82
74
  s.add_dependency(%q<parseconfig>, [">= 0"])
83
75
  s.add_dependency(%q<munin-ruby>, ["~> 0.2.1"])
84
76
  s.add_dependency(%q<json>, ["~> 1.6.3"])
85
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
86
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
77
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
87
78
  s.add_dependency(%q<yard>, ["~> 0.6.0"])
88
79
  end
89
80
  else
@@ -92,8 +83,7 @@ Gem::Specification.new do |s|
92
83
  s.add_dependency(%q<parseconfig>, [">= 0"])
93
84
  s.add_dependency(%q<munin-ruby>, ["~> 0.2.1"])
94
85
  s.add_dependency(%q<json>, ["~> 1.6.3"])
95
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
96
- s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
86
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
97
87
  s.add_dependency(%q<yard>, ["~> 0.6.0"])
98
88
  end
99
89
  end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),"/test_init"))
2
+
3
+ class TestGraphite < Test::Unit::TestCase
4
+
5
+ def test_endpoint
6
+ assert_nothing_thrown {
7
+ Graphite::Base.set_connection(Munin2Graphite::Config["graphite_endpoint"])
8
+ Graphite::Base.authenticate(Munin2Graphite::Config["graphite_user"],Munin2Graphite::Config["graphite_password"])
9
+ }
10
+ end
11
+
12
+ def test_different_endpoint
13
+ endpoint_uri = URI.parse(Munin2Graphite::Config["graphite_endpoint"])
14
+ assert_nothing_thrown {
15
+ Graphite::Base.set_connection("http://#{endpoint_uri.host}:80")
16
+ Graphite::Base.authenticate(Munin2Graphite::Config["graphite_user"],Munin2Graphite::Config["graphite_password"])
17
+ }
18
+ end
19
+
20
+ def test_different_endpoint_with_path
21
+ endpoint_uri = URI.parse(Munin2Graphite::Config["graphite_endpoint"])
22
+ assert_nothing_thrown {
23
+ Graphite::Base.set_connection("http://#{endpoint_uri.host}:80////")
24
+ Graphite::Base.authenticate(Munin2Graphite::Config["graphite_user"],Munin2Graphite::Config["graphite_password"])
25
+ }
26
+ end
27
+
28
+ end
@@ -107,7 +107,7 @@ END
107
107
  root = @simple_graph.root
108
108
  root.compile
109
109
  field_declarations = root.children_of_class(FieldDeclarationNode)
110
- assert_equal field_declarations.first.compile,"alias(test.frontends.linux.myhost.sensors.acpi.THM0,'THM0')"
110
+ assert_match "alias(test.frontends.linux.myhost.sensors.acpi.THM0,'THM0')", field_declarations.first.compile
111
111
  assert_equal root.graph_properties[:vtitle], "Celcius"
112
112
  assert_equal root.graph_properties[:title], "ACPI Thermal zone temperatures"
113
113
  end
@@ -116,8 +116,7 @@ END
116
116
  root = @apache_graph.root
117
117
  field_declarations = root.children_of_class(FieldDeclarationNode)
118
118
  root.compile
119
- assert_equal field_declarations.first.compile,"alias(scaleToSeconds(nonNegativeDerivative(test.frontends.linux.myhost.apache.apache_accesses.accesses80),1),'port 80')"
120
- assert_equal root.graph_properties[:yMax], 1000000
119
+ assert_match "alias(scaleToSeconds(nonNegativeDerivative(test.frontends.linux.myhost.apache.apache_accesses.accesses80,1000000),1),'port 80')",field_declarations.first.compile
121
120
  assert_equal root.graph_properties[:yMin], 0
122
121
  assert_equal root.properties[:base] , 1000
123
122
  assert_equal root.graph_properties[:title], "Apache accesses"
@@ -218,14 +217,13 @@ up.negative down
218
217
  up.cdef up,8,*
219
218
  up.max 1000000000
220
219
  up.info Traffic of the eth2 interface. Maximum speed is 1000 Mbps.
221
- down.max 1000000000
222
220
  END
223
221
  )
224
222
  graph.config = Munin2Graphite::Config.merge({ 'metric' => "load",'hostname' => "localhost"})
225
223
  graph.root.compile
226
224
  color_list = graph.root.graph_properties[:colorList]
227
225
  assert_equal color_list.first , color_list[1] # Thew should be drawn with the same color
228
- assert_match graph.root.url , /alias\(scale\(scale\(scaleToSeconds\(nonNegativeDerivative\(test.frontends.linux.localhost.network.load.down\),1\),8\),-1/
226
+ assert_match graph.root.url , /scale\(scale\(scaleToSeconds\(nonNegativeDerivative\(test.frontends.linux.localhost.network.load.down\),1\),8\)/
229
227
  assert_equal graph.root.children_of_class(FieldDeclarationNode).length , 2
230
228
  graph.root.url
231
229
  end
@@ -282,5 +280,92 @@ END
282
280
  end
283
281
 
284
282
 
283
+ def test_negative_graphs
284
+ graph = MuninGraph.new(<<END
285
+ graph_order down up
286
+ graph_title eth0 traffic
287
+ graph_args --base 1000
288
+ graph_vlabel bits in (-) / out (+) per ${graph_period}
289
+ graph_category network
290
+ graph_info This graph shows the traffic of the eth0 network interface. Please note that the traffic is shown in bits per second, not bytes. IMPORTANT: On 32 bit systems the data source for this plugin uses 32bit counters, which makes the plugin unreliable and unsuitable for most 100Mb (or faster) interfaces, where traffic is expected to exceed 50Mbps over a 5 minute period. This means that this plugin is unsuitable for most 32 bit production environments. To avoid this problem, use the ip_ plugin instead. There should be no problems on 64 bit systems running 64 bit kernels.
291
+ down.label received
292
+ down.type COUNTER
293
+ down.graph no
294
+ down.cdef down,8,*
295
+ up.label bps
296
+ up.type COUNTER
297
+ up.negative down
298
+ up.cdef up,8,*
299
+ up.max 1000000000
300
+ up.info Traffic of the eth0 interface. Maximum speed is 1000 Mbps.
301
+ down.max 1000000000
302
+ END
303
+ )
304
+ graph.config = Munin2Graphite::Config.merge({ "graphite_user" => "",'metric' => "if_eth0",'hostname' => "test"})
305
+ graph.root.compile
306
+ assert_not_match graph.root.url, /received/
307
+ end
308
+
309
+ def test_network
310
+ graph = MuninGraph.new(<<END
311
+ graph_category gtw.gtw4
312
+ graph_title gtw4
313
+ graph_info Model: 7206VXR Firmware: 12.2(15)T8
314
+ graph_args --base 1000
315
+ graph_vlabel Octets in (G) / out (B) per ${graph_period}
316
+ GigabitEthernet0_2_octets_in.label Conn
317
+ GigabitEthernet0_2_octets_in.negative GigabitEthernet0_2_octets_out
318
+ GigabitEthernet0_2_octets_in.draw LINE1
319
+ GigabitEthernet0_2_octets_in.type DERIVE
320
+ GigabitEthernet0_2_octets_in.cdef GigabitEthernet0_2_octets_in,8,*
321
+ GigabitEthernet0_2_octets_in.max 2000000000
322
+ GigabitEthernet0_2_octets_in.min 0
323
+ GigabitEthernet0_2_octets_out.label Conn
324
+ GigabitEthernet0_2_octets_out.draw LINE1
325
+ GigabitEthernet0_2_octets_out.type DERIVE
326
+ GigabitEthernet0_2_octets_out.cdef GigabitEthernet0_2_octets_out,8,*
327
+ GigabitEthernet0_2_octets_out.max 2000000000
328
+ GigabitEthernet0_2_octets_out.min 0
329
+ FastEthernet1_0_octets_in.label VLAN Internet - IN
330
+ FastEthernet1_0_octets_in.negative FastEthernet1_0_octets_out
331
+ FastEthernet1_0_octets_in.draw LINE1
332
+ FastEthernet1_0_octets_in.type DERIVE
333
+ FastEthernet1_0_octets_in.cdef FastEthernet1_0_octets_in,8,*
334
+ FastEthernet1_0_octets_in.max 2000000000
335
+ FastEthernet1_0_octets_in.min 0
336
+ FastEthernet1_0_octets_out.label VLAN Internet - OUT
337
+ FastEthernet1_0_octets_out.draw LINE1
338
+ FastEthernet1_0_octets_out.type DERIVE
339
+ FastEthernet1_0_octets_out.cdef FastEthernet1_0_octets_out,8,*
340
+ FastEthernet1_0_octets_out.max 2000000000
341
+ FastEthernet1_0_octets_out.min 0
342
+ FastEthernet1_1_octets_in.label FW
343
+ FastEthernet1_1_octets_in.negative FastEthernet1_1_octets_out
344
+ FastEthernet1_1_octets_in.draw LINE1
345
+ FastEthernet1_1_octets_in.type DERIVE
346
+ FastEthernet1_1_octets_in.cdef FastEthernet1_1_octets_in,8,*
347
+ FastEthernet1_1_octets_in.max 2000000000
348
+ FastEthernet1_1_octets_in.min 0
349
+ FastEthernet1_1_octets_out.label FW
350
+ FastEthernet1_1_octets_out.draw LINE1
351
+ FastEthernet1_1_octets_out.type DERIVE
352
+ FastEthernet1_1_octets_out.cdef FastEthernet1_1_octets_out,8,*
353
+ FastEthernet1_1_octets_out.max 2000000000
354
+ FastEthernet1_1_octets_out.min 0
355
+ END
356
+ )
357
+ graph.config = Munin2Graphite::Config.merge({ "graphite_prefix" => "","munin_nodes" => "routers", "graphite_user" => "network",'metric' => "snmp_routers_gtw_gtw4_octets",'hostname' => "routers"})
358
+ graph.root.compile
359
+ assert_not_match graph.root.url, /received/
360
+ assert_not_match graph.root.url, /\.\./
361
+ end
362
+
363
+ def test_default_graph_properties
364
+ graph = MuninGraph.new("")
365
+ graph.config = Munin2Graphite::Config
366
+ graph.root.compile
367
+ assert_match graph.root.url, /#{ASTNode::DEFAULT_GRAPH_PROPERTIES.keys.first}/
368
+
369
+ end
285
370
 
286
371
  end
@@ -1,5 +1,4 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__),"/test_init"))
2
- require 'rspec-mocks'
3
2
 
4
3
  class TestMuninGraph < Test::Unit::TestCase
5
4
 
@@ -11,16 +10,20 @@ class TestMuninGraph < Test::Unit::TestCase
11
10
  @scheduler = Munin2Graphite::Scheduler.new(Munin2Graphite::Config)
12
11
  @scheduler.obtain_metrics
13
12
  end
14
-
13
+
15
14
  def test_obtain_graphs
16
15
  @scheduler = Munin2Graphite::Scheduler.new(Munin2Graphite::Config)
17
16
  @scheduler.obtain_graphs
18
17
  end
19
18
 
19
+ def test_obtain_graphs_when_it_cannot_connect
20
+ Munin2Graphite::Config.config.params["test_worker1"]["munin_hostname"] = "192.168.1.1"
21
+ @scheduler = Munin2Graphite::Scheduler.new(Munin2Graphite::Config)
22
+ assert_nothing_thrown { @scheduler.obtain_graphs }
23
+ end
24
+
20
25
  def test_send_graphs
21
- mockSocket = mock( TCPSocket )
22
26
  @scheduler = Munin2Graphite::Scheduler.new(Munin2Graphite::Config)
23
- @scheduler.carbon = mockSocket
24
27
  @scheduler.obtain_metrics
25
28
  end
26
29
 
metadata CHANGED
@@ -1,117 +1,145 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: munin2graphite
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.8
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Jose Fernandez (magec)
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-08-13 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rufus-scheduler
16
- requirement: &70102053585380 !ruby/object:Gem::Requirement
17
+
18
+ date: 2012-10-16 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ requirement: &id001 !ruby/object:Gem::Requirement
17
22
  none: false
18
- requirements:
19
- - - =
20
- - !ruby/object:Gem::Version
23
+ requirements:
24
+ - - "="
25
+ - !ruby/object:Gem::Version
26
+ hash: 27
27
+ segments:
28
+ - 2
29
+ - 0
30
+ - 10
21
31
  version: 2.0.10
22
- type: :runtime
32
+ version_requirements: *id001
33
+ name: rufus-scheduler
23
34
  prerelease: false
24
- version_requirements: *70102053585380
25
- - !ruby/object:Gem::Dependency
26
- name: daemons
27
- requirement: &70102053584900 !ruby/object:Gem::Requirement
35
+ type: :runtime
36
+ - !ruby/object:Gem::Dependency
37
+ requirement: &id002 !ruby/object:Gem::Requirement
28
38
  none: false
29
- requirements:
30
- - - =
31
- - !ruby/object:Gem::Version
39
+ requirements:
40
+ - - "="
41
+ - !ruby/object:Gem::Version
42
+ hash: 27
43
+ segments:
44
+ - 1
45
+ - 1
46
+ - 4
32
47
  version: 1.1.4
33
- type: :runtime
48
+ version_requirements: *id002
49
+ name: daemons
34
50
  prerelease: false
35
- version_requirements: *70102053584900
36
- - !ruby/object:Gem::Dependency
37
- name: parseconfig
38
- requirement: &70102053584420 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
44
51
  type: :runtime
52
+ - !ruby/object:Gem::Dependency
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ version_requirements: *id003
63
+ name: parseconfig
45
64
  prerelease: false
46
- version_requirements: *70102053584420
47
- - !ruby/object:Gem::Dependency
48
- name: munin-ruby
49
- requirement: &70102053583940 !ruby/object:Gem::Requirement
65
+ type: :runtime
66
+ - !ruby/object:Gem::Dependency
67
+ requirement: &id004 !ruby/object:Gem::Requirement
50
68
  none: false
51
- requirements:
69
+ requirements:
52
70
  - - ~>
53
- - !ruby/object:Gem::Version
71
+ - !ruby/object:Gem::Version
72
+ hash: 21
73
+ segments:
74
+ - 0
75
+ - 2
76
+ - 1
54
77
  version: 0.2.1
55
- type: :runtime
78
+ version_requirements: *id004
79
+ name: munin-ruby
56
80
  prerelease: false
57
- version_requirements: *70102053583940
58
- - !ruby/object:Gem::Dependency
59
- name: json
60
- requirement: &70102053583440 !ruby/object:Gem::Requirement
81
+ type: :runtime
82
+ - !ruby/object:Gem::Dependency
83
+ requirement: &id005 !ruby/object:Gem::Requirement
61
84
  none: false
62
- requirements:
85
+ requirements:
63
86
  - - ~>
64
- - !ruby/object:Gem::Version
87
+ - !ruby/object:Gem::Version
88
+ hash: 9
89
+ segments:
90
+ - 1
91
+ - 6
92
+ - 3
65
93
  version: 1.6.3
66
- type: :runtime
94
+ version_requirements: *id005
95
+ name: json
67
96
  prerelease: false
68
- version_requirements: *70102053583440
69
- - !ruby/object:Gem::Dependency
70
- name: bundler
71
- requirement: &70102053582960 !ruby/object:Gem::Requirement
97
+ type: :runtime
98
+ - !ruby/object:Gem::Dependency
99
+ requirement: &id006 !ruby/object:Gem::Requirement
72
100
  none: false
73
- requirements:
101
+ requirements:
74
102
  - - ~>
75
- - !ruby/object:Gem::Version
76
- version: 1.0.0
77
- type: :development
78
- prerelease: false
79
- version_requirements: *70102053582960
80
- - !ruby/object:Gem::Dependency
103
+ - !ruby/object:Gem::Version
104
+ hash: 63
105
+ segments:
106
+ - 1
107
+ - 8
108
+ - 4
109
+ version: 1.8.4
110
+ version_requirements: *id006
81
111
  name: jeweler
82
- requirement: &70102053582480 !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
85
- - - ~>
86
- - !ruby/object:Gem::Version
87
- version: 1.5.2
88
- type: :development
89
112
  prerelease: false
90
- version_requirements: *70102053582480
91
- - !ruby/object:Gem::Dependency
92
- name: yard
93
- requirement: &70102053582000 !ruby/object:Gem::Requirement
113
+ type: :development
114
+ - !ruby/object:Gem::Dependency
115
+ requirement: &id007 !ruby/object:Gem::Requirement
94
116
  none: false
95
- requirements:
117
+ requirements:
96
118
  - - ~>
97
- - !ruby/object:Gem::Version
119
+ - !ruby/object:Gem::Version
120
+ hash: 7
121
+ segments:
122
+ - 0
123
+ - 6
124
+ - 0
98
125
  version: 0.6.0
99
- type: :development
126
+ version_requirements: *id007
127
+ name: yard
100
128
  prerelease: false
101
- version_requirements: *70102053582000
102
- description: This gem will install as a daemon and can be used to connect to a graphite
103
- and a carbon backend. It will not only post the data for the metrics but also create
104
- graphs into graphite, by means of a translation from munin-node.
129
+ type: :development
130
+ description: This gem will install as a daemon and can be used to connect to a graphite and a carbon backend. It will not only post the data for the metrics but also create graphs into graphite, by means of a translation from munin-node.
105
131
  email: jfernandezperez@gmail.com
106
- executables:
132
+ executables:
133
+ - munin2graphite-daemon
107
134
  - munin2gdash
108
135
  - munin2graphite
109
- - munin2graphite-daemon
136
+ - munin2graphite-1r
110
137
  extensions: []
111
- extra_rdoc_files:
138
+
139
+ extra_rdoc_files:
112
140
  - LICENSE.txt
113
141
  - README.markdown
114
- files:
142
+ files:
115
143
  - Gemfile
116
144
  - LICENSE.txt
117
145
  - README.markdown
@@ -119,6 +147,7 @@ files:
119
147
  - VERSION
120
148
  - bin/munin2gdash
121
149
  - bin/munin2graphite
150
+ - bin/munin2graphite-1r
122
151
  - bin/munin2graphite-daemon
123
152
  - conf/munin2graphite.conf.example
124
153
  - etc/munin2graphite/munin2graphite.conf.example
@@ -137,44 +166,44 @@ files:
137
166
  - munin2graphite.gemspec
138
167
  - test/munin2graphite/config_test.rb
139
168
  - test/test_config.rb
169
+ - test/test_graphite.rb
140
170
  - test/test_init.rb
141
171
  - test/test_munin.rb
142
172
  - test/test_munin_graph.rb
143
173
  - test/test_my_graph.rb
144
174
  - test/test_scheduler.rb
145
175
  homepage: http://github.com/magec/munin2graphite
146
- licenses:
176
+ licenses:
147
177
  - MIT
148
178
  post_install_message:
149
179
  rdoc_options: []
150
- require_paths:
180
+
181
+ require_paths:
151
182
  - lib
152
- required_ruby_version: !ruby/object:Gem::Requirement
183
+ required_ruby_version: !ruby/object:Gem::Requirement
153
184
  none: false
154
- requirements:
155
- - - ! '>='
156
- - !ruby/object:Gem::Version
157
- version: '0'
158
- segments:
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ hash: 3
189
+ segments:
159
190
  - 0
160
- hash: 1309715336698624535
161
- required_rubygems_version: !ruby/object:Gem::Requirement
191
+ version: "0"
192
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
193
  none: false
163
- requirements:
164
- - - ! '>='
165
- - !ruby/object:Gem::Version
166
- version: '0'
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ hash: 3
198
+ segments:
199
+ - 0
200
+ version: "0"
167
201
  requirements: []
202
+
168
203
  rubyforge_project:
169
- rubygems_version: 1.8.10
204
+ rubygems_version: 1.8.24
170
205
  signing_key:
171
206
  specification_version: 3
172
207
  summary: Allows to post both data and graphic info from munin to graphite (https://launchpad.net/graphite)
173
- test_files:
174
- - test/munin2graphite/config_test.rb
175
- - test/test_config.rb
176
- - test/test_init.rb
177
- - test/test_munin.rb
178
- - test/test_munin_graph.rb
179
- - test/test_my_graph.rb
180
- - test/test_scheduler.rb
208
+ test_files: []
209
+