munin2graphite 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +1 -0
- data/VERSION +1 -1
- data/etc/munin2graphite/munin2graphite.conf.example +1 -1
- data/lib/ast_node.rb +1 -1
- data/lib/carbon.rb +6 -1
- data/lib/graphite/base.rb +8 -4
- data/lib/munin2graphite/scheduler.rb +54 -28
- data/munin2graphite.gemspec +2 -2
- data/test/test_init.rb +2 -2
- data/test/test_munin_graph.rb +2 -2
- data/test/test_scheduler.rb +8 -0
- metadata +19 -19
data/README.markdown
CHANGED
@@ -51,6 +51,7 @@ Imagine, for example, that we have two munin-nodes in two different servers (mun
|
|
51
51
|
# The period for sending the metrics
|
52
52
|
# its format is the one of rufus-scheduler
|
53
53
|
scheduler_metrics_period=1m
|
54
|
+
scheduler_graphs_period=1m
|
54
55
|
|
55
56
|
# The munin node hostname and its port
|
56
57
|
munin_hostname=localhost
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.8
|
@@ -11,7 +11,7 @@ carbon_port=2003
|
|
11
11
|
|
12
12
|
# Graphite endpoint
|
13
13
|
# This is needed to send graph data to graphite
|
14
|
-
graphite_endpoint=http://graphite/
|
14
|
+
graphite_endpoint=http://graphite:port/pathprefix/
|
15
15
|
|
16
16
|
# prefix for the metrics usually, the user name have to be put as a prefix
|
17
17
|
graphite_metric_prefix=
|
data/lib/ast_node.rb
CHANGED
@@ -266,7 +266,7 @@ class TypeFieldPropertyNode < FieldPropertyNode
|
|
266
266
|
if @value == "DERIVE" || @value == "COUNTER"
|
267
267
|
# The scaling is because of the minutes/(60*seconds)"
|
268
268
|
#return "scale(nonNegativeDerivative(#{operand}),0.0166666666666667)"
|
269
|
-
return "
|
269
|
+
return "scaleToSeconds(nonNegativeDerivative(#{operand}),1)"
|
270
270
|
end
|
271
271
|
operand
|
272
272
|
end
|
data/lib/carbon.rb
CHANGED
@@ -19,10 +19,15 @@ require 'socket'
|
|
19
19
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20
20
|
|
21
21
|
class Carbon
|
22
|
+
|
23
|
+
def initialize(socket)
|
24
|
+
@carbon = socket
|
25
|
+
end
|
26
|
+
|
22
27
|
def initialize(chost='localhost', port=2003)
|
23
28
|
@carbon = TCPSocket.new(chost, port)
|
24
29
|
end
|
25
|
-
|
30
|
+
|
26
31
|
def send(msg)
|
27
32
|
@carbon.write(msg)
|
28
33
|
end
|
data/lib/graphite/base.rb
CHANGED
@@ -6,13 +6,17 @@ module Graphite
|
|
6
6
|
|
7
7
|
# connection instance (shared with every instance of the class)
|
8
8
|
def self.connection
|
9
|
-
|
10
|
-
@@connection ||=
|
9
|
+
@init_header ||= {}
|
10
|
+
@@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
|
11
15
|
end
|
12
16
|
|
13
17
|
# If the operation needs authentication you have to call this first
|
14
18
|
def self.authenticate(user = @@user,password = @@password)
|
15
|
-
response = self.connection.post("
|
19
|
+
response = self.connection.post(@@path + "account/login","nextPage=/&password=#{password}&username=#{user}")
|
16
20
|
@@init_header = {"Cookie" => response.get_fields('Set-Cookie').first}
|
17
21
|
end
|
18
22
|
|
@@ -24,7 +28,7 @@ module Graphite
|
|
24
28
|
|
25
29
|
# Get
|
26
30
|
def self.get(path,args)
|
27
|
-
self.connection.get(path + "?" + args.map { |i,j| i.to_s + "=" + j }.join("&"),@@init_header)
|
31
|
+
self.connection.get(@@path + path + "?" + args.map { |i,j| i.to_s + "=" + j }.join("&"),@@init_header)
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -16,6 +16,7 @@
|
|
16
16
|
# along with this program; if not, write to the Free Software
|
17
17
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
require 'rufus/scheduler'
|
19
|
+
require 'thread'
|
19
20
|
module Munin2Graphite
|
20
21
|
##
|
21
22
|
# This class holds the main scheduler of the system, it will perform the applicacion loops
|
@@ -27,6 +28,10 @@ module Munin2Graphite
|
|
27
28
|
@config = config
|
28
29
|
end
|
29
30
|
|
31
|
+
def carbon=(socket)
|
32
|
+
@carbon = Carbon.new(socket)
|
33
|
+
end
|
34
|
+
|
30
35
|
def category_from_config(config)
|
31
36
|
config.each_line do |configline|
|
32
37
|
if configline =~ /^graph_category ([\w\-_\.]+)$/
|
@@ -41,35 +46,53 @@ module Munin2Graphite
|
|
41
46
|
@munin_config = {}
|
42
47
|
@config.log.info("Obtaining metrics configuration")
|
43
48
|
@munin_config[:workers] = []
|
49
|
+
semaphore = Mutex.new
|
50
|
+
threads = []
|
44
51
|
workers.each do |worker|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
:
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
52
|
+
threads << Thread.new do
|
53
|
+
current_config = {}
|
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
|
57
|
+
current_config[:nodes] = {}
|
58
|
+
semaphore_nodes = Mutex.new
|
59
|
+
threads_nodes = []
|
60
|
+
nodes.each do |node|
|
61
|
+
threads_nodes << Thread.new do
|
62
|
+
munin = Munin::Node.new(config["munin_hostname"],config["munin_port"])
|
63
|
+
metrics = munin.list(node)
|
64
|
+
config.log.info("Config for node #{worker}::#{node}")
|
65
|
+
semaphore_nodes.synchronize do
|
66
|
+
current_config[:nodes][node] = { :metrics => {} }
|
67
|
+
end
|
68
|
+
metrics.each do |metric|
|
69
|
+
begin
|
70
|
+
raw_config = munin.config(metric,true)[metric]
|
71
|
+
category = category_from_config(raw_config)
|
72
|
+
semaphore_nodes.synchronize do
|
73
|
+
current_config[:nodes][node][:metrics][metric] = {
|
74
|
+
:config => munin.config(metric)[metric],
|
75
|
+
:raw_config => raw_config,
|
76
|
+
:category => category
|
77
|
+
}
|
78
|
+
end
|
79
|
+
rescue Exception
|
80
|
+
config.log.error("Error when trying to obtain graph conf for #{worker}::#{node}::#{metric} Ignored")
|
81
|
+
end
|
82
|
+
end
|
64
83
|
end
|
65
84
|
end
|
85
|
+
threads_nodes.each { |i| i.join }
|
86
|
+
# @config.log.debug(current_config.inspect)
|
87
|
+
semaphore.synchronize do
|
88
|
+
@munin_config[worker] = current_config
|
89
|
+
@munin_config[:workers] << worker
|
90
|
+
end
|
91
|
+
munin_worker.disconnect
|
92
|
+
config.log.info("Config for #{worker} obtained")
|
66
93
|
end
|
67
|
-
# @config.log.debug(current_config.inspect)
|
68
|
-
@munin_config[worker] = current_config
|
69
|
-
@munin_config[:workers] << worker
|
70
|
-
munin.disconnect
|
71
94
|
end
|
72
|
-
|
95
|
+
threads.each { |i| i.join }
|
73
96
|
@munin_config
|
74
97
|
end
|
75
98
|
|
@@ -102,21 +125,24 @@ module Munin2Graphite
|
|
102
125
|
local_munin = Munin::Node.new(config["munin_hostname"],config["munin_port"])
|
103
126
|
values[metric] = local_munin.fetch metric
|
104
127
|
local_munin.disconnect
|
105
|
-
rescue
|
128
|
+
rescue Exception => e
|
106
129
|
@config.log.error("There was a problem when getting the metric #{metric} for #{node} , Ignored")
|
130
|
+
@config.log.error(e.message)
|
131
|
+
@config.log.error(e.backtrace.inspect)
|
107
132
|
end
|
108
133
|
end
|
109
134
|
end
|
110
|
-
metrics_threads.each {|i| i.join
|
135
|
+
metrics_threads.each {|i| i.join}
|
111
136
|
config.log.debug(values.inspect)
|
112
137
|
config.log.info("Done with: #{node} (#{Time.now - metric_time} s)")
|
113
|
-
carbon = Carbon.new(config["carbon_hostname"],config["carbon_port"])
|
138
|
+
carbon = @carbon || Carbon.new(config["carbon_hostname"],config["carbon_port"])
|
114
139
|
string_to_send = ""
|
115
140
|
values.each do |metric,results|
|
116
141
|
category = node_info[:metrics][metric][:category]
|
117
142
|
results.each do |k,v|
|
118
143
|
v.each do |c_metric,c_value|
|
119
|
-
|
144
|
+
name = "#{node_name}.#{category}.#{metric}.#{c_metric}".gsub("-","_")
|
145
|
+
string_to_send += "#{name} #{c_value} #{Time.now.to_i}\n" if c_value != "U"
|
120
146
|
end
|
121
147
|
end
|
122
148
|
end
|
data/munin2graphite.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "munin2graphite"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.8"
|
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-08-13"
|
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
15
|
s.executables = ["munin2gdash", "munin2graphite", "munin2graphite-daemon"]
|
data/test/test_init.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$:.unshift(File.join(File.dirname(__FILE__) + "/../lib/"))
|
2
2
|
require 'rubygems'
|
3
3
|
require 'test/unit'
|
4
|
-
require '
|
4
|
+
require 'munin-ruby'
|
5
5
|
require 'graphite'
|
6
6
|
require 'munin2graphite'
|
7
7
|
require 'munin_graph'
|
@@ -9,5 +9,5 @@ require 'carbon'
|
|
9
9
|
|
10
10
|
TEST_CONFIG_FILE = File.join(File.dirname(__FILE__),"config.conf")
|
11
11
|
Munin2Graphite::Config.config_file = TEST_CONFIG_FILE
|
12
|
-
Graphite::Base.set_connection(Munin2Graphite::Config["
|
12
|
+
Graphite::Base.set_connection(Munin2Graphite::Config["graphite_endpoint"])
|
13
13
|
Graphite::Base.authenticate(Munin2Graphite::Config["graphite_user"],Munin2Graphite::Config["graphite_password"])
|
data/test/test_munin_graph.rb
CHANGED
@@ -116,7 +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(
|
119
|
+
assert_equal field_declarations.first.compile,"alias(scaleToSeconds(nonNegativeDerivative(test.frontends.linux.myhost.apache.apache_accesses.accesses80),1),'port 80')"
|
120
120
|
assert_equal root.graph_properties[:yMax], 1000000
|
121
121
|
assert_equal root.graph_properties[:yMin], 0
|
122
122
|
assert_equal root.properties[:base] , 1000
|
@@ -225,7 +225,7 @@ END
|
|
225
225
|
graph.root.compile
|
226
226
|
color_list = graph.root.graph_properties[:colorList]
|
227
227
|
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\(
|
228
|
+
assert_match graph.root.url , /alias\(scale\(scale\(scaleToSeconds\(nonNegativeDerivative\(test.frontends.linux.localhost.network.load.down\),1\),8\),-1/
|
229
229
|
assert_equal graph.root.children_of_class(FieldDeclarationNode).length , 2
|
230
230
|
graph.root.url
|
231
231
|
end
|
data/test/test_scheduler.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__),"/test_init"))
|
2
|
+
require 'rspec-mocks'
|
2
3
|
|
3
4
|
class TestMuninGraph < Test::Unit::TestCase
|
4
5
|
|
@@ -16,4 +17,11 @@ class TestMuninGraph < Test::Unit::TestCase
|
|
16
17
|
@scheduler.obtain_graphs
|
17
18
|
end
|
18
19
|
|
20
|
+
def test_send_graphs
|
21
|
+
mockSocket = mock( TCPSocket )
|
22
|
+
@scheduler = Munin2Graphite::Scheduler.new(Munin2Graphite::Config)
|
23
|
+
@scheduler.carbon = mockSocket
|
24
|
+
@scheduler.obtain_metrics
|
25
|
+
end
|
26
|
+
|
19
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: munin2graphite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-13 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rufus-scheduler
|
16
|
-
requirement: &
|
16
|
+
requirement: &70102053585380 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - =
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.0.10
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70102053585380
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: daemons
|
27
|
-
requirement: &
|
27
|
+
requirement: &70102053584900 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - =
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.1.4
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70102053584900
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: parseconfig
|
38
|
-
requirement: &
|
38
|
+
requirement: &70102053584420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70102053584420
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: munin-ruby
|
49
|
-
requirement: &
|
49
|
+
requirement: &70102053583940 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 0.2.1
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70102053583940
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: json
|
60
|
-
requirement: &
|
60
|
+
requirement: &70102053583440 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.6.3
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70102053583440
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
|
-
requirement: &
|
71
|
+
requirement: &70102053582960 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 1.0.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70102053582960
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: jeweler
|
82
|
-
requirement: &
|
82
|
+
requirement: &70102053582480 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: 1.5.2
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70102053582480
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: yard
|
93
|
-
requirement: &
|
93
|
+
requirement: &70102053582000 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: 0.6.0
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70102053582000
|
102
102
|
description: This gem will install as a daemon and can be used to connect to a graphite
|
103
103
|
and a carbon backend. It will not only post the data for the metrics but also create
|
104
104
|
graphs into graphite, by means of a translation from munin-node.
|
@@ -157,7 +157,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
157
157
|
version: '0'
|
158
158
|
segments:
|
159
159
|
- 0
|
160
|
-
hash:
|
160
|
+
hash: 1309715336698624535
|
161
161
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
162
|
none: false
|
163
163
|
requirements:
|