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 +1 -2
- data/README.markdown +7 -14
- data/VERSION +1 -1
- data/bin/munin2graphite-1r +19 -0
- data/conf/munin2graphite.conf.example +7 -5
- data/lib/ast_node.rb +36 -5
- data/lib/graphite/base.rb +14 -8
- data/lib/munin2graphite/config.rb +1 -1
- data/lib/munin2graphite/scheduler.rb +45 -9
- data/lib/munin_graph.rb +7 -2
- data/munin2graphite.gemspec +9 -19
- data/test/test_graphite.rb +28 -0
- data/test/test_munin_graph.rb +90 -5
- data/test/test_scheduler.rb +7 -4
- metadata +129 -100
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 "
|
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
|
-
#
|
37
|
-
graphite_endpoint=http://
|
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
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
+
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
|
-
#
|
18
|
-
graphite_endpoint=http://
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
-
|
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,:
|
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
|
-
|
56
|
-
|
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
|
-
|
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["
|
125
|
+
metric_base = [config["graphite_user"], config["graphite_prefix"]].reject{|i| i== ""}.compact.join(".")
|
111
126
|
|
112
|
-
|
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
|
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
|
-
#
|
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["
|
56
|
+
graph.name = "#{@config["graphite_prefix"]}.#{graph.name}" if @config["graphite_prefix"] && @config["graphite_prefix"] != ""
|
52
57
|
return graph
|
53
58
|
end
|
54
59
|
|
data/munin2graphite.gemspec
CHANGED
@@ -5,14 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "munin2graphite"
|
8
|
-
s.version = "0.
|
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-
|
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-
|
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.
|
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<
|
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<
|
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<
|
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
|
data/test/test_munin_graph.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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 , /
|
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
|
data/test/test_scheduler.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
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
|
-
|
32
|
+
version_requirements: *id001
|
33
|
+
name: rufus-scheduler
|
23
34
|
prerelease: false
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
|
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
|
-
|
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
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
|
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
|
-
|
78
|
+
version_requirements: *id004
|
79
|
+
name: munin-ruby
|
56
80
|
prerelease: false
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
|
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
|
-
|
94
|
+
version_requirements: *id005
|
95
|
+
name: json
|
67
96
|
prerelease: false
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
-
|
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
|
-
|
91
|
-
- !ruby/object:Gem::Dependency
|
92
|
-
|
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
|
-
|
126
|
+
version_requirements: *id007
|
127
|
+
name: yard
|
100
128
|
prerelease: false
|
101
|
-
|
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-
|
136
|
+
- munin2graphite-1r
|
110
137
|
extensions: []
|
111
|
-
|
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
|
-
|
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
|
-
|
158
|
-
segments:
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
hash: 3
|
189
|
+
segments:
|
159
190
|
- 0
|
160
|
-
|
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
|
-
|
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.
|
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
|
-
|
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
|
+
|