systemstats 0.1.dev
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 +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +4 -0
- data/Rakefile +11 -0
- data/lib/systemstats/iostat_reader.rb +87 -0
- data/lib/systemstats/os_detect.rb +29 -0
- data/lib/systemstats/version.rb +4 -0
- data/lib/systemstats.rb +6 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/unit/iostat_linux_spec.rb +62 -0
- data/spec/unit/iostat_osx_spec.rb +57 -0
- data/systemstats.gemspec +28 -0
- metadata +180 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Dave Golombek
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module SystemStats
|
3
|
+
|
4
|
+
class IoStatReader
|
5
|
+
|
6
|
+
IOSTAT_CMD_OSX = 'iostat -dC disk'
|
7
|
+
IOSTAT_CMD_LINUX = 'iostat -x'
|
8
|
+
|
9
|
+
private
|
10
|
+
# Gets system statistics from iostats and parses the output
|
11
|
+
def read_iostats(disk)
|
12
|
+
if OS::linux?
|
13
|
+
process_iostat_linux(disk)
|
14
|
+
elsif OS::mac?
|
15
|
+
process_iostat_mac(disk)
|
16
|
+
else
|
17
|
+
raise 'Unsupported operating system'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Parse disk/cpu counters from iostat on osx.
|
22
|
+
def process_iostat_mac(disk_id = 0)
|
23
|
+
output = IO.popen(IOSTAT_CMD_OSX + disk_id.to_s)
|
24
|
+
data = output.readlines
|
25
|
+
values = Hash.new
|
26
|
+
begin
|
27
|
+
values[:cpu] = data[2].split[3,3]
|
28
|
+
values[:disk] = data[2].split[0,3]
|
29
|
+
rescue => parse_error
|
30
|
+
raise 'Error parsing IoStats output.'
|
31
|
+
end
|
32
|
+
values
|
33
|
+
end
|
34
|
+
|
35
|
+
# Parse disk/cpu counters from iostat on linux.
|
36
|
+
def process_iostat_linux(disk_id = 'sda1')
|
37
|
+
output = IO.popen(IOSTAT_CMD_LINUX + disk_id.to_s)
|
38
|
+
data = output.readlines
|
39
|
+
values = Hash.new
|
40
|
+
begin
|
41
|
+
values[:cpu] = [data[3].split[0] , data[3].split[2], data[3].split[5]]
|
42
|
+
values[:disk] = data[2].split[0,3]
|
43
|
+
rescue => parse_error
|
44
|
+
raise 'Error parsing IoStats output.'
|
45
|
+
end
|
46
|
+
values
|
47
|
+
end
|
48
|
+
|
49
|
+
public
|
50
|
+
|
51
|
+
# Returns the User Cpu average percentage
|
52
|
+
def cpu_user_average
|
53
|
+
read_iostats(0)[:cpu][0]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the system Cpu average use percentage
|
57
|
+
def cpu_system_average
|
58
|
+
read_iostats(0)[:cpu][1]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the user Cpu average idle time percentage
|
62
|
+
def cpu_idle_average
|
63
|
+
read_iostats(0)[:cpu][2]
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the user's Kilobytes per transfer
|
67
|
+
# Disk id is the numeric ID in osx, disk type in linux
|
68
|
+
# OSX: disk0 => '0', Linux => disk 0 => 'sda'
|
69
|
+
def disk_kb_per_transfer(disk_id)
|
70
|
+
read_iostats(disk_id)[:disk][0]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns the number of current transfers per second for a disk
|
74
|
+
# Disk id is the numeric ID in osx, disk type in linux
|
75
|
+
# OSX: disk0 => '0', Linux => disk 0 => 'sda'
|
76
|
+
def disk_transfers_per_second(disk_id)
|
77
|
+
read_iostats(disk_id)[:disk][1]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns the current number of megabytes transfered on a disk per second
|
81
|
+
# Disk id is the numeric ID in osx, disk type in linux
|
82
|
+
# OSX: disk0 => '0', Linux => disk 0 => 'sda'
|
83
|
+
def disk_megabytes_per_second(disk_id)
|
84
|
+
read_iostats(disk_id)[:disk][2]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
module OS
|
5
|
+
class << self
|
6
|
+
# Detects the current OS running
|
7
|
+
def is?(what)
|
8
|
+
what === RbConfig::CONFIG['host_os']
|
9
|
+
end
|
10
|
+
alias is is?
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
RbConfig::CONFIG['host_os']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module_function
|
18
|
+
|
19
|
+
# Returns true if operating system is Linux
|
20
|
+
def linux?
|
21
|
+
OS.is? /linux|cygwin/
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns true if Operating system is OsX
|
25
|
+
def mac?
|
26
|
+
OS.is? /mac|darwin/
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/systemstats.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.join(*%w[ .. lib ]), File.dirname(__FILE__))
|
2
|
+
require 'systemstats'
|
3
|
+
|
4
|
+
def self.stub_all_syscalls
|
5
|
+
Dir.stub(:chdir)
|
6
|
+
Kernel.stub(:system)
|
7
|
+
bundler_helper.stub(:system)
|
8
|
+
end
|
9
|
+
|
10
|
+
def mock_next_io(str)
|
11
|
+
include RSpec::Mocks::ExampleMethods
|
12
|
+
io = mock('IO Connection').as_null_object
|
13
|
+
IO.stub!(:new).and_return(io)
|
14
|
+
IO.stub!(:popen).and_return(io)
|
15
|
+
io.stub!(:write){|b| b.size}
|
16
|
+
io.stub!(:readlines).and_return(str)
|
17
|
+
io.stub!(:flush).and_return(io)
|
18
|
+
io.stub!(:close).and_return(nil)
|
19
|
+
io.stub!(:pid).and_return(rand(300))
|
20
|
+
end
|
21
|
+
|
22
|
+
def unmock_io
|
23
|
+
io_proxy = IO.send(:__mock_proxy)
|
24
|
+
io_proxy.reset
|
25
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe SystemStats::IoStatReader do
|
5
|
+
|
6
|
+
#pre-made response
|
7
|
+
let (:mock_iostat_output_linux) {[
|
8
|
+
"Linux 2.6.32-312-ec2 (domU-12-31-39-0A-70-82) 05/15/2013 _x86_64_ (2 CPU)",
|
9
|
+
"avg-cpu: %user %nice %system %iowait %steal %idle",
|
10
|
+
"0.41 0.00 0.44 0.01 0.32 98.82",
|
11
|
+
"Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util",
|
12
|
+
"sda1 0.00 0.33 0.00 0.19 0.01 4.13 22.02 0.01 28.66 0.75 0.01",
|
13
|
+
"sdb 0.00 0.00 0.00 0.00 0.00 0.00 10.35 0.00 3.51 3.50 0.00"]}
|
14
|
+
|
15
|
+
let(:stats) do
|
16
|
+
stats = SystemStats::IoStatReader.new
|
17
|
+
end
|
18
|
+
|
19
|
+
before(:each) do
|
20
|
+
mock_next_io(mock_iostat_output_linux)
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:each) do
|
24
|
+
unmock_io
|
25
|
+
end
|
26
|
+
|
27
|
+
it "creates a new instance" do
|
28
|
+
stats.stub(:readlines).and_return(mock_iostat_output_linux)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return the average cpu_user_average for the current cpu" do
|
32
|
+
stats.cpu_user_average.should == '0.01'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return the average cpu_system_average for the current cpu" do
|
36
|
+
stats.cpu_system_average.should == '0.32'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return the average cpu_user_average for the current cpu" do
|
40
|
+
stats.cpu_idle_average.should == '98.82'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return the megabytes per second for disk 0" do
|
44
|
+
stats.disk_megabytes_per_second(0).should == '0.44'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should fail on a non existent disk" do
|
48
|
+
stats.disk_megabytes_per_second(100).should_not == '0.27'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should fail on a random string as disk" do
|
52
|
+
stats.disk_megabytes_per_second('randomdisk').should raise_error
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return the transfer per second for disk 0" do
|
56
|
+
stats.disk_transfers_per_second(0) == '12'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return the transfer per second for disk 0" do
|
60
|
+
stats.disk_kb_per_transfer(0) == '23.41'
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SystemStats::IoStatReader do
|
4
|
+
|
5
|
+
describe 'Osx Iostats' do
|
6
|
+
|
7
|
+
#pre-made response
|
8
|
+
let (:mock_iostat_output_osx) {
|
9
|
+
["disk0 cpu load average",
|
10
|
+
"KB/t tps MB/s us sy id 1m 5m 15m",
|
11
|
+
"23.41 12 0.27 4 2 94 0.71 0.80 0.75"]}
|
12
|
+
|
13
|
+
let(:stats) do
|
14
|
+
stats = SystemStats::IoStatReader.new
|
15
|
+
end
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
mock_next_io(mock_iostat_output_osx)
|
19
|
+
end
|
20
|
+
|
21
|
+
after(:each) do
|
22
|
+
unmock_io
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should return the average cpu_user_average for the current cpu" do
|
26
|
+
stats.cpu_user_average.should == '4'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return the average cpu_system_average for the current cpu" do
|
30
|
+
stats.cpu_system_average.should == '2'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return the average cpu_user_average for the current cpu" do
|
34
|
+
stats.cpu_idle_average.should == '94'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "creates a new instance" do
|
38
|
+
stats.stub(:readlines).and_return(mock_iostat_output_osx)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return the megabytes per second for disk 0" do
|
42
|
+
stats.disk_megabytes_per_second(0).should == '0.27'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should fail on a random string as disk" do
|
46
|
+
stats.disk_megabytes_per_second('randomdisk').should raise_error
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return the transfer per second for disk 0" do
|
50
|
+
stats.disk_transfers_per_second(0) == '12'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return the transfer per second for disk 0" do
|
54
|
+
stats.disk_kb_per_transfer(0) == '23.41'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/systemstats.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'systemstats/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "systemstats"
|
8
|
+
gem.version = SystemStats::VERSION
|
9
|
+
gem.authors = ["Ivan Marcin"]
|
10
|
+
gem.email = ["ivan.marcin@lookout.com"]
|
11
|
+
gem.description = %q{Retrieves machine stats, including cpu,memory,disk,io}
|
12
|
+
gem.summary = %q{Library to access a machine's performance stats}
|
13
|
+
gem.homepage = "https://source.flexilis.local/gems/systemstats"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "json"
|
21
|
+
gem.add_dependency "git"
|
22
|
+
gem.add_dependency "activesupport"
|
23
|
+
|
24
|
+
gem.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
gem.add_development_dependency "rake"
|
26
|
+
gem.add_development_dependency "rspec"
|
27
|
+
gem.add_development_dependency "ruby-debug"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: systemstats
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: -2034994314
|
5
|
+
prerelease: 4
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- dev
|
10
|
+
version: 0.1.dev
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ivan Marcin
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-05-29 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: json
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: git
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: activesupport
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: bundler
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
hash: 9
|
71
|
+
segments:
|
72
|
+
- 1
|
73
|
+
- 3
|
74
|
+
version: "1.3"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: rake
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rspec
|
93
|
+
prerelease: false
|
94
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
type: :development
|
104
|
+
version_requirements: *id006
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: ruby-debug
|
107
|
+
prerelease: false
|
108
|
+
requirement: &id007 !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
|
+
type: :development
|
118
|
+
version_requirements: *id007
|
119
|
+
description: Retrieves machine stats, including cpu,memory,disk,io
|
120
|
+
email:
|
121
|
+
- ivan.marcin@lookout.com
|
122
|
+
executables: []
|
123
|
+
|
124
|
+
extensions: []
|
125
|
+
|
126
|
+
extra_rdoc_files: []
|
127
|
+
|
128
|
+
files:
|
129
|
+
- .gitignore
|
130
|
+
- Gemfile
|
131
|
+
- LICENSE.txt
|
132
|
+
- README.md
|
133
|
+
- Rakefile
|
134
|
+
- lib/systemstats.rb
|
135
|
+
- lib/systemstats/iostat_reader.rb
|
136
|
+
- lib/systemstats/os_detect.rb
|
137
|
+
- lib/systemstats/version.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
- spec/unit/iostat_linux_spec.rb
|
140
|
+
- spec/unit/iostat_osx_spec.rb
|
141
|
+
- systemstats.gemspec
|
142
|
+
homepage: https://source.flexilis.local/gems/systemstats
|
143
|
+
licenses: []
|
144
|
+
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
hash: 3
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
version: "0"
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
none: false
|
161
|
+
requirements:
|
162
|
+
- - ">"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
hash: 25
|
165
|
+
segments:
|
166
|
+
- 1
|
167
|
+
- 3
|
168
|
+
- 1
|
169
|
+
version: 1.3.1
|
170
|
+
requirements: []
|
171
|
+
|
172
|
+
rubyforge_project:
|
173
|
+
rubygems_version: 1.8.24
|
174
|
+
signing_key:
|
175
|
+
specification_version: 3
|
176
|
+
summary: Library to access a machine's performance stats
|
177
|
+
test_files:
|
178
|
+
- spec/spec_helper.rb
|
179
|
+
- spec/unit/iostat_linux_spec.rb
|
180
|
+
- spec/unit/iostat_osx_spec.rb
|