custodian 0.0.1 → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2012 Johannes Gorset
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,23 +1,39 @@
1
1
  # Custodian
2
2
 
3
- Custodian is a lightweight resource monitor that is easy to use and augment.
3
+ Custodian is a lightweight resource monitor that makes it really easy
4
+ and really awesome to sample metrics.
4
5
 
5
6
  ## Usage
6
7
 
7
- Start Custodian and configure it to sample metrics every 60 seconds and expose
8
- them on port 5100:
8
+ ### Server
9
9
 
10
- $ custodian start 127.0.0.1:5100 --interval=60
10
+ Start Custodian and configure it to expose its metrics on port 5100:
11
11
 
12
- ## Augmenting Custodian
12
+ $ custodian --port=5100
13
13
 
14
- Custodian convenes statistics from *samplers*, which are just simple Ruby classes:
14
+ ![Example](https://github.com/jgorset/custodian/raw/master/docs/images/example.png)
15
15
 
16
- class Who << Custodian::Sampler
16
+ #### Samplers
17
17
 
18
- # Return a list of usernames describing logged-in users.
19
- def sample
20
- `who`.lines.collect { |line| line.split.first }
21
- end
18
+ Custodian aggregates metrics from *samplers*, and ships with samplers for popular figures
19
+ such as logged in users and load averages. That's interesting and all, but custom
20
+ samplers are all the rage.
22
21
 
23
- end
22
+ ```ruby
23
+ class RegisteredUsers < Custodian::Samplers::Sampler
24
+ describe "Registered users"
25
+
26
+ def self.sample
27
+ Users.count
28
+ end
29
+ end
30
+ ```
31
+
32
+ You can load your own samplers with the `--samplers` option.
33
+
34
+ $ custodian --samplers=~/.samplers
35
+
36
+ ### Clients
37
+
38
+ Unless you're crazy about JSON, you'll want to consume Custodian's API with a
39
+ *client*. Unfortunately, there are no clients for Custodian yet — you should make one!
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.test_files = FileList["test/*_test.rb"]
6
+ t.verbose = true
7
+ end
data/bin/custodian ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "custodian"
4
+
5
+ Custodian::CLI.new ARGV
data/custodian.gemspec CHANGED
@@ -19,6 +19,8 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  # specify any dependencies here; for example:
22
- # s.add_development_dependency "rspec"
23
- # s.add_runtime_dependency "rest-client"
22
+ s.add_development_dependency "rspec"
23
+ s.add_runtime_dependency "thin"
24
+ s.add_runtime_dependency "rack"
25
+ s.add_runtime_dependency "active_support"
24
26
  end
Binary file
data/lib/custodian.rb CHANGED
@@ -1,5 +1,7 @@
1
- require "custodian/version"
2
-
3
1
  module Custodian
4
- # Your code goes here...
2
+ autoload :VERSION, "custodian/version"
3
+ autoload :Samplers, "custodian/samplers"
4
+ autoload :API, "custodian/api"
5
+ autoload :CLI, "custodian/cli"
6
+ autoload :OS, "custodian/os"
5
7
  end
@@ -0,0 +1,33 @@
1
+ require "json"
2
+
3
+ module Custodian
4
+
5
+ # The API class is a Rack-compatible* application that encapsulates
6
+ # Custodian's interface.
7
+ #
8
+ # * http://rack.rubyforge.org/doc/files/SPEC.html.
9
+ class API
10
+
11
+ # Render the JSON representation of each sample.
12
+ #
13
+ # env - A Hash of CGI-like headers describing the
14
+ # environment under which the request was received.
15
+ #
16
+ # Returns an Array describing the HTTP response.
17
+ def call(env)
18
+ status = 200
19
+
20
+ headers = {
21
+ "Content-Type" => "application/json"
22
+ }
23
+
24
+ body = Custodian::Samplers.list.collect do |sampler|
25
+ { description: sampler.description, sample: sampler.sample } if sampler.compatible?
26
+ end.compact.to_json
27
+
28
+ [status, headers, [body]]
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,158 @@
1
+ require "thin"
2
+ require "rack"
3
+ require "rack/auth/basic"
4
+ require "optparse"
5
+
6
+ module Custodian
7
+
8
+ # The CLI class encapsulates Custodian's command-line interface.
9
+ class CLI
10
+ DEFAULT_PORT = 5100
11
+
12
+ # Create a new command-line interface.
13
+ #
14
+ # arguments - An Array of String objects describing arguments
15
+ # passed to the program (see CLI#parse).
16
+ def initialize(arguments)
17
+ options = parse arguments
18
+
19
+ if samplers = options[:samplers]
20
+ load_samplers samplers
21
+ end
22
+
23
+ if options.include? :daemonize
24
+ deamonize
25
+ end
26
+
27
+ if pidfile = options[:pidfile]
28
+ write_pidfile pidfile
29
+ end
30
+
31
+ log "Custodian is accepting connections on port #{options[:port]}"
32
+
33
+ compatible_samplers = Custodian::Samplers.compatible
34
+ incompatible_samplers = Custodian::Samplers.incompatible
35
+
36
+ log "#{compatible_samplers.count} compatible samplers."
37
+ compatible_samplers.each do |s|
38
+ log " - #{s.description}"
39
+ end
40
+
41
+ log "#{incompatible_samplers.count} incompatible samplers."
42
+ incompatible_samplers.each do |s|
43
+ log " - #{s.description}"
44
+ end
45
+
46
+ log "CTRL+C to stop"
47
+
48
+ Thin::Logging.silent = true
49
+ Thin::Server.start '0.0.0.0', options[:port] do
50
+ use Rack::CommonLogger
51
+ use Rack::ShowExceptions
52
+ use Rack::Auth::Basic do |username, password|
53
+ [username, password] == [options[:username], options[:password]]
54
+ end if options.include? :username
55
+
56
+ run Custodian::API.new
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ # Load samplers from the given directories.
63
+ #
64
+ # directories - An Array of Strings describing paths to directories
65
+ # that contain samplers.
66
+ #
67
+ # Returns nothing.
68
+ def load_samplers(directories)
69
+ directories.each do |directory|
70
+ Custodian::Samplers.load directory
71
+ end
72
+ end
73
+
74
+ # Write the process id to the given file.
75
+ #
76
+ # file - A String describing a path to a file. If the file does not exist, it
77
+ # will be created. If the file already exists, it will be overwritten.
78
+ #
79
+ # Returns nothing.
80
+ def write_pidfile(file)
81
+ File.open file, "w" do |file|
82
+ file << Process.id
83
+ end
84
+ end
85
+
86
+ # Daemonize the process.
87
+ def deamonize
88
+ Process.daemon
89
+ end
90
+
91
+ # Parse the given arguments or exit with an error if they are malformed and/or invalid.
92
+ #
93
+ # arguments - An Array of String objects describing arguments passed to the program.
94
+ #
95
+ # Returns a Hash of options derived from the given arguments:
96
+ # :port - An Integer describing the port to listen on.
97
+ # :samplers - An Array of String objects describing paths to load samplers from.
98
+ # :daemonize - A Boolean describing whether or not to daemonize the process.
99
+ # :pidfile - A String describing a path to a file.
100
+ # :username - A String describing a username required by HTTP Basic authentication.
101
+ # :password - A String describing a password required by HTTP Basic authentication.
102
+ def parse(arguments)
103
+ options = {
104
+ port: DEFAULT_PORT
105
+ }
106
+
107
+ OptionParser.new do |o|
108
+ o.banner = "Usage: custodian [options]"
109
+ o.version = Custodian::VERSION
110
+
111
+ o.on "-p PORT", "--port PORT", "Listen on PORT (default #{options[:port]})" do |port|
112
+ options[:port] = port
113
+ end
114
+
115
+ o.on "-s DIR", "--samplers DIR", "Load samplers from DIR" do |samplers|
116
+ options[:samplers] = samplers.split(":")
117
+ end
118
+
119
+ o.on "--daemonize", "Daemonize the process" do
120
+ options[:daemonize] = true
121
+ end
122
+
123
+ o.on "--pidfile FILE", "Write the process id to FILE" do |pidfile|
124
+ options[:pidfile] = pidfile
125
+ end
126
+
127
+ o.on "--authenticate USERNAME:PASSWORD", "Authenticate clients with the given USERNAME and PASSWORD" do |credentials|
128
+ unless credentials.include? ":"
129
+ raise OptionParser::InvalidArgument, "must be a colon-separated string of username and password"
130
+ end
131
+
132
+ options[:username], options[:password] = credentials.split(":")
133
+ end
134
+ end.parse! arguments
135
+
136
+ options
137
+ rescue OptionParser::ParseError => e
138
+ error e
139
+ end
140
+
141
+ # Log a message to STDOUT.
142
+ #
143
+ # message - A String describing a message.
144
+ def log(message)
145
+ puts ">> #{message}"
146
+ end
147
+
148
+ # Print a message and exit with the given code.
149
+ #
150
+ # message - A String describing the message to print.
151
+ # code - An Integer describing the exit code (defaults to 1).
152
+ def error(message, code = 1)
153
+ puts "custodian: #{message}"
154
+ exit code
155
+ end
156
+ end
157
+
158
+ end
@@ -0,0 +1,25 @@
1
+ module Custodian
2
+
3
+ # The OS module encapsulates Custodian's operating
4
+ # system detection algorithms.
5
+ module OS
6
+
7
+ # Determine whether the operating system is darwin.
8
+ #
9
+ # Returns a boolean describing whether the operating system
10
+ # is darwin.
11
+ def self.darwin?
12
+ RUBY_PLATFORM.downcase.include? "darwin"
13
+ end
14
+
15
+ # Determine whether the operating system is linux.
16
+ #
17
+ # Returns a boolean describing whether the operating system
18
+ # is linux.
19
+ def self.linux?
20
+ RUBY_PLATFORM.downcase.include? "linux"
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,100 @@
1
+ require "pathname"
2
+
3
+ module Custodian
4
+
5
+ # The Samplers module encapsulates a collection of samplers
6
+ # for various metrics.
7
+ module Samplers
8
+ autoload :Sampler, "custodian/samplers/sampler"
9
+ autoload :Utilities, "custodian/samplers/utilities"
10
+
11
+ @samplers = []
12
+
13
+ # List all samplers.
14
+ #
15
+ # Returns an Array of Sampler objects.
16
+ def self.list
17
+ @samplers
18
+ end
19
+
20
+ # List compatible samplers.
21
+ #
22
+ # Returns an Array of Sampler objects that are compatible
23
+ # with this system.
24
+ def self.compatible
25
+ @samplers.select { |s| s.compatible? }
26
+ end
27
+
28
+ # List incompatible samplers.
29
+ #
30
+ # Returns an Array of Sampler objects that are incompatible
31
+ # with this system.
32
+ def self.incompatible
33
+ @samplers.reject { |s| s.compatible? }
34
+ end
35
+
36
+ # Register the given sampler.
37
+ #
38
+ # sampler - An object that inherits from Sampler.
39
+ #
40
+ # Returns nothing.
41
+ def self.register(sampler)
42
+ @samplers << sampler
43
+ end
44
+
45
+ # Remove the given sampler.
46
+ #
47
+ # sampler - An object that inherits from Sampler.
48
+ def self.remove(sampler)
49
+ @samplers.delete(sampler)
50
+ end
51
+
52
+ # Replace one sampler with another.
53
+ #
54
+ # a - An object that inherits from Sampler.
55
+ # b - Another object that inherits from Sampler.
56
+ #
57
+ # Returns nothing.
58
+ def self.replace(a, b)
59
+ remove a
60
+ register b
61
+ end
62
+
63
+ # Clear all samplers.
64
+ def self.clear
65
+ @samplers = []
66
+ end
67
+
68
+ # Restore stock samplers.
69
+ def self.stock
70
+ load File.dirname(__FILE__) + "/samplers/darwin" if OS.darwin?
71
+ load File.dirname(__FILE__) + "/samplers/linux" if OS.linux?
72
+ end
73
+
74
+ # Load samplers from the given directory.
75
+ #
76
+ # directory - A String describing a path to a directory. If the path is relative,
77
+ # it will be expanded from the current working directory. If the path
78
+ # is prefixed with a tilde, it will be expanded from the current user's
79
+ # home directory. If the path is prefixed with a tilde immediately followed
80
+ # by a username, it will be expanded from that user's home directory.
81
+ #
82
+ # Returns nothing.
83
+ def self.load(directory)
84
+ path = Pathname.new directory
85
+
86
+ # Allow referencing directories by relative and home path.
87
+ path = path.expand_path unless path.absolute?
88
+
89
+ unless path.directory?
90
+ raise StandardError, "#{directory} is not a directory"
91
+ end
92
+
93
+ path.each_child do |child|
94
+ require child if child.file?
95
+ end
96
+ end
97
+
98
+ stock
99
+ end
100
+ end
@@ -0,0 +1,19 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ class CPU < Custodian::Samplers::Sampler
5
+ describe "CPU usage"
6
+
7
+ def self.sample
8
+ cpu = `top -l 1`.match /CPU usage: ([0-9]+\.[0-9]+%) user, ([0-9]+\.[0-9]+%) sys, ([0-9]+\.[0-9]+%) idle/
9
+
10
+ {
11
+ "User" => cpu[1],
12
+ "System" => cpu[2],
13
+ "Idle" => cpu[3]
14
+ }
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ class Load < Custodian::Samplers::Sampler
5
+ describe "Load averages"
6
+
7
+ def self.sample
8
+ uptime = `uptime`[/load averages: (.*)/, 1].split
9
+
10
+ {
11
+ "Last 5 minutes" => uptime[0],
12
+ "Last 10 minutes" => uptime[1],
13
+ "Last 15 minutes" => uptime[2]
14
+ }
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ class RAM < Custodian::Samplers::Sampler
5
+ describe "RAM usage"
6
+
7
+ def self.sample
8
+ vmstat = `vm_stat`
9
+
10
+ pages_free = vmstat[/Pages free: +([0-9]+)/, 1].to_i + vmstat[/Pages speculative: +([0-9]+)/, 1].to_i
11
+ pages_inactive = vmstat[/Pages inactive: +([0-9]+)/, 1].to_i
12
+ pages_active = vmstat[/Pages active: +([0-9]+)/, 1].to_i
13
+ pages_wired = vmstat[/Pages wired down: +([0-9]+)/, 1].to_i
14
+ page_ins = vmstat[/Pageins: +([0-9]+)/, 1].to_i
15
+ page_outs = vmstat[/Pageouts: +([0-9]+)/, 1].to_i
16
+
17
+ {
18
+ "Free" => "#{pages_free * 4096 / 1024 / 1024} MB",
19
+ "Inactive" => "#{pages_inactive * 4096 / 1024 / 1024} MB",
20
+ "Active" => "#{pages_active * 4096 / 1024 / 1024} MB",
21
+ "Wired" => "#{pages_wired * 4096 / 1024 / 1024} MB",
22
+ "Page ins" => "#{page_ins * 4096 / 1024 / 1024} MB",
23
+ "Page outs" => "#{page_outs * 4096 / 1024 / 1024} MB"
24
+ }
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ class Who < Custodian::Samplers::Sampler
5
+ describe "Logged in users"
6
+
7
+ def self.sample
8
+ `who`.lines.collect { |line| line.split.first }.uniq
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ class CPU < Custodian::Samplers::Sampler
5
+ describe "CPU usage"
6
+
7
+ def self.sample
8
+ top = `top -b -n1`.match /Cpu\(s\): +([0-9.]+)%us, +([0-9.]+)%sy, +([0-9.%]+)ni, +([0-9.]+)%id, +([0-9.]+)%wa, +([0-9.]+)%hi, +([0-9.]+)%si, +([0-9.]+)%st/
9
+
10
+ us = top[1].to_f # User CPU time: The time the CPU has spent running users' processes that are not niced.
11
+ sy = top[2].to_f # System CPU time: The time the CPU has spent running the kernel and its processes.
12
+ ni = top[3].to_f # Nice CPU time: The time the CPU has spent running users' proccess that have been niced.
13
+ id = top[4].to_f # Hardware IRQ: The amount of time the CPU has been servicing hardware interrupts.
14
+ wa = top[5].to_f # iowait: Amount of time the CPU has been waiting for I/O to complete.
15
+ hi = top[6].to_f # Hardware IRQ: The amount of time the CPU has been servicing hardware interrupts.
16
+ si = top[7].to_f # Hardware Interrupts: The amount of time the CPU has been servicing software interrupts.
17
+ st = top[8].to_f # Steal Time: The amount of CPU 'stolen' from this virtual machine by the hypervisor for other tasks.
18
+
19
+ {
20
+ "User" => "#{us + ni}%",
21
+ "System" => "#{sy + wa + hi + si + st}%",
22
+ "Idle" => "#{id}%"
23
+ }
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+
@@ -0,0 +1,19 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ class Load < Custodian::Samplers::Sampler
5
+ describe "Load averages"
6
+
7
+ def self.sample
8
+ uptime = `uptime`.match /load average: ([0-9.]+), ([0-9.]+), ([0-9.]+)/
9
+
10
+ {
11
+ "Last 5 minutes" => uptime[1],
12
+ "Last 10 minutes" => uptime[2],
13
+ "Last 15 minutes" => uptime[3]
14
+ }
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ class RAM < Custodian::Samplers::Sampler
5
+ describe "RAM usage"
6
+
7
+ def self.sample
8
+ free = `free -m`.match /Mem: +([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+)/
9
+
10
+ {
11
+ "Total" => "#{free[1]} MB",
12
+ "Used" => "#{free[2]} MB",
13
+ "Free" => "#{free[3]} MB",
14
+ "Buffers" => "#{free[4]} MB",
15
+ "Cached" => "#{free[5]} MB"
16
+ }
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,58 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ # Base class for samplers.
5
+ class Sampler
6
+ include Custodian::Samplers::Utilities
7
+
8
+ class << self
9
+
10
+ # Describe the sampler.
11
+ #
12
+ # description - A String describing the sampler.
13
+ #
14
+ # Returns nothing.
15
+ def describe(description)
16
+ @description = description
17
+ end
18
+
19
+ # Returns the sampler's description.
20
+ def description
21
+ @description
22
+ end
23
+
24
+ # Make a sample from this sampler.
25
+ #
26
+ # Examples
27
+ #
28
+ # CPU.sample # => { "User" => "10%", "System" => "5%", "Idle" => "85%" }
29
+ #
30
+ # Returns an Integer, Symbol, String, Hash or Array (or any combination thereof)
31
+ # describing the outcome of the sample.
32
+ def sample
33
+ nil
34
+ end
35
+
36
+ # Determine whether the sampler is compatible with this system.
37
+ #
38
+ # Returns true if it is compatible, or false if it isn't.
39
+ def compatible?
40
+ true
41
+ end
42
+
43
+ end
44
+
45
+ private
46
+
47
+ # Register samplers for classes that inherit from this class.
48
+ #
49
+ # sampler - The Class that inherited this class.
50
+ #
51
+ # Returns nothing.
52
+ def self.inherited(sampler)
53
+ Custodian::Samplers.register(sampler)
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,37 @@
1
+ module Custodian
2
+ module Samplers
3
+
4
+ # Utility methods for samplers.
5
+ module Utilities
6
+
7
+ # Determine whether the given program exists.
8
+ #
9
+ # program - A String describing the name of a program.
10
+ #
11
+ # Returns true if the program exists, or false if it doesn't.
12
+ def self.program_exists?(program)
13
+ system "which #{command} > /dev/null 2>&1"
14
+ end
15
+
16
+ # Determine whether the given directory exists.
17
+ #
18
+ # directory - A String describing the path to a directory.
19
+ #
20
+ # Returns true if the directory exists, or false if it doesn't.
21
+ def self.directory_exists?(directory)
22
+ Pathname.new(directory).directory?
23
+ end
24
+
25
+ # Determine whether the given file exists.
26
+ #
27
+ # file - A String describing the path to a file.
28
+ #
29
+ # Returns true if the file exists, or false if it doesn't.
30
+ def self.file_exists?(file)
31
+ Pathname.new(file).file?
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -1,3 +1,3 @@
1
1
  module Custodian
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/test/cli_test.rb ADDED
@@ -0,0 +1,24 @@
1
+ require "custodian"
2
+ require "minitest/spec"
3
+ require "minitest/autorun"
4
+ require "rack/test"
5
+
6
+ describe Custodian::API do
7
+ include Rack::Test::Methods
8
+
9
+ def app
10
+ Custodian::API.new
11
+ end
12
+
13
+ it "responds with HTTP 200 OK" do
14
+ get "/"
15
+
16
+ last_response.ok?.must_equal true
17
+ end
18
+
19
+ it "responds with valid JSON" do
20
+ get "/"
21
+
22
+ JSON.parse(last_response.body).must_be_instance_of Array
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ require "custodian"
2
+ require "minitest/spec"
3
+ require "minitest/autorun"
4
+
5
+ describe Custodian::Samplers::Sampler do
6
+
7
+ before do
8
+ @sampler = Custodian::Samplers::Sampler
9
+ end
10
+
11
+ it "can sample" do
12
+ @sampler.sample
13
+ end
14
+
15
+ it "can be described" do
16
+ @sampler.description.must_equal nil
17
+ end
18
+
19
+ it "can determine whether its compatible" do
20
+ @sampler.compatible?.must_equal true
21
+ end
22
+
23
+ end
@@ -0,0 +1,47 @@
1
+ require "custodian"
2
+ require "minitest/spec"
3
+ require "minitest/autorun"
4
+
5
+ describe Custodian::Samplers do
6
+
7
+ before do
8
+ Custodian::Samplers.clear
9
+ end
10
+
11
+ after do
12
+ Custodian::Samplers.stock
13
+ end
14
+
15
+ it "can list samplers" do
16
+ Custodian::Samplers.list.must_be_instance_of Array
17
+ end
18
+
19
+ it "can list compatible samplers" do
20
+ Custodian::Samplers.compatible.must_be_instance_of Array
21
+ end
22
+
23
+ it "can list incompatible samplers" do
24
+ Custodian::Samplers.incompatible.must_be_instance_of Array
25
+ end
26
+
27
+ it "can register new samplers" do
28
+ Custodian::Samplers::register Custodian::Samplers::CPU
29
+
30
+ Custodian::Samplers.list.must_include Custodian::Samplers::CPU
31
+ end
32
+
33
+ it "can remove samplers" do
34
+ Custodian::Samplers::remove Custodian::Samplers::CPU
35
+
36
+ Custodian::Samplers.list.wont_include Custodian::Samplers::CPU
37
+ end
38
+
39
+ it "can replace samplers" do
40
+ Custodian::Samplers.register Custodian::Samplers::CPU
41
+ Custodian::Samplers.replace Custodian::Samplers::CPU, Custodian::Samplers::RAM
42
+
43
+ Custodian::Samplers.list.must_include Custodian::Samplers::RAM
44
+ Custodian::Samplers.list.wont_include Custodian::Samplers::CPU
45
+ end
46
+
47
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: custodian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,86 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-24 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2012-02-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70234530717300 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70234530717300
25
+ - !ruby/object:Gem::Dependency
26
+ name: thin
27
+ requirement: &70234530713980 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70234530713980
36
+ - !ruby/object:Gem::Dependency
37
+ name: rack
38
+ requirement: &70234530708540 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70234530708540
47
+ - !ruby/object:Gem::Dependency
48
+ name: active_support
49
+ requirement: &70234536390620 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70234536390620
14
58
  description: Custodian is a lightweight resource monitor that is easy to use and augment
15
59
  email:
16
60
  - jgorset@gmail.com
17
- executables: []
61
+ executables:
62
+ - custodian
18
63
  extensions: []
19
64
  extra_rdoc_files: []
20
65
  files:
21
66
  - .gitignore
22
67
  - Gemfile
68
+ - LICENSE
23
69
  - README.md
24
70
  - Rakefile
71
+ - bin/custodian
25
72
  - custodian.gemspec
73
+ - docs/images/example.png
26
74
  - lib/custodian.rb
75
+ - lib/custodian/api.rb
76
+ - lib/custodian/cli.rb
77
+ - lib/custodian/os.rb
78
+ - lib/custodian/samplers.rb
79
+ - lib/custodian/samplers/darwin/cpu.rb
80
+ - lib/custodian/samplers/darwin/load.rb
81
+ - lib/custodian/samplers/darwin/ram.rb
82
+ - lib/custodian/samplers/darwin/who.rb
83
+ - lib/custodian/samplers/linux/cpu.rb
84
+ - lib/custodian/samplers/linux/load.rb
85
+ - lib/custodian/samplers/linux/ram.rb
86
+ - lib/custodian/samplers/sampler.rb
87
+ - lib/custodian/samplers/utilities.rb
27
88
  - lib/custodian/version.rb
89
+ - test/cli_test.rb
90
+ - test/sampler_test.rb
91
+ - test/samplers_test.rb
28
92
  homepage: http://github.com/jgorset/custodian
29
93
  licenses: []
30
94
  post_install_message:
@@ -49,4 +113,7 @@ rubygems_version: 1.8.11
49
113
  signing_key:
50
114
  specification_version: 3
51
115
  summary: Lightweight resource monitor
52
- test_files: []
116
+ test_files:
117
+ - test/cli_test.rb
118
+ - test/sampler_test.rb
119
+ - test/samplers_test.rb