apocalypse-client 0.0.2
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/.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
|