apocalypse-client 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.md +82 -0
- data/Rakefile +9 -0
- data/apocalypse-client.gemspec +25 -0
- data/bin/apocalypse-client +37 -0
- data/lib/apocalypse-client.rb +133 -0
- data/lib/apocalypse-client/version.rb +5 -0
- data/spec/client_spec.rb +125 -0
- data/spec/spec_helper.rb +4 -0
- metadata +126 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour -f progress
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Apocalypse Client
|
2
|
+
|
3
|
+
Apocalypse Client is a ruby gem that can be installed on a remote
|
4
|
+
server.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Apocalypse Client currently focusses on Debian/Ubuntu systems only.
|
9
|
+
|
10
|
+
There is only one dependency to the operating system, namely the
|
11
|
+
`sysstat` package. This package is used to gather information about disk
|
12
|
+
utilisation and performance.
|
13
|
+
|
14
|
+
sudo apt-get install sysstat
|
15
|
+
|
16
|
+
Next install the ruby gem.
|
17
|
+
|
18
|
+
sudo gem install apocalypse-client
|
19
|
+
|
20
|
+
Now you can create the file `/etc/cron.d/apocalypse` with the following
|
21
|
+
content:
|
22
|
+
|
23
|
+
* * * * * root PATH=$PATH:/sbin:/usr/sbin /usr/bin/env apocalypse-client report --server SERVER --port PORT --hostid HOSTID > /dev/null
|
24
|
+
|
25
|
+
This will send metrics data every minute to your Apocalypse server. If
|
26
|
+
you require different intervals, refer to `man 5 crontab` for details on
|
27
|
+
how to schedule reporting.
|
28
|
+
|
29
|
+
You need to replace the placeholders with actual data:
|
30
|
+
|
31
|
+
* `SERVER` - The ip or hostname for your Apocalypse server. E.g.
|
32
|
+
apocalyse.example.org
|
33
|
+
* `PORT` - The port number the Apocalypse server is listening on.
|
34
|
+
Default: 80
|
35
|
+
* `HOSTID` - An ID identifying this server. You are free to choose
|
36
|
+
whatever you want. But be careful not to chose a duplicate hostid,
|
37
|
+
because it will mess up you statistics.
|
38
|
+
|
39
|
+
If an error occurs cron will try to notify you by email. This depends on
|
40
|
+
how your systems cron is configured.
|
41
|
+
|
42
|
+
## Choosing a proper hostid
|
43
|
+
|
44
|
+
Choosing a proper hostid is important, because it can be arbitrarily
|
45
|
+
chosen. There are several options:
|
46
|
+
|
47
|
+
* Use the format `appname-role-number`. E.g. `ariejannet-db-01` or
|
48
|
+
`reddis-memcached-42`.
|
49
|
+
* IP Address of the server, this guarantees some level of uniqueness
|
50
|
+
|
51
|
+
Note: at this time, there is not convention for picking hostids.
|
52
|
+
However, the first method is likely to become the convention and will
|
53
|
+
allow logical grouping of servers by role and application.
|
54
|
+
|
55
|
+
## Authors
|
56
|
+
|
57
|
+
* Ariejan de Vroom <ariejan@ariejan.net>
|
58
|
+
* Kabisa ICT - http://kabisa.nl
|
59
|
+
|
60
|
+
## License
|
61
|
+
|
62
|
+
Copyright (c) 2011 Ariejan de Vroom
|
63
|
+
|
64
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
65
|
+
a copy of this software and associated documentation files (the
|
66
|
+
"Software"), to deal in the Software without restriction, including
|
67
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
68
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
69
|
+
permit persons to whom the Software is furnished to do so, subject to
|
70
|
+
the following conditions:
|
71
|
+
|
72
|
+
The above copyright notice and this permission notice shall be
|
73
|
+
included in all copies or substantial portions of the Software.
|
74
|
+
|
75
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
76
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
77
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
78
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
79
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
80
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
81
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
82
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "apocalypse-client/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "apocalypse-client"
|
7
|
+
s.version = Apocalypse::Client::VERSION
|
8
|
+
s.authors = ["Ariejan de Vroom"]
|
9
|
+
s.email = ["ariejan@ariejan.net"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Watch out for the apocalypse}
|
12
|
+
s.description = %q{Server monitoring made easy}
|
13
|
+
|
14
|
+
s.rubyforge_project = "apocalypse-client"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency("json", ["~> 1.5.3"])
|
22
|
+
s.add_dependency("trollop", ["~> 1.16.2"])
|
23
|
+
|
24
|
+
s.add_development_dependency("rspec", ["~> 2.6.0"])
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require "apocalypse-client"
|
7
|
+
require 'trollop'
|
8
|
+
|
9
|
+
SUB_COMMANDS = %w(report install check)
|
10
|
+
|
11
|
+
global_opts = Trollop::options do
|
12
|
+
banner "Apocalypse Reporter"
|
13
|
+
stop_on SUB_COMMANDS
|
14
|
+
end
|
15
|
+
|
16
|
+
cmd = ARGV.shift
|
17
|
+
cmd_opts = case cmd
|
18
|
+
when "report"
|
19
|
+
Trollop::options do
|
20
|
+
opt :server, "Hostname of the Apocalypse Server", :type => :string, :short => "-s"
|
21
|
+
opt :port, "Port the Apocalypse Server is listening on. Default: 80", :type => :string, :default => '80', :short => "-p"
|
22
|
+
opt :hostid, "Identifier for this server", :type => :string, :short => "-i"
|
23
|
+
end
|
24
|
+
when "install"
|
25
|
+
Trollop::options do
|
26
|
+
# TODO
|
27
|
+
end
|
28
|
+
when "check"
|
29
|
+
Trollop::options do
|
30
|
+
# TODO
|
31
|
+
end
|
32
|
+
else
|
33
|
+
Trollop::die "unknown command #{cmd.inspect}"
|
34
|
+
end
|
35
|
+
|
36
|
+
reporter = Apocalypse::Client.new
|
37
|
+
reporter.send(cmd, cmd_opts)
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Hash
|
6
|
+
#
|
7
|
+
# Create a hash from an array of keys and corresponding values.
|
8
|
+
def self.zip(keys, values, default=nil, &block)
|
9
|
+
hsh = block_given? ? Hash.new(&block) : Hash.new(default)
|
10
|
+
keys.zip(values) { |k,v| hsh[k]=v }
|
11
|
+
hsh
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Apocalypse
|
16
|
+
class Client
|
17
|
+
## Commands
|
18
|
+
|
19
|
+
# Report metrics
|
20
|
+
def report(options)
|
21
|
+
puts options.inspect
|
22
|
+
request = Net::HTTP::Post.new("/api/metrics/#{options[:hostid]}", initheader = {'Content-Type' =>'application/json'})
|
23
|
+
request.body = gather_metrics.to_json
|
24
|
+
response = Net::HTTP.new(options[:server], options[:port]).start {|http| http.request(request) }
|
25
|
+
puts "Response #{response.code} #{response.message}: #{response.body}"
|
26
|
+
end
|
27
|
+
|
28
|
+
# Check if all local deps are available
|
29
|
+
def check(options)
|
30
|
+
errors = []
|
31
|
+
[
|
32
|
+
["/usr/bin/iostat", "sysstat"]
|
33
|
+
].each do |filename, package|
|
34
|
+
errors << "Cannot find `#{filename}`. Please run `apt-get install #{package}` to resolve this." if !File.exists?(filename)
|
35
|
+
end
|
36
|
+
|
37
|
+
if errors.empty?
|
38
|
+
puts "Everything seems to be in place. You're good to go."
|
39
|
+
else
|
40
|
+
errors.each { |error| puts errors }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def install(options)
|
45
|
+
puts <<-EOF
|
46
|
+
Sorry, no automated installation yet. Installation is, however, quite easy.
|
47
|
+
|
48
|
+
Simply create the file `/etc/cron.d/apocalypse` and put the following line in it:
|
49
|
+
|
50
|
+
* * * * * root PATH=$PATH:/sbin:/usr/sbin /usr/bin/env apocalypse-reporter report --server APOCALYPSE_SERVER --hostid SERVER_ID > /dev/null
|
51
|
+
|
52
|
+
Make sure to replace the server and hostid placeholders with something more useful.
|
53
|
+
EOF
|
54
|
+
end
|
55
|
+
|
56
|
+
# Gather metrics
|
57
|
+
def gather_metrics
|
58
|
+
{
|
59
|
+
'cpu' => {
|
60
|
+
'cores' => cpu_cores.strip,
|
61
|
+
'loadavg' => cpu_loadavg
|
62
|
+
},
|
63
|
+
'memory' => memory_metrics,
|
64
|
+
'swap' => swap_metrics,
|
65
|
+
'blockdevices' => blockdevice_metrics,
|
66
|
+
'network' => network_metrics
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the number of CPU Cores for this system
|
71
|
+
def cpu_cores
|
72
|
+
`cat /proc/cpuinfo | grep bogomips | wc -l`.strip
|
73
|
+
end
|
74
|
+
|
75
|
+
# Gather load average data
|
76
|
+
def cpu_loadavg
|
77
|
+
`cat /proc/loadavg`.split
|
78
|
+
end
|
79
|
+
|
80
|
+
def blockdevice_metrics
|
81
|
+
columns = ["tps", "rps", "wps", "size", "used", "available", "usage", "mount"]
|
82
|
+
|
83
|
+
io_data = `/usr/bin/env iostat -dk | tail -n+4`.split("\n").map { |line| line.split[0...-2] }
|
84
|
+
usage_data = `df -l --block-size=M | grep -i ^/dev/[sh]`.split("\n").map { |line| line.split }
|
85
|
+
|
86
|
+
io_data.collect do |device_data|
|
87
|
+
device_name = device_data.shift
|
88
|
+
device_usage = usage_data.select { |x| x[0].include? device_name }.flatten
|
89
|
+
|
90
|
+
unless device_usage.empty?
|
91
|
+
device_data += device_usage[1..-1]
|
92
|
+
end
|
93
|
+
|
94
|
+
{ device_name => Hash.zip(columns, device_data) }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def memory_metrics
|
99
|
+
{
|
100
|
+
'free' => `cat /proc/meminfo | grep MemFree | awk '{print $2}'`.strip,
|
101
|
+
'total' => `cat /proc/meminfo | grep MemTotal | awk '{print $2}'`.strip
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
def swap_metrics
|
106
|
+
{
|
107
|
+
'free' => `cat /proc/meminfo | grep SwapFree | awk '{print $2}'`.strip,
|
108
|
+
'total' => `cat /proc/meminfo | grep SwapTotal | awk '{print $2}'`.strip
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
def network_metrics
|
113
|
+
devices = `/usr/bin/env ifconfig | egrep 'Link encap' | grep -v 'lo' | awk '{print $1}'`.split
|
114
|
+
|
115
|
+
devices.collect do |device_name|
|
116
|
+
{ device_name => {
|
117
|
+
'hwaddr' => `/usr/bin/env ifconfig #{device_name} | egrep -o 'HWaddr \([0-9a-fA-F]\{2\}\:*\){6}' | awk '{print $2}'`.strip,
|
118
|
+
'mtu' => `/usr/bin/env ifconfig #{device_name} | egrep -o MTU\:[0-9]+ | tr -s ':' ' ' | awk '{print $2}'`.strip,
|
119
|
+
'metric' => `/usr/bin/env ifconfig #{device_name} | egrep -o Metric\:[0-9]+ | tr -s ':' ' ' | awk '{print $2}'`.strip,
|
120
|
+
'encapsulation' => `/usr/bin/env ifconfig #{device_name} | egrep -o 'Link encap\:[a-zA-Z]+' | cut -d":" -f2`.strip,
|
121
|
+
'rxbytes' => `/usr/bin/env ifconfig #{device_name} | grep bytes | awk '/RX/ {print $2}' | tr -s ':' ' ' | awk '{print $2}'`.strip,
|
122
|
+
'txbytes' => `/usr/bin/env ifconfig #{device_name} | grep bytes | awk '/TX/ {print $6}' | tr -s ':' ' ' | awk '{print $2}'`.strip,
|
123
|
+
'ipv4address' => `/usr/bin/env ifconfig #{device_name} | egrep -o 'inet addr\:[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | tr -s ':' ' ' | awk '{print $3}'`.strip,
|
124
|
+
'broadcast' => `/usr/bin/env ifconfig #{device_name} | egrep -o Bcast\:[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} | tr -s ':' ' ' | awk '{print $2}'`.strip,
|
125
|
+
'netmask' => `/usr/bin/env ifconfig #{device_name} | egrep -o Mask\:[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} | tr -s ':' ' ' | awk '{print $2}'`.strip,
|
126
|
+
'gateway' => `netstat -rn | grep ^0.0.0.0 | grep UG | grep #{device_name} | awk '{print $2}' | head -n1`.strip,
|
127
|
+
'ipv6addr' => `/usr/bin/env ifconfig #{device_name} | egrep -o 'inet6 addr\:\ \([a-fA-F0-9]\{1,4}\:\{1,2\}[a-fA-F0-9]\{1,4}\:\{1,2\}\)+[A-Fa-f0-9\/^\ ]+' | awk '{print $3}'`.strip,
|
128
|
+
'ipv6scope' => `/usr/bin/env ifconfig #{device_name} | egrep -o Scope\:[a-zA-Z]+ | cut -d":" -f2`.strip
|
129
|
+
}}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apocalypse::Client do
|
4
|
+
before(:each) do
|
5
|
+
@reporter = Apocalypse::Client.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "cpu cores" do
|
9
|
+
it "should return the correct number of cores" do
|
10
|
+
@reporter.should_receive(:`).with("cat /proc/cpuinfo | grep bogomips | wc -l").and_return("4")
|
11
|
+
@reporter.cpu_cores.should eql("4")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "cpu loadavg" do
|
16
|
+
it "should return the correct loadavg values" do
|
17
|
+
@reporter.should_receive(:`).with("cat /proc/loadavg").and_return("0.89 0.92 1.12 1/124 28786")
|
18
|
+
@reporter.cpu_loadavg.should eql(["0.89", "0.92", "1.12", "1/124", "28786"])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "memory" do
|
23
|
+
it "should gather free and used memory" do
|
24
|
+
@reporter.should_receive(:`).with("cat /proc/meminfo | grep MemFree | awk '{print $2}'").and_return("998452")
|
25
|
+
@reporter.should_receive(:`).with("cat /proc/meminfo | grep MemTotal | awk '{print $2}'").and_return("7864548")
|
26
|
+
|
27
|
+
memory_metrics = @reporter.memory_metrics
|
28
|
+
memory_metrics["free"].should eql("998452")
|
29
|
+
memory_metrics["total"].should eql("7864548")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "swap" do
|
34
|
+
it "should gather free and used swap" do
|
35
|
+
@reporter.should_receive(:`).with("cat /proc/meminfo | grep SwapFree | awk '{print $2}'").and_return("934452")
|
36
|
+
@reporter.should_receive(:`).with("cat /proc/meminfo | grep SwapTotal | awk '{print $2}'").and_return("15728632")
|
37
|
+
|
38
|
+
swap_metrics = @reporter.swap_metrics
|
39
|
+
swap_metrics["free"].should eql("934452")
|
40
|
+
swap_metrics["total"].should eql("15728632")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "networking" do
|
45
|
+
it "should get network metrics" do
|
46
|
+
{
|
47
|
+
"/usr/bin/env ifconfig | egrep 'Link encap' | grep -v 'lo' | awk '{print $1}'" => "eth0",
|
48
|
+
"/usr/bin/env ifconfig eth0 | egrep -o 'HWaddr \([0-9a-fA-F]\{2\}\:*\){6}' | awk '{print $2}'" => "bc:de:12:ba:38:b3",
|
49
|
+
"/usr/bin/env ifconfig eth0 | egrep -o MTU\:[0-9]+ | tr -s ':' ' ' | awk '{print $2}'" => "1500",
|
50
|
+
"/usr/bin/env ifconfig eth0 | egrep -o Metric\:[0-9]+ | tr -s ':' ' ' | awk '{print $2}'" => "1",
|
51
|
+
"/usr/bin/env ifconfig eth0 | egrep -o 'Link encap\:[a-zA-Z]+' | cut -d\":\" -f2" => "Ethernet",
|
52
|
+
"/usr/bin/env ifconfig eth0 | grep bytes | awk '/RX/ {print $2}' | tr -s ':' ' ' | awk '{print $2}'" => "384735745",
|
53
|
+
"/usr/bin/env ifconfig eth0 | grep bytes | awk '/TX/ {print $6}' | tr -s ':' ' ' | awk '{print $2}'" => "3575372573",
|
54
|
+
"/usr/bin/env ifconfig eth0 | egrep -o 'inet addr\:[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | tr -s ':' ' ' | awk '{print $3}'" => "10.187.234.18",
|
55
|
+
"/usr/bin/env ifconfig eth0 | egrep -o Bcast\:[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} | tr -s ':' ' ' | awk '{print $2}'" => "10.187.234.254",
|
56
|
+
"/usr/bin/env ifconfig eth0 | egrep -o Mask\:[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\} | tr -s ':' ' ' | awk '{print $2}'" => "255.0.0.0",
|
57
|
+
"netstat -rn | grep ^0.0.0.0 | grep UG | grep eth0 | awk '{print $2}' | head -n1" => "10.187.234.1",
|
58
|
+
"/usr/bin/env ifconfig eth0 | egrep -o 'inet6 addr\:\ \([a-fA-F0-9]\{1,4}\:\{1,2\}[a-fA-F0-9]\{1,4}\:\{1,2\}\)+[A-Fa-f0-9\/^\ ]+' | awk '{print $3}'" => "fe80::1031:3cff:fe00:bde1/64",
|
59
|
+
"/usr/bin/env ifconfig eth0 | egrep -o Scope\:[a-zA-Z]+ | cut -d\":\" -f2" => "Link"
|
60
|
+
}.each do |command, result|
|
61
|
+
@reporter.should_receive(:`).with(command).and_return(result)
|
62
|
+
end
|
63
|
+
|
64
|
+
network_metrics = @reporter.network_metrics.first["eth0"]
|
65
|
+
|
66
|
+
network_metrics["hwaddr"].should eql("bc:de:12:ba:38:b3")
|
67
|
+
network_metrics["mtu"].should eql("1500")
|
68
|
+
network_metrics["metric"].should eql("1")
|
69
|
+
network_metrics["encapsulation"].should eql("Ethernet")
|
70
|
+
network_metrics["rxbytes"].should eql("384735745")
|
71
|
+
network_metrics["txbytes"].should eql("3575372573")
|
72
|
+
network_metrics["ipv4address"].should eql("10.187.234.18")
|
73
|
+
network_metrics["broadcast"].should eql("10.187.234.254")
|
74
|
+
network_metrics["netmask"].should eql("255.0.0.0")
|
75
|
+
network_metrics["gateway"].should eql("10.187.234.1")
|
76
|
+
network_metrics["ipv6addr"].should eql("fe80::1031:3cff:fe00:bde1/64")
|
77
|
+
network_metrics["ipv6scope"].should eql("Link")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "block devices" do
|
82
|
+
it "should gather the correct block device info" do
|
83
|
+
iostat = <<-EOF
|
84
|
+
sda1 0.21 1.95 2.35 157872 189884
|
85
|
+
sda2 5.74 18.53 22.08 1496597 1783516
|
86
|
+
|
87
|
+
EOF
|
88
|
+
|
89
|
+
df = <<-EOF
|
90
|
+
/dev/sda2 29529M 7506M 20524M 27% /
|
91
|
+
EOF
|
92
|
+
|
93
|
+
@reporter.should_receive(:`).with("/usr/bin/env iostat -dk | tail -n+4").and_return(iostat)
|
94
|
+
@reporter.should_receive(:`).with("df -l --block-size=M | grep -i ^/dev/[sh]").and_return(df)
|
95
|
+
|
96
|
+
result = @reporter.blockdevice_metrics
|
97
|
+
|
98
|
+
result.size.should eql(2)
|
99
|
+
|
100
|
+
# sda1
|
101
|
+
sda1 = result.select{ |a| a.keys.include?("sda1") }.first["sda1"]
|
102
|
+
|
103
|
+
sda1["tps"].should eql("0.21")
|
104
|
+
sda1["rps"].should eql("1.95")
|
105
|
+
sda1["wps"].should eql("2.35")
|
106
|
+
sda1["size"].should be_nil
|
107
|
+
sda1["usage"].should be_nil
|
108
|
+
sda1["used"].should be_nil
|
109
|
+
sda1["available"].should be_nil
|
110
|
+
sda1["mount"].should be_nil
|
111
|
+
|
112
|
+
# sda2
|
113
|
+
sda2 = result.select{ |a| a.keys.include?("sda2") }.first["sda2"]
|
114
|
+
|
115
|
+
sda2["tps"].should eql("5.74")
|
116
|
+
sda2["rps"].should eql("18.53")
|
117
|
+
sda2["wps"].should eql("22.08")
|
118
|
+
sda2["size"].should eql("29529M")
|
119
|
+
sda2["usage"].should eql("27%")
|
120
|
+
sda2["used"].should eql("7506M")
|
121
|
+
sda2["available"].should eql("20524M")
|
122
|
+
sda2["mount"].should eql("/")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: apocalypse-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ariejan de Vroom
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-07-06 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: json
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 5
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 5
|
33
|
+
- 3
|
34
|
+
version: 1.5.3
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: trollop
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 83
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 16
|
49
|
+
- 2
|
50
|
+
version: 1.16.2
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rspec
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
hash: 23
|
62
|
+
segments:
|
63
|
+
- 2
|
64
|
+
- 6
|
65
|
+
- 0
|
66
|
+
version: 2.6.0
|
67
|
+
type: :development
|
68
|
+
version_requirements: *id003
|
69
|
+
description: Server monitoring made easy
|
70
|
+
email:
|
71
|
+
- ariejan@ariejan.net
|
72
|
+
executables:
|
73
|
+
- apocalypse-client
|
74
|
+
extensions: []
|
75
|
+
|
76
|
+
extra_rdoc_files: []
|
77
|
+
|
78
|
+
files:
|
79
|
+
- .gitignore
|
80
|
+
- .rspec
|
81
|
+
- Gemfile
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- apocalypse-client.gemspec
|
85
|
+
- bin/apocalypse-client
|
86
|
+
- lib/apocalypse-client.rb
|
87
|
+
- lib/apocalypse-client/version.rb
|
88
|
+
- spec/client_spec.rb
|
89
|
+
- spec/spec_helper.rb
|
90
|
+
has_rdoc: true
|
91
|
+
homepage: ""
|
92
|
+
licenses: []
|
93
|
+
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 3
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
version: "0"
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
requirements: []
|
118
|
+
|
119
|
+
rubyforge_project: apocalypse-client
|
120
|
+
rubygems_version: 1.5.0
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Watch out for the apocalypse
|
124
|
+
test_files:
|
125
|
+
- spec/client_spec.rb
|
126
|
+
- spec/spec_helper.rb
|