datacenter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3fa2516a5f477daf4eeadc79df36156fbafec2a5
4
+ data.tar.gz: 5c41eb5080de83a1d8e6dc0db5fd3cfc959d5de7
5
+ SHA512:
6
+ metadata.gz: 50b3a3429d16c823b19d5cc99e738b95fbafb1d32ee7aa14ba10f7adeb804213dc71c1033fa9137e5217e037c8e897c918a9e2bac0734ee6c4d217e0dc5a0756
7
+ data.tar.gz: 5be18502eaaf0e95960cefa2ecca5d062920e377d0154f648563118d12197da4cb5a60f665531dedf33a8c2f3eb5ac7183fb07b6cc00319530ad6838a71f8547
data/.coveralls.yml ADDED
@@ -0,0 +1,2 @@
1
+ service_name: travis-ci
2
+ repo_token: 83Qyu0lVODgDmi68xxsdXE3aJdwY1h78X
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0
5
+ - 2.1
6
+ - jruby
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in datacenter.gemspec
4
+ gemspec
5
+
6
+ gem 'coveralls', require: false
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Gabriel Naiman
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
@@ -0,0 +1,35 @@
1
+ # Datacenter
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/datacenter.png)](https://rubygems.org/gems/datacenter)
4
+ [![Build Status](https://travis-ci.org/gabynaiman/datacenter.png?branch=master)](https://travis-ci.org/gabynaiman/datacenter)
5
+ [![Coverage Status](https://coveralls.io/repos/gabynaiman/datacenter/badge.png?branch=master)](https://coveralls.io/r/gabynaiman/datacenter?branch=master)
6
+ [![Code Climate](https://codeclimate.com/github/gabynaiman/datacenter.png)](https://codeclimate.com/github/gabynaiman/datacenter)
7
+ [![Dependency Status](https://gemnasium.com/gabynaiman/datacenter.png)](https://gemnasium.com/gabynaiman/datacenter)
8
+
9
+ Manage and monitor servers and processes
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'datacenter'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install datacenter
24
+
25
+ ## Usage
26
+
27
+ TODO: Write usage instructions here
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it ( https://github.com/[my-github-username]/datacenter/fork )
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:spec) do |t|
5
+ t.libs << 'spec'
6
+ t.pattern = 'spec/**/*_spec.rb'
7
+ t.verbose = false
8
+ end
9
+
10
+ desc 'Console'
11
+ task :console do
12
+ require 'pry'
13
+ require 'datacenter'
14
+ ARGV.clear
15
+ Pry.start
16
+ end
17
+
18
+ task default: :spec
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'datacenter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'datacenter'
8
+ spec.version = Datacenter::VERSION
9
+ spec.authors = ['Gabriel Naiman']
10
+ spec.email = ['gabynaiman@gmail.com']
11
+ spec.description = 'Manage and monitor servers and processes'
12
+ spec.summary = 'Manage and monitor servers and processes'
13
+ spec.homepage = 'https://github.com/gabynaiman/datacenter'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'net-ssh'
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.3'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'minitest', '~> 4.7'
26
+ spec.add_development_dependency 'turn', '~> 0.9'
27
+ spec.add_development_dependency 'simplecov'
28
+ spec.add_development_dependency 'pry'
29
+ end
@@ -0,0 +1,117 @@
1
+ module Datacenter
2
+ class Machine
3
+
4
+ attr_reader :shell
5
+
6
+ def initialize(shell=nil)
7
+ @shell = shell || Shell::Localhost.new
8
+ end
9
+
10
+ def ips
11
+ shell.run('ifconfig')
12
+ .scan(/inet addr:(([0-9]*\.){3}[0-9]*)/)
13
+ .map { |s| s[0] }
14
+ end
15
+
16
+ def name
17
+ shell.run('hostname').strip
18
+ end
19
+
20
+ def os
21
+ @os ||= OS.new shell
22
+ end
23
+
24
+ def cpu
25
+ cpuinfo['model name']
26
+ end
27
+
28
+ def cores
29
+ shell.run('nproc').to_i
30
+ end
31
+
32
+ def memory
33
+ meminfo['MemTotal'].to_i / 1024.0
34
+ end
35
+
36
+ def memory_free
37
+ meminfo['MemFree'].to_i / 1024.0
38
+ end
39
+
40
+ def memory_used
41
+ memory - memory_free
42
+ end
43
+
44
+ def swap
45
+ meminfo['SwapTotal'].to_i / 1024.0
46
+ end
47
+
48
+ def swap_free
49
+ meminfo['SwapFree'].to_i / 1024.0
50
+ end
51
+
52
+ def swap_used
53
+ swap - swap_free
54
+ end
55
+
56
+ def disk_partitions
57
+ partitions.map { |p| DiskPartition.new p }
58
+ end
59
+
60
+ def processes(filter='')
61
+ if filter.empty?
62
+ command = 'ps aux'
63
+ start = 1
64
+ else
65
+ command = "ps aux | grep #{filter} | grep -v grep"
66
+ start = 0
67
+ end
68
+ shell.run(command)
69
+ .split("\n")[start..-1]
70
+ .map { |l| Datacenter::Process.new l.split[1], self }
71
+ end
72
+
73
+ def top(order,n=10)
74
+ mappings = { memory: 'rss', pid: 'pid', cpu: '%cpu' }
75
+ shell.run("ps aux --sort -#{mappings[order]} | head -n #{n+1}")
76
+ .split("\n")[1..-1]
77
+ .map { |l| Datacenter::Process.new l.split[1], self }
78
+ end
79
+
80
+ private
81
+
82
+ def partitions
83
+ shell.run('df -lT')
84
+ .scan(/^\/dev.*/)
85
+ .map do |p|
86
+ line = p.split
87
+ {
88
+ filesystem: line[0],
89
+ type: line[1],
90
+ size: line[2].to_f / 1024,
91
+ used: line[3].to_f / 1024,
92
+ available: line[4].to_f / 1024,
93
+ used_percentage: line[5].to_f,
94
+ mounted: line[6]
95
+ }
96
+ end
97
+ end
98
+
99
+ def meminfo
100
+ Hash[shell.run('cat /proc/meminfo').split("\n").map { |e| e.split(':').map(&:strip) }]
101
+ end
102
+
103
+ def cpuinfo
104
+ Hash[shell.run('cat /proc/cpuinfo').split("\n").select {|e| e.length>0}.map { |e| e.split(':').map(&:strip) }]
105
+ end
106
+
107
+ class DiskPartition
108
+ attr_reader :filesystem, :type, :size, :used, :available, :used_percentage, :mounted
109
+
110
+ def initialize(attributes)
111
+ attributes.each do |name, value|
112
+ instance_variable_set "@#{name}", value if respond_to? name
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,33 @@
1
+ module Datacenter
2
+ class OS
3
+
4
+ def initialize(shell=nil)
5
+ @shell = shell || Shell::Localhost.new
6
+ end
7
+
8
+ def name
9
+ shell.run 'uname -o'
10
+ end
11
+
12
+ def distribution
13
+ shell.run('lsb_release -i').split(':')[1].strip
14
+ end
15
+
16
+ def version
17
+ shell.run('lsb_release -r').split(':')[1].strip
18
+ end
19
+
20
+ def kernel
21
+ shell.run 'uname -r'
22
+ end
23
+
24
+ def platform
25
+ shell.run 'uname -i'
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :shell
31
+
32
+ end
33
+ end
@@ -0,0 +1,67 @@
1
+ module Datacenter
2
+ class Process
3
+
4
+ ATTRIBUTES = [
5
+ :command,
6
+ :status,
7
+ :memory,
8
+ :virtual_memory,
9
+ :cpu,
10
+ :user,
11
+ :name,
12
+ :cpu_usage,
13
+ :mem_usage
14
+ ]
15
+
16
+ TIME_CACHE = 2
17
+
18
+ attr_reader :pid, :machine, :cache
19
+
20
+ def initialize(pid, machine=nil)
21
+ @pid = pid
22
+ @machine = machine
23
+ @cache = {:fetched=>0, :content=>[]}
24
+ end
25
+
26
+ def alive?
27
+ !(machine.shell.run 'ls /proc').scan("\n#{pid}\n").empty?
28
+ end
29
+
30
+ ATTRIBUTES.each do |attribute|
31
+ define_method attribute do
32
+ info[attribute]
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def info
39
+ if cache[:content].empty? || (Time.now - cache[:fetched] > TIME_CACHE)
40
+ ps = machine.shell.run('ps aux').scan(/.*#{pid}.*/)[0].split
41
+ Hash.new.tap do |info|
42
+ status = Hash[proc_file(:status).split("\n").map{ |s| s.split(':').map(&:strip) }]
43
+ info[:name] = status['Name']
44
+ info[:user] = ps[0]
45
+ info[:pid] = ps[1]
46
+ info[:cpu_usage] = ps[2].to_f
47
+ info[:mem_usage] = ps[3].to_f
48
+ info[:virtual_memory] = ps[4].to_i / 1024.0
49
+ info[:memory] = ps[5].to_i / 1024.0
50
+ info[:status] = ps[7]
51
+ info[:command] = ps[10..-1].reduce {|acum,e| "#{acum} #{e}"}
52
+ @cache = {:fetched => Time.now, :content=>info}
53
+ end
54
+ else
55
+ cache[:content]
56
+ end
57
+ end
58
+
59
+ def proc_dir
60
+ "/proc/#{pid}"
61
+ end
62
+
63
+ def proc_file(file)
64
+ machine.shell.run "cat #{File.join(proc_dir, file.to_s)}"
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,45 @@
1
+ module Datacenter
2
+ module Shell
3
+
4
+ class Localhost
5
+ def run(command)
6
+ `#{command}`.strip
7
+ end
8
+ end
9
+
10
+ class Ssh
11
+ attr_reader :ssh_args
12
+
13
+ def initialize(*args)
14
+ @ssh_args = args
15
+ end
16
+
17
+ def run(command)
18
+ if @session
19
+ @session.exec!(command).strip
20
+ else
21
+ Net::SSH.start(*@ssh_args) { |ssh| ssh.exec! command }.strip
22
+ end
23
+ end
24
+
25
+ def open
26
+ @session = Net::SSH.start *@ssh_args unless @session
27
+ end
28
+
29
+ def close
30
+ if @session
31
+ @session.close
32
+ @session = nil
33
+ end
34
+ end
35
+
36
+ def self.open(*args, &block)
37
+ shell = new *args
38
+ shell.open
39
+ block.call shell
40
+ shell.close
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module Datacenter
2
+ VERSION = "0.0.1"
3
+ end
data/lib/datacenter.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'net/ssh'
2
+
3
+ Dir.glob(File.expand_path('datacenter/*.rb', File.dirname(__FILE__))).sort.each { |f| require f }
data/monitor.rb ADDED
@@ -0,0 +1,106 @@
1
+ require_relative 'lib/datacenter.rb'
2
+ require 'hirb'
3
+ require 'benchmark'
4
+ extend Hirb::Console
5
+
6
+ ## Set up
7
+ server = ARGV[0]
8
+ user = ARGV[1]
9
+
10
+ shell = Datacenter::Shell::Ssh.new server,user
11
+ shell.open
12
+ machine = Datacenter::Machine.new shell
13
+
14
+ ## General Information
15
+ puts "General Information \n\n"
16
+
17
+ # Server name
18
+ server = [{:value=>"Server : #{server} \n", :level=>0}]
19
+ # Operating System
20
+ os = [{:value=>"Operating System", :level=>0}]
21
+ os << {:value=>"#{machine.os.name} #{machine.os.distribution}" "#{machine.os.version}", :level=>3}
22
+ os << {:value=>"Kernel #{machine.os.kernel} #{machine.os.platform}", :level=>3}
23
+ # Hardware
24
+ hw = [{:value=>"Hardware", :level=>0}]
25
+ hw << {:value=>"Memory: #{machine.memory.to_i} MB", :level=>3}
26
+ hw << {:value=>"Processor: #{machine.cpu} x #{machine.cores}", :level=>3}
27
+ # Status
28
+ st = [{:value=>"Status", :level=>0}]
29
+ st += machine.disk_partition.map { |p| Hash[:value => "Partition #{p.filesystem}: #{p.available.to_i} MB available", :level=>3] }
30
+ st << {:value=>"Memory Free: #{machine.memory_free.to_i} MB", :level=>3}
31
+ st << {:value=>"Swap Free: #{machine.swap_free.to_i} MB", :level=>3}
32
+
33
+ info_machine = server + os + hw + st
34
+ puts "#{Hirb::Helpers::Tree.render(info_machine)} \n"
35
+
36
+ ## Detailed Information
37
+ puts "\n\nDetailed Information \n\n"
38
+
39
+ filter_size = Proc.new{|e| "#{e.to_i} MB"}
40
+ filter_perc = Proc.new{|e| "#{e} %"}
41
+
42
+ puts 'Operating System'
43
+ os_fields = [:name, :distribution, :platform, :kernel, :version]
44
+ table machine.os, :fields=>os_fields
45
+
46
+ puts 'Hardware'
47
+
48
+ hw_fields = [:cpu, :cores, :memory]
49
+ table machine, :fields=>hw_fields, :filters=>{:memory=>filter_size}
50
+
51
+ puts 'Processes With Filter'
52
+ pr_fields = [:name, :mem_usage, :cpu_usage, :command, :status, :user]
53
+ puts "Time: #{Benchmark.measure { table machine.processes('ruby'), :fields=>pr_fields,
54
+ :filters=>{:mem_usage=>filter_perc,
55
+ :cpu_usage=>filter_perc}}.real }"
56
+
57
+ puts 'Top Processes by Memory Usage'
58
+ pr_fields = [:name, :mem_usage, :cpu_usage, :command, :status, :user]
59
+ puts "Time: #{Benchmark.measure { table machine.top(:memory), :fields=>pr_fields,
60
+ :filters=>{:mem_usage=>filter_perc,
61
+ :cpu_usage=>filter_perc}}.real }"
62
+
63
+ puts 'Top Processes by CPU Usage'
64
+ puts "Time: #{Benchmark.measure { table machine.top(:cpu), :fields=>pr_fields,
65
+ :filters=>{:mem_usage=>filter_perc,
66
+ :cpu_usage=>filter_perc} }.real}"
67
+
68
+ puts 'Filesystems'
69
+ bench = Benchmark.measure do
70
+ hdd_fields = [:filesystem, :type, :size, :used, :available, :p_use, :mounted]
71
+ table machine.disk_partition, :fields=>hdd_fields, :filters=>{:size=>filter_size,
72
+ :used=>filter_size,
73
+ :available=>filter_size,
74
+ :p_use=>filter_perc}
75
+ end
76
+ puts "Time: #{bench.real}"
77
+
78
+ puts 'Memory'
79
+ bench = Benchmark.measure do
80
+ mem_fields = [:memory, :memory_free, :memory_used, :swap, :swap_used, :swap_free]
81
+ table machine, :fields=>mem_fields, :filters=> Hash.new.tap { |f| mem_fields.map { |e| f[e]=filter_size } }
82
+ end
83
+ puts "Time #{bench.real}"
84
+
85
+ ## Menu: TODO: Hay que definir como usarlo, es para verlo
86
+ class InfoMachineType
87
+ attr_reader :description
88
+
89
+ def initialize(description, detail)
90
+ @description = description
91
+ @detail = detail
92
+ end
93
+
94
+ def detail
95
+ Hirb::Helpers::Tree.render(@detail)
96
+ end
97
+ end
98
+
99
+ type_gen = InfoMachineType.new 'Informacion General', info_machine
100
+ type_det = InfoMachineType.new 'Info Detallada', info_machine
101
+
102
+ puts menu [type_gen, type_det], :prompt=> "Elegir opción: ",
103
+ :fields => [:description],
104
+ :default_field=>
105
+ :detail,
106
+ :two_d=>true
data/spec/commands.yml ADDED
@@ -0,0 +1,152 @@
1
+ ---
2
+ "uname -i": x86_64
3
+
4
+ "uname -r": 3.5.0-49-generic
5
+
6
+ "uname -o": GNU/Linux
7
+
8
+ "lsb_release -i": "Distributor ID: Ubuntu"
9
+
10
+ "lsb_release -r": "Release: 12.04"
11
+
12
+ hostname: |
13
+ matias
14
+
15
+ nproc: |
16
+ 2
17
+
18
+ "df -lT": |
19
+ Filesystem Type 1K-blocks Used Available Use% Mounted on
20
+ /dev/sda1 ext4 303546744 4722968 283404488 2% /
21
+ /dev/sdb1 ext4 293458489 3956948 208455288 15% /sys
22
+ udev devtmpfs 2010472 4 2010468 1% /dev
23
+ tmpfs tmpfs 403964 824 403140 1% /run
24
+ none tmpfs 5120 0 5120 0% /run/lock
25
+ none tmpfs 2019816 512 2019304 1% /run/shm
26
+
27
+ ifconfig: |
28
+ eth4 Link encap:Ethernet HWaddr e0:cb:4e:c2:99:9d
29
+ inet addr:192.168.50.127 Bcast:192.168.50.255 Mask:255.255.255.0
30
+ inet6 addr: fe80::e2cb:4eff:fec2:999d/64 Scope:Link
31
+ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
32
+ RX packets:349964 errors:0 dropped:0 overruns:0 frame:0
33
+ TX packets:118783 errors:0 dropped:0 overruns:0 carrier:0
34
+ collisions:0 txqueuelen:1000
35
+ RX bytes:110494415 (110.4 MB) TX bytes:21453491 (21.4 MB)
36
+
37
+ lo Link encap:Local Loopback
38
+ inet addr:127.0.0.1 Mask:255.0.0.0
39
+ inet6 addr: ::1/128 Scope:Host
40
+ UP LOOPBACK RUNNING MTU:16436 Metric:1
41
+ RX packets:24200 errors:0 dropped:0 overruns:0 frame:0
42
+ TX packets:24200 errors:0 dropped:0 overruns:0 carrier:0
43
+ collisions:0 txqueuelen:0
44
+ RX bytes:2760696 (2.7 MB) TX bytes:2760696 (2.7 MB)
45
+
46
+ "cat /proc/meminfo": |
47
+ MemTotal: 4039632 kB
48
+ MemFree: 1293268 kB
49
+ Buffers: 169960 kB
50
+ Cached: 1292480 kB
51
+ SwapCached: 0 kB
52
+ Active: 1898944 kB
53
+ Inactive: 650700 kB
54
+ Active(anon): 1288260 kB
55
+ Inactive(anon): 141764 kB
56
+ Active(file): 610684 kB
57
+ Inactive(file): 508936 kB
58
+ Unevictable: 0 kB
59
+ Mlocked: 0 kB
60
+ SwapTotal: 4183036 kB
61
+ SwapFree: 4183036 kB
62
+ Dirty: 356 kB
63
+
64
+ "cat /proc/cpuinfo": |
65
+ processor : 0
66
+ vendor_id : GenuineIntel
67
+ cpu family : 6
68
+ model : 23
69
+ model name : Intel(R) Core(TM)2 Duo CPU E7500 @ 2.93GHz
70
+ stepping : 10
71
+ microcode : 0xa07
72
+ cpu MHz : 2926.000
73
+ cache size : 3072 KB
74
+ physical id : 0
75
+ siblings : 2
76
+ core id : 0
77
+
78
+
79
+ "ps aux --sort -rss | head -n 11": |
80
+ USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
81
+ matias 22322 5.2 21.5 1531844 872460 ? Sl 09:35 20:53 /usr/lib/firefox/firefox
82
+ matias 1683 0.5 2.4 1371260 99364 ? Sl May15 10:17 compiz
83
+ matias 22376 0.9 2.0 2107500 84000 ? Sl 09:36 3:51 /opt/sublime_text/sublime_text
84
+ matias 27949 0.4 1.1 452060 47676 ? Sl 11:48 1:09 /usr/lib/firefox/plugin-container /usr/lib/flashplugin-installer/libflashplay
85
+ matias 1755 0.0 1.0 549020 44088 ? Sl May15 0:31 /usr/lib/unity/unity-panel-service
86
+ matias 1704 0.0 0.8 919756 35580 ? Sl May15 0:06 nautilus -n
87
+ matias 1473 0.0 0.8 106696 34208 pts/1 Sl+ 15:27 0:00 /home/matias/.rvm/rubies/ruby-2.0.0-p451/bin/rake
88
+ matias 22803 11.7 0.8 512092 32632 ? Rl 09:43 45:48 gnome-system-monitor
89
+ matias 22392 0.2 0.7 350564 31900 ? Sl 09:36 0:50 /opt/sublime_text/plugin_host 22376
90
+ matias 1971 0.0 0.6 554976 25388 ? Sl May15 0:02 /usr/bin/python /usr/lib/unity-scope-video-remote/unity-scope-video-remote
91
+ matias 3494 0.0 0.6 497476 25268 ? Sl 15:56 0:00 gedit
92
+
93
+ "ps aux --sort -%cpu | head -n 11" : |
94
+ USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
95
+ matias 22803 11.7 0.8 512088 32632 ? Sl 09:43 45:54 gnome-system-monitor
96
+ matias 22322 5.2 19.8 1490884 802188 ? Sl 09:35 20:57 /usr/lib/firefox/firefox
97
+ root 971 1.0 0.6 105380 24492 tty7 Ss+ May15 20:07 /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -b
98
+ matias 22376 0.9 2.1 2117648 85696 ? Sl 09:36 3:56 /opt/sublime_text/sublime_text
99
+ matias 1683 0.5 2.4 1371256 99360 ? Sl May15 10:18 compiz
100
+ matias 27949 0.4 1.1 452060 47676 ? Sl 11:48 1:09 /usr/lib/firefox/plugin-container /usr/lib/flashplugin-installer/libflashplay
101
+ matias 22392 0.2 0.7 350564 31944 ? Sl 09:36 0:50 /opt/sublime_text/plugin_host 22376
102
+ matias 22577 0.1 0.5 555828 24124 ? Sl 09:42 0:33 gnome-terminal
103
+
104
+ "ps aux --sort -pid | head -n 11": |
105
+ USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
106
+ root 28382 0.0 0.0 23820 692 ? Ss 11:55 0:00 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
107
+ root 28381 0.0 0.0 26564 540 ? S 11:55 0:00 dbus-launch --autolaunch=31627581c457d548441745e800000005 --binary-syntax --c
108
+ matias 27949 0.4 1.1 452060 47676 ? Sl 11:48 1:10 /usr/lib/firefox/plugin-container /usr/lib/flashplugin-installer/libflashplay
109
+ root 25129 0.0 0.0 50040 2932 ? Ss 10:46 0:00 /usr/sbin/sshd -D
110
+ matias 23542 0.0 0.2 34216 11408 pts/0 Ss 10:24 0:01 -bash
111
+ matias 22903 0.0 0.2 34164 11360 pts/1 Ss 09:46 0:00 -bash
112
+
113
+ "ps aux": |
114
+ USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
115
+ root 1 0.0 0.0 24548 2460 ? Ss May15 0:00 /sbin/init
116
+ root 2 0.0 0.0 0 0 ? S May15 0:00 [kthreadd]
117
+ root 3 0.0 0.0 0 0 ? S May15 0:06 [ksoftirqd/0]
118
+ root 6 0.0 0.0 0 0 ? S May15 0:00 [migration/0]
119
+ root 7 0.0 0.0 0 0 ? S May15 0:00 [watchdog/0]
120
+ root 8 0.0 0.0 0 0 ? S May15 0:00 [migration/1]
121
+ matias 22803 11.9 0.8 513268 33792 ? Sl 09:43 52:47 gnome-system-monitor
122
+
123
+ ps aux | grep gnome-system-monitor | grep -v grep: |
124
+ matias 22803 7.2 0.8 597980 34948 ? Sl May21 136:34 gnome-system-monitor
125
+
126
+ "cat /proc/22803/status": |
127
+ Name: gnome-system-mo
128
+ State: S (sleeping)
129
+ Tgid: 22803
130
+ Pid: 22803
131
+ PPid: 1
132
+ TracerPid: 0
133
+ Uid: 1000 1000 1000 1000
134
+ Gid: 1000 1000 1000 1000
135
+ FDSize: 64
136
+ Groups: 4 24 27 30 46 109 124 1000
137
+ VmPeak: 608584 kB
138
+ VmSize: 512088 kB
139
+ VmLck: 0 kB
140
+ VmPin: 0 kB
141
+ VmHWM: 32632 kB
142
+ VmRSS: 32632 kB
143
+ VmData: 302676 kB
144
+ VmStk: 136 kB
145
+ VmExe: 264 kB
146
+ VmLib: 27732 kB
147
+ VmPTE: 556 kB
148
+ VmSwap: 0 kB
149
+ Threads: 4
150
+
151
+ "ls /proc": "18\n1813\n22803\n22903\n23\n2350\n23542\n2370\n246\n247\n25129\ntimer_list\nvmstat\nzoneinfo"
152
+
@@ -0,0 +1,2 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
@@ -0,0 +1,132 @@
1
+ require 'minitest_helper'
2
+
3
+ describe Datacenter do
4
+
5
+ COMMANDS_FILE = File.join(File.dirname(__FILE__), 'commands.yml')
6
+
7
+ describe Datacenter::OS do
8
+
9
+ let(:shell) { Datacenter::Shell::Mock.new COMMANDS_FILE }
10
+ let(:os) { Datacenter::OS.new shell }
11
+
12
+ it ('Name') { os.name.must_equal 'GNU/Linux' }
13
+
14
+ it ('Distribution') { os.distribution.must_equal 'Ubuntu' }
15
+
16
+ it ('Version') { os.version.must_equal '12.04' }
17
+
18
+ it ('Kernel') { os.kernel.must_equal '3.5.0-49-generic' }
19
+
20
+ it ('Platform') { os.platform.must_equal 'x86_64' }
21
+
22
+ end
23
+
24
+ describe Datacenter::Machine do
25
+
26
+ describe 'Local' do
27
+
28
+ let(:shell) { Datacenter::Shell::Mock.new COMMANDS_FILE }
29
+ let(:machine) { Datacenter::Machine.new shell}
30
+
31
+ it ('IPs') { machine.ips.must_equal %w(192.168.50.127 127.0.0.1) }
32
+
33
+ it ('Name') { machine.name.must_equal "matias" }
34
+
35
+ it 'OS' do
36
+ machine.os.name.must_equal 'GNU/Linux'
37
+ machine.os.distribution.must_equal 'Ubuntu'
38
+ machine.os.version.must_equal '12.04'
39
+ end
40
+
41
+ it ('CPU') { machine.cpu.must_equal 'Intel(R) Core(TM)2 Duo CPU E7500 @ 2.93GHz'}
42
+
43
+ it ('Cores') { machine.cores.must_equal 2 }
44
+
45
+ it ('Total Memory') { machine.memory.must_equal 3944.953125 }
46
+
47
+ it ('Free Memory') { machine.memory_free.must_equal 1262.95703125 }
48
+
49
+ it ('Used Memory') { machine.memory_used.must_equal 2681.99609375 }
50
+
51
+ it ('Total Swap') { machine.swap.must_equal 4084.99609375 }
52
+
53
+ it ('Free Swap') { machine.swap_free.must_equal 4084.99609375 }
54
+
55
+ it ('Used Swap') { machine.swap_used.must_equal 0.0}
56
+
57
+ it ('List of Proccess') { machine.processes.find {|p| p.pid=="22803"}.command.must_equal 'gnome-system-monitor' }
58
+
59
+ it ('List of Proccess With Filter') { machine.processes('gnome-system-monitor').find {|p| p.pid=="22803"}.name.must_equal 'gnome-system-mo' }
60
+
61
+ it ('Top by Memory') { machine.top(:memory)[7].command.must_equal 'gnome-system-monitor' }
62
+
63
+ it ('Top by CPU') { machine.top(:cpu)[0].command.must_equal 'gnome-system-monitor' }
64
+
65
+ describe 'Disk Paritions' do
66
+
67
+ it ('Size') { machine.disk_partitions.map(&:size).must_equal [296432.3671875, 286580.5556640625] }
68
+
69
+ it ('Available') { machine.disk_partitions.map(&:available).must_equal [276762.1953125, 203569.6171875] }
70
+
71
+ it ('Used') { machine.disk_partitions.map(&:used).must_equal [4612.2734375, 3864.20703125] }
72
+
73
+ it ('% Use') { machine.disk_partitions.map(&:used_percentage).must_equal [2, 15] }
74
+
75
+ it ('Filesystem') { machine.disk_partitions.map(&:filesystem).must_equal ["/dev/sda1", "/dev/sdb1"] }
76
+
77
+ it ('Type') { machine.disk_partitions.map(&:type).must_equal ["ext4", "ext4"] }
78
+
79
+ it ('Mounted on') { machine.disk_partitions.map(&:mounted).must_equal ["/", "/sys"] }
80
+ end
81
+
82
+ end
83
+
84
+ describe Datacenter::Process do
85
+
86
+ let(:pid) { 22803 }
87
+ let(:shell) { Datacenter::Shell::Mock.new COMMANDS_FILE }
88
+ let(:machine) { Datacenter::Machine.new shell}
89
+ let(:process) { Datacenter::Process.new pid,machine }
90
+
91
+ it ('Pid') { process.pid.must_equal pid }
92
+
93
+ it ('Alive') { process.alive?.must_equal true }
94
+
95
+ it 'Dead' do
96
+ process = Datacenter::Process.new -1,machine
97
+ process.alive?.must_equal false
98
+ end
99
+
100
+ it ('Name') { process.name.must_equal 'gnome-system-mo' }
101
+
102
+ it ('Command') { process.command.must_equal 'gnome-system-monitor' }
103
+
104
+ it ('Memory') { process.memory.must_equal 33.0 }
105
+
106
+ it ('Virtual Memory') { process.virtual_memory.must_equal 501.23828125 }
107
+
108
+ it ('% Memory') { process.mem_usage.must_equal 0.8}
109
+
110
+ it ('% CPU') { process.cpu_usage.must_equal 11.9 }
111
+
112
+ it ('Status') { process.status.must_equal 'Sl' }
113
+
114
+ it ('User') { process.user.must_equal 'matias' }
115
+
116
+ end
117
+
118
+ end
119
+
120
+ describe Datacenter::Shell::Ssh do
121
+
122
+ let(:shell) { Datacenter::Shell::Ssh.new 'localhost', `whoami`.strip }
123
+
124
+ before { shell.open }
125
+ after { shell.close }
126
+
127
+ it 'Run' do
128
+ shell.run('ls /').must_equal `ls /`.strip
129
+ end
130
+ end
131
+
132
+ end
@@ -0,0 +1,36 @@
1
+ require 'coverage_helper'
2
+ require 'minitest/autorun'
3
+ require 'turn'
4
+ require 'yaml'
5
+ require 'datacenter'
6
+
7
+ Turn.config do |c|
8
+ c.format = :pretty
9
+ c.natural = true
10
+ c.ansi = true
11
+ end
12
+
13
+ module Datacenter
14
+ module Shell
15
+ class Mock
16
+
17
+ def initialize(file=nil)
18
+ @commands = file ? YAML.load_file(file) : {}
19
+ end
20
+
21
+ def stub(command, value=nil, &block)
22
+ commands[command] = value || block.call
23
+ end
24
+
25
+ def run(command)
26
+ raise "Undefined command: #{command}" unless commands.key? command
27
+ commands[command]
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :commands
33
+
34
+ end
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: datacenter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Gabriel Naiman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-ssh
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: turn
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.9'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Manage and monitor servers and processes
112
+ email:
113
+ - gabynaiman@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".coveralls.yml"
119
+ - ".gitignore"
120
+ - ".travis.yml"
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - datacenter.gemspec
126
+ - lib/datacenter.rb
127
+ - lib/datacenter/machine.rb
128
+ - lib/datacenter/os.rb
129
+ - lib/datacenter/process.rb
130
+ - lib/datacenter/shell.rb
131
+ - lib/datacenter/version.rb
132
+ - monitor.rb
133
+ - spec/commands.yml
134
+ - spec/coverage_helper.rb
135
+ - spec/datacenter_spec.rb
136
+ - spec/minitest_helper.rb
137
+ homepage: https://github.com/gabynaiman/datacenter
138
+ licenses:
139
+ - MIT
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.2.2
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: Manage and monitor servers and processes
161
+ test_files:
162
+ - spec/commands.yml
163
+ - spec/coverage_helper.rb
164
+ - spec/datacenter_spec.rb
165
+ - spec/minitest_helper.rb