munin-ruby 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +42 -0
- data/.rspec +3 -0
- data/README.md +165 -0
- data/Rakefile +11 -0
- data/lib/munin-ruby.rb +6 -0
- data/lib/munin-ruby/cache.rb +34 -0
- data/lib/munin-ruby/connection.rb +98 -0
- data/lib/munin-ruby/errors.rb +8 -0
- data/lib/munin-ruby/node.rb +124 -0
- data/lib/munin-ruby/parser.rb +75 -0
- data/lib/munin-ruby/version.rb +5 -0
- data/munin-ruby.gemspec +19 -0
- data/spec/fixtures/config.txt +47 -0
- data/spec/fixtures/fetch.txt +15 -0
- data/spec/fixtures/list.txt +1 -0
- data/spec/fixtures/version.txt +1 -0
- data/spec/node_spec.rb +5 -0
- data/spec/parser_spec.rb +27 -0
- data/spec/spec_helper.rb +11 -0
- metadata +81 -0
data/.gitignore
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
!.gitignore
|
2
|
+
*.gem
|
3
|
+
*.rbc
|
4
|
+
*.sw[a-p]
|
5
|
+
*.tmproj
|
6
|
+
*.tmproject
|
7
|
+
*.un~
|
8
|
+
*~
|
9
|
+
.DS_Store
|
10
|
+
.Spotlight-V100
|
11
|
+
.Trashes
|
12
|
+
._*
|
13
|
+
.bundle
|
14
|
+
.config
|
15
|
+
.directory
|
16
|
+
.elc
|
17
|
+
.redcar
|
18
|
+
.yardoc
|
19
|
+
/.emacs.desktop
|
20
|
+
/.emacs.desktop.lock
|
21
|
+
Desktop.ini
|
22
|
+
Gemfile.lock
|
23
|
+
Icon?
|
24
|
+
InstalledFiles
|
25
|
+
Session.vim
|
26
|
+
Thumbs.db
|
27
|
+
\#*\#
|
28
|
+
_yardoc
|
29
|
+
auto-save-list
|
30
|
+
coverage
|
31
|
+
doc/
|
32
|
+
lib/bundler/man
|
33
|
+
pkg
|
34
|
+
pkg/*
|
35
|
+
rdoc
|
36
|
+
spec/reports
|
37
|
+
test/tmp
|
38
|
+
test/version_tmp
|
39
|
+
tmp
|
40
|
+
tmtags
|
41
|
+
tramp
|
42
|
+
lib/test.rb
|
data/.rspec
ADDED
data/README.md
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# Munin-Ruby
|
2
|
+
|
3
|
+
Munin-ruby is a sockets-based ruby client library to communicate and fetch information from munin-node servers.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Simple install using rubygems:
|
8
|
+
|
9
|
+
```
|
10
|
+
gem install munin-ruby
|
11
|
+
```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
Just require the gem and you're good to go.
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
require 'munin-ruby'
|
19
|
+
|
20
|
+
node = Munin::Node.new
|
21
|
+
node.version # => 1.4.4
|
22
|
+
```
|
23
|
+
|
24
|
+
### Connections
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
# Connects to 127.0.0.1:4949
|
28
|
+
node = Munin::Node.new
|
29
|
+
node = Munin::Node.new('YOUR_HOST', YOUR_PORT)
|
30
|
+
```
|
31
|
+
|
32
|
+
If munin-node has any restrictions on IP addresses, client will trigger ```Munin::AccessDenied``` exception.
|
33
|
+
|
34
|
+
By default client will reconnect if connection was lost. To disable that specify ```false``` after port option.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
node = Munin::Node.new('YOUR_HOST', 4949, false)
|
38
|
+
```
|
39
|
+
|
40
|
+
Ways to disconnect:
|
41
|
+
|
42
|
+
```
|
43
|
+
# Disconnect from server
|
44
|
+
node.disconnect
|
45
|
+
node.connection.close
|
46
|
+
```
|
47
|
+
|
48
|
+
In case if automatic reconnection was enabled, service will establish connection even after you call 'disconnect' method.
|
49
|
+
|
50
|
+
To force client not to open connection: ```node.disconnect(false)```.
|
51
|
+
|
52
|
+
This will trigger ```Munin::ConnectionError``` on any client calls.
|
53
|
+
|
54
|
+
### Services and metrics
|
55
|
+
|
56
|
+
See what's available on server:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
services = node.list
|
60
|
+
|
61
|
+
# => ["cpu","df", "df_inode", "entropy", "forks", ...]
|
62
|
+
```
|
63
|
+
|
64
|
+
#### Get service configuration
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
config = node.config('cpu')
|
68
|
+
```
|
69
|
+
|
70
|
+
This will produce the following result:
|
71
|
+
|
72
|
+
```
|
73
|
+
{"graph"=>
|
74
|
+
{"title"=>"CPU usage",
|
75
|
+
"order"=>"system user nice idle iowait irq softirq",
|
76
|
+
"args"=>
|
77
|
+
{"raw"=>"--base 1000 -r --lower-limit 0 --upper-limit 400",
|
78
|
+
"parsed"=>{"base"=>"1000", "lower-limit"=>"0", "upper-limit"=>"400"}},
|
79
|
+
"vlabel"=>"%",
|
80
|
+
"scale"=>"no",
|
81
|
+
"info"=>"This graph shows how CPU time is spent.",
|
82
|
+
"category"=>"system",
|
83
|
+
"period"=>"second"},
|
84
|
+
"metrics"=>
|
85
|
+
{"system"=>
|
86
|
+
{"label"=>"system",
|
87
|
+
"draw"=>"AREA",
|
88
|
+
"min"=>"0",
|
89
|
+
"type"=>"DERIVE",
|
90
|
+
"info"=>"CPU time spent by the kernel in system activities"},
|
91
|
+
"user"=>
|
92
|
+
{"label"=>"user",
|
93
|
+
"draw"=>"STACK",
|
94
|
+
"min"=>"0",
|
95
|
+
"type"=>"DERIVE",
|
96
|
+
"info"=>"CPU time spent by normal programs and daemons"},
|
97
|
+
"nice"=>
|
98
|
+
{"label"=>"nice",
|
99
|
+
"draw"=>"STACK",
|
100
|
+
"min"=>"0",
|
101
|
+
"type"=>"DERIVE",
|
102
|
+
"info"=>"CPU time spent by nice(1)d programs"},
|
103
|
+
"idle"=>
|
104
|
+
{"label"=>"idle",
|
105
|
+
"draw"=>"STACK",
|
106
|
+
"min"=>"0",
|
107
|
+
"type"=>"DERIVE",
|
108
|
+
"info"=>"Idle CPU time"},
|
109
|
+
"iowait"=>
|
110
|
+
{"label"=>"iowait",
|
111
|
+
"draw"=>"STACK",
|
112
|
+
"min"=>"0",
|
113
|
+
"type"=>"DERIVE",
|
114
|
+
"info"=>
|
115
|
+
"CPU time spent waiting for I/O operations to finish when there is nothing else to do."},
|
116
|
+
"irq"=>
|
117
|
+
{"label"=>"irq",
|
118
|
+
"draw"=>"STACK",
|
119
|
+
"min"=>"0",
|
120
|
+
"type"=>"DERIVE",
|
121
|
+
"info"=>"CPU time spent handling interrupts"},
|
122
|
+
"softirq"=>
|
123
|
+
{"label"=>"softirq",
|
124
|
+
"draw"=>"STACK",
|
125
|
+
"min"=>"0",
|
126
|
+
"type"=>"DERIVE",
|
127
|
+
"info"=>"CPU time spent handling \"batched\" interrupts"},
|
128
|
+
"steal"=>
|
129
|
+
{"label"=>"steal",
|
130
|
+
"draw"=>"STACK",
|
131
|
+
"min"=>"0",
|
132
|
+
"type"=>"DERIVE",
|
133
|
+
"info"=>
|
134
|
+
"The time that a virtual CPU had runnable tasks, but the virtual CPU itself was not running"}}}
|
135
|
+
```
|
136
|
+
|
137
|
+
#### Fetch a single service
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
service = node.fetch('cpu')
|
141
|
+
```
|
142
|
+
|
143
|
+
Output:
|
144
|
+
|
145
|
+
```
|
146
|
+
{"user"=>"140349907",
|
147
|
+
"nice"=>"0",
|
148
|
+
"system"=>"19694121",
|
149
|
+
"idle"=>"536427034",
|
150
|
+
"iowait"=>"6455996",
|
151
|
+
"irq"=>"445",
|
152
|
+
"softirq"=>"482942",
|
153
|
+
"steal"=>"635801"}
|
154
|
+
```
|
155
|
+
|
156
|
+
|
157
|
+
## License
|
158
|
+
|
159
|
+
Copyright © 2011 Dan Sosedoff.
|
160
|
+
|
161
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
162
|
+
|
163
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
164
|
+
|
165
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/lib/munin-ruby.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Munin
|
2
|
+
module Cache
|
3
|
+
def cache(key)
|
4
|
+
raise RuntimeError, "Block required." unless block_given?
|
5
|
+
data = cache_get(key)
|
6
|
+
if data.nil?
|
7
|
+
data = yield
|
8
|
+
cache_set(key, data)
|
9
|
+
end
|
10
|
+
data
|
11
|
+
end
|
12
|
+
|
13
|
+
def flush_cache
|
14
|
+
instance_variables.select { |l| l =~ /^@cache_/ }.each do |var|
|
15
|
+
remove_instance_variable(var)
|
16
|
+
end
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def cache_key(key)
|
23
|
+
"@cache_#{key.gsub(/[\.-]/,'__')}".to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
def cache_get(key)
|
27
|
+
instance_variable_get(cache_key(key))
|
28
|
+
end
|
29
|
+
|
30
|
+
def cache_set(key, value)
|
31
|
+
instance_variable_set(cache_key(key), value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Munin
|
4
|
+
class Connection
|
5
|
+
include Munin::Parser
|
6
|
+
|
7
|
+
attr_reader :host, :port
|
8
|
+
|
9
|
+
# Initialize a new connection to munin-node server
|
10
|
+
#
|
11
|
+
# host - Server host (default: 127.0.0.1)
|
12
|
+
# port - Server port (default: 4949)
|
13
|
+
#
|
14
|
+
def initialize(host='127.0.0.1', port=4949, reconnect=true)
|
15
|
+
@host = host
|
16
|
+
@port = port
|
17
|
+
@socket = nil
|
18
|
+
@connected = false
|
19
|
+
@reconnect = reconnect
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns true if socket is connected
|
23
|
+
#
|
24
|
+
def connected?
|
25
|
+
@connected == true
|
26
|
+
end
|
27
|
+
|
28
|
+
# Establish connection to the server
|
29
|
+
#
|
30
|
+
def open
|
31
|
+
begin
|
32
|
+
@socket = TCPSocket.new(@host, @port)
|
33
|
+
@socket.sync = true
|
34
|
+
welcome = @socket.gets
|
35
|
+
unless welcome =~ /^# munin node at/
|
36
|
+
raise Munin::AccessDenied
|
37
|
+
end
|
38
|
+
@connected = true
|
39
|
+
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET => ex
|
40
|
+
raise Munin::ConnectionError, ex.message
|
41
|
+
rescue EOFError
|
42
|
+
raise Munin::AccessDenied
|
43
|
+
rescue Exception => ex
|
44
|
+
raise Munin::ConnectionError, ex.message
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Close connection
|
49
|
+
#
|
50
|
+
def close(reconnect=true)
|
51
|
+
if connected?
|
52
|
+
@socket.flush
|
53
|
+
@socket.shutdown
|
54
|
+
@connected = false
|
55
|
+
@reconnect = reconnect
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Send a string of data followed by a newline symbol
|
60
|
+
#
|
61
|
+
def send_data(str)
|
62
|
+
if !connected?
|
63
|
+
if !@socket.nil? && @reconnect == false
|
64
|
+
raise Munin::ConnectionError, "Not connected."
|
65
|
+
else
|
66
|
+
open
|
67
|
+
end
|
68
|
+
end
|
69
|
+
@socket.puts("#{str.strip}\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
# Reads a single line from socket
|
73
|
+
#
|
74
|
+
def read_line
|
75
|
+
begin
|
76
|
+
@socket.gets.to_s.strip
|
77
|
+
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, EOFError => ex
|
78
|
+
raise Munin::ConnectionError, ex.message
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Reads a packet of data until '.' reached
|
83
|
+
#
|
84
|
+
def read_packet
|
85
|
+
begin
|
86
|
+
lines = []
|
87
|
+
while(str = @socket.readline.to_s) do
|
88
|
+
break if str.strip == '.'
|
89
|
+
lines << str.strip
|
90
|
+
end
|
91
|
+
parse_error(lines)
|
92
|
+
lines
|
93
|
+
rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, EOFError => ex
|
94
|
+
raise Munin::ConnectionError, ex.message
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Munin
|
4
|
+
class Node
|
5
|
+
include Munin::Parser
|
6
|
+
include Munin::Cache
|
7
|
+
|
8
|
+
attr_reader :connection
|
9
|
+
|
10
|
+
# Initialize a new Node instance
|
11
|
+
#
|
12
|
+
# host - Server host
|
13
|
+
# port - Server port
|
14
|
+
# reconnect - Reconnect if connection was closed (default: true)
|
15
|
+
#
|
16
|
+
|
17
|
+
def initialize(host='127.0.0.1', port=4949, reconnect=true)
|
18
|
+
@connection = Munin::Connection.new(host, port, reconnect)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Open service connection
|
22
|
+
#
|
23
|
+
def connect
|
24
|
+
connection.open
|
25
|
+
end
|
26
|
+
|
27
|
+
# Close server connection
|
28
|
+
#
|
29
|
+
def disconnect(reconnect=true)
|
30
|
+
connection.close(reconnect)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get a node version
|
34
|
+
#
|
35
|
+
def version
|
36
|
+
cache 'version' do
|
37
|
+
connection.send_data("version")
|
38
|
+
parse_version(connection.read_line)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get a list of all available nodes
|
43
|
+
#
|
44
|
+
def nodes
|
45
|
+
cache 'nodes' do
|
46
|
+
connection.send_data("nodes")
|
47
|
+
connection.read_line.split
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get a list of all available metrics
|
52
|
+
#
|
53
|
+
def list(node = nil)
|
54
|
+
cache "list_#{node || 'default'}" do
|
55
|
+
connection.send_data("list #{node}")
|
56
|
+
if ( line = connection.read_line ) != "."
|
57
|
+
line.split
|
58
|
+
else
|
59
|
+
connection.read_line.split
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get a configuration information for service
|
65
|
+
#
|
66
|
+
# services - Name of the service, or list of service names
|
67
|
+
#
|
68
|
+
def config(services, raw=false)
|
69
|
+
unless [String, Array].include?(services.class)
|
70
|
+
raise ArgumentError, "Service(s) argument required"
|
71
|
+
end
|
72
|
+
|
73
|
+
results = {}
|
74
|
+
names = [services].flatten.uniq
|
75
|
+
|
76
|
+
if names.empty?
|
77
|
+
raise ArgumentError, "Service(s) argument required"
|
78
|
+
end
|
79
|
+
|
80
|
+
key = 'config_' + Digest::MD5.hexdigest(names.to_s) + "_#{raw}"
|
81
|
+
|
82
|
+
cache(key) do
|
83
|
+
names.each do |service|
|
84
|
+
begin
|
85
|
+
connection.send_data("config #{service}")
|
86
|
+
lines = connection.read_packet
|
87
|
+
results[service] = raw ? lines.join("\n") : parse_config(lines)
|
88
|
+
rescue UnknownService, BadExit
|
89
|
+
# TODO
|
90
|
+
end
|
91
|
+
end
|
92
|
+
results
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get all service metrics values
|
97
|
+
#
|
98
|
+
# services - Name of the service, or list of service names
|
99
|
+
#
|
100
|
+
def fetch(services)
|
101
|
+
unless [String, Array].include?(services.class)
|
102
|
+
raise ArgumentError, "Service(s) argument required"
|
103
|
+
end
|
104
|
+
|
105
|
+
results = {}
|
106
|
+
names = [services].flatten
|
107
|
+
|
108
|
+
if names.empty?
|
109
|
+
raise ArgumentError, "Service(s) argument required"
|
110
|
+
end
|
111
|
+
|
112
|
+
names.each do |service|
|
113
|
+
begin
|
114
|
+
connection.send_data("fetch #{service}")
|
115
|
+
lines = connection.read_packet
|
116
|
+
results[service] = parse_fetch(lines)
|
117
|
+
rescue UnknownService, BadExit
|
118
|
+
# TODO
|
119
|
+
end
|
120
|
+
end
|
121
|
+
results
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Munin
|
2
|
+
module Parser
|
3
|
+
# Parse a version request
|
4
|
+
#
|
5
|
+
def parse_version(line)
|
6
|
+
if line =~ /^munins node on/
|
7
|
+
line.split.last
|
8
|
+
else
|
9
|
+
raise Munin::InvalidResponse, "Invalid version response"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Process response
|
14
|
+
#
|
15
|
+
def process_data(lines)
|
16
|
+
data = {}
|
17
|
+
lines.each do |line|
|
18
|
+
line = line.split
|
19
|
+
key = line.first.split('.value').first
|
20
|
+
data[key] = line.last
|
21
|
+
end
|
22
|
+
data
|
23
|
+
end
|
24
|
+
|
25
|
+
# Parse 'config' request
|
26
|
+
#
|
27
|
+
def parse_config(data)
|
28
|
+
config = {'graph' => {}, 'metrics' => {}}
|
29
|
+
data.each do |l|
|
30
|
+
if l =~ /^graph_/
|
31
|
+
key_name, value = l.scan(/^graph_([\w]+)\s(.*)/).flatten
|
32
|
+
config['graph'][key_name] = value
|
33
|
+
elsif l =~ /^[a-z]+\./
|
34
|
+
matches = l.scan(/^([a-z\d\-\_]+)\.([a-z\d\-\_]+)\s(.*)/).flatten
|
35
|
+
config['metrics'][matches[0]] ||= {}
|
36
|
+
config['metrics'][matches[0]][matches[1]] = matches[2]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Now, lets process the args hash
|
41
|
+
if config['graph'].key?('args')
|
42
|
+
config['graph']['args'] = parse_config_args(config['graph']['args'])
|
43
|
+
end
|
44
|
+
|
45
|
+
config
|
46
|
+
end
|
47
|
+
|
48
|
+
# Parse 'fetch' request
|
49
|
+
#
|
50
|
+
def parse_fetch(data)
|
51
|
+
process_data(data)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Detect error from output
|
55
|
+
#
|
56
|
+
def parse_error(lines)
|
57
|
+
if lines.size == 1
|
58
|
+
case lines.first
|
59
|
+
when '# Unknown service' then raise UnknownService
|
60
|
+
when '# Bad exit' then raise BadExit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Parse configuration arguments
|
66
|
+
#
|
67
|
+
def parse_config_args(args)
|
68
|
+
result = {}
|
69
|
+
args.scan(/--?([a-z\-\_]+)\s([\d]+)\s?/).each do |arg|
|
70
|
+
result[arg.first] = arg.last
|
71
|
+
end
|
72
|
+
{'raw' => args, 'parsed' => result}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/munin-ruby.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/munin-ruby/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "munin-ruby"
|
6
|
+
gem.version = Munin::VERSION.dup
|
7
|
+
gem.author = "Dan Sosedoff"
|
8
|
+
gem.email = "dan.sosedoff@gmail.com"
|
9
|
+
gem.homepage = "http://github.com/sosedoff/munin-ruby"
|
10
|
+
gem.description = "Munin Node client"
|
11
|
+
gem.summary = "Ruby client library to communicate with munin-node servers"
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split("\n")
|
14
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
|
16
|
+
gem.require_paths = ['lib']
|
17
|
+
|
18
|
+
gem.add_development_dependency 'rspec', '~> 2.6'
|
19
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
config memory
|
2
|
+
graph_args --base 1024 -l 0 --upper-limit 16175665152
|
3
|
+
graph_vlabel Bytes
|
4
|
+
graph_title Memory usage
|
5
|
+
graph_category system
|
6
|
+
graph_info This graph shows what the machine uses memory for.
|
7
|
+
graph_order apps page_tables swap_cache slab cached buffers free swap
|
8
|
+
apps.label apps
|
9
|
+
apps.draw AREA
|
10
|
+
apps.info Memory used by user-space applications.
|
11
|
+
buffers.label buffers
|
12
|
+
buffers.draw STACK
|
13
|
+
buffers.info Block device (e.g. harddisk) cache. Also where "dirty" blocks are stored until written.
|
14
|
+
swap.label swap
|
15
|
+
swap.draw STACK
|
16
|
+
swap.info Swap space used.
|
17
|
+
cached.label cache
|
18
|
+
cached.draw STACK
|
19
|
+
cached.info Parked file data (file content) cache.
|
20
|
+
free.label unused
|
21
|
+
free.draw STACK
|
22
|
+
free.info Wasted memory. Memory that is not used for anything at all.
|
23
|
+
slab.label slab_cache
|
24
|
+
slab.draw STACK
|
25
|
+
slab.info Memory used by the kernel (major users are caches like inode, dentry, etc).
|
26
|
+
swap_cache.label swap_cache
|
27
|
+
swap_cache.draw STACK
|
28
|
+
swap_cache.info A piece of memory that keeps track of pages that have been fetched from swap but not yet been modified.
|
29
|
+
page_tables.label page_tables
|
30
|
+
page_tables.draw STACK
|
31
|
+
page_tables.info Memory used to map between virtual and physical memory addresses.
|
32
|
+
vmalloc_used.label vmalloc_used
|
33
|
+
vmalloc_used.draw LINE2
|
34
|
+
vmalloc_used.info 'VMalloc' (kernel) memory used
|
35
|
+
committed.label committed
|
36
|
+
committed.draw LINE2
|
37
|
+
committed.info The amount of memory allocated to programs. Overcommitting is normal, but may indicate memory leaks.
|
38
|
+
mapped.label mapped
|
39
|
+
mapped.draw LINE2
|
40
|
+
mapped.info All mmap()ed pages.
|
41
|
+
active.label active
|
42
|
+
active.draw LINE2
|
43
|
+
active.info Memory recently used. Not reclaimed unless absolutely necessary.
|
44
|
+
inactive.label inactive
|
45
|
+
inactive.draw LINE2
|
46
|
+
inactive.info Memory not currently used.
|
47
|
+
.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
fetch memory
|
2
|
+
slab.value 710025216
|
3
|
+
swap_cache.value 823296
|
4
|
+
page_tables.value 27803648
|
5
|
+
vmalloc_used.value 9228288
|
6
|
+
apps.value 1219354624
|
7
|
+
free.value 204206080
|
8
|
+
buffers.value 2046074880
|
9
|
+
cached.value 11967377408
|
10
|
+
swap.value 2961408
|
11
|
+
committed.value 2358927360
|
12
|
+
mapped.value 1625862144
|
13
|
+
active.value 5164363776
|
14
|
+
inactive.value 10039930880
|
15
|
+
.
|
@@ -0,0 +1 @@
|
|
1
|
+
cpu memory load
|
@@ -0,0 +1 @@
|
|
1
|
+
munins node on hostname version: 1.4.4
|
data/spec/node_spec.rb
ADDED
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ParseTester
|
4
|
+
include Munin::Parser
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Munin::Parser do
|
8
|
+
before :each do
|
9
|
+
@parser = ParseTester.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'parses version request' do
|
13
|
+
@parser.parse_version(fixture('version.txt')).should == '1.4.4'
|
14
|
+
|
15
|
+
proc { @parser.parse_version("some other response") }.
|
16
|
+
should raise_error Munin::InvalidResponse, "Invalid version response"
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'parses config request' do
|
20
|
+
c = @parser.parse_config(fixture('config.txt').strip.split("\n"))
|
21
|
+
c.should be_a Hash
|
22
|
+
c['graph'].should be_a Hash
|
23
|
+
c['graph']['args']['raw'].should == '--base 1024 -l 0 --upper-limit 16175665152'
|
24
|
+
c['graph']['args']['parsed'].keys.should == %w(base l upper-limit)
|
25
|
+
c['metrics'].should be_an Hash
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: munin-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Sosedoff
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-06 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &2164790540 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.6'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2164790540
|
25
|
+
description: Munin Node client
|
26
|
+
email: dan.sosedoff@gmail.com
|
27
|
+
executables: []
|
28
|
+
extensions: []
|
29
|
+
extra_rdoc_files: []
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- .rspec
|
33
|
+
- README.md
|
34
|
+
- Rakefile
|
35
|
+
- lib/munin-ruby.rb
|
36
|
+
- lib/munin-ruby/cache.rb
|
37
|
+
- lib/munin-ruby/connection.rb
|
38
|
+
- lib/munin-ruby/errors.rb
|
39
|
+
- lib/munin-ruby/node.rb
|
40
|
+
- lib/munin-ruby/parser.rb
|
41
|
+
- lib/munin-ruby/version.rb
|
42
|
+
- munin-ruby.gemspec
|
43
|
+
- spec/fixtures/config.txt
|
44
|
+
- spec/fixtures/fetch.txt
|
45
|
+
- spec/fixtures/list.txt
|
46
|
+
- spec/fixtures/version.txt
|
47
|
+
- spec/node_spec.rb
|
48
|
+
- spec/parser_spec.rb
|
49
|
+
- spec/spec_helper.rb
|
50
|
+
homepage: http://github.com/sosedoff/munin-ruby
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.10
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Ruby client library to communicate with munin-node servers
|
74
|
+
test_files:
|
75
|
+
- spec/fixtures/config.txt
|
76
|
+
- spec/fixtures/fetch.txt
|
77
|
+
- spec/fixtures/list.txt
|
78
|
+
- spec/fixtures/version.txt
|
79
|
+
- spec/node_spec.rb
|
80
|
+
- spec/parser_spec.rb
|
81
|
+
- spec/spec_helper.rb
|