cognizant 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,4 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- .DS_Store
18
+ .DS_Store
19
+ .rbenv*
data/README.md CHANGED
@@ -1,31 +1,32 @@
1
- # Cognizant
1
+ # Cognizant: system utility to supervise your processes
2
2
 
3
- Cognizant is a system utility that supervises your processes, ensuring their
4
- state based on a flexible criteria.
3
+ Let us say that you have a program that is critical for your application. Any
4
+ downtime for the processes of this program would hurt your business. You want
5
+ to make sure these processes are always up and working. If anything unexpected
6
+ happens to their state, you want to be notified about it.
5
7
 
6
- In simpler terms, cognizant keeps your processes up and running. It ensures
8
+ Enter Cognizant. Cognizant is a system utility that supervises your processes,
9
+ monitoring and ensuring their state based on a flexible criteria.
10
+
11
+ In simpler terms, it keeps your processes up and running. It ensures
7
12
  that something productive (like restart) is done when the process being
8
13
  monitored matches a certain condition (like RAM, CPU usage or a custom
9
14
  condition).
10
15
 
11
- PS: Although the core works efficiently, yet the command interface to the
12
- utility, documentation and some other features need a lot of work.
13
- Contributions will be overwhelmingly welcomed!
14
-
15
- PS2: This README is written as a roadmap for the features cognizant would
16
- ideally provide. Some of them might not yet be implemented (e.g. conditions).
16
+ And if it matters, cognizant means "having knowledge or being aware of",
17
+ according to Apple's Dictionary.
17
18
 
18
19
  Cognizant can be used to monitor any long running process, including the
19
- following examples:
20
+ following:
20
21
 
21
22
  - Web servers (Nginx, Apache httpd, WebSocket, etc.)
22
23
  - Databases (Redis, MongoDB, MySQL, PostgreSQL, etc.)
23
- - Job workers (Resque, Sidekiq, etc.)
24
+ - Job workers (Resque, Sidekiq, Qless, etc.)
24
25
  - Message queue applications (RabbitMQ, Beanstalkd, etc.)
25
- - Logs collection daemon
26
+ - Logs collection daemons
26
27
  - Or any other program that needs to keep running
27
28
 
28
- ## Monitoring
29
+ ### Monitoring
29
30
 
30
31
  Cognizant can be used to monitor an application process' state so that it
31
32
  is running at all times. When cognizant is instructed to monitor a process,
@@ -33,13 +34,23 @@ by default, the process will automatically be started. These processes are
33
34
  automatically monitored for their state. i.e. a process is automatically
34
35
  started again if it stops unexpectedly.
35
36
 
36
- ## Conditions
37
+ ### Conditions
37
38
 
38
39
  Conditions provide a way to monitor and act on more than just the state of a
39
40
  process. For example, conditions can monitor the resource utilization (RAM,
40
41
  CPU, etc.) of the application process and restart it if it matches a
41
42
  condition.
42
43
 
44
+ See examples for conditions usage.
45
+
46
+ ### Notifications
47
+
48
+ PS: Notifications currently need work.
49
+
50
+ Notifications provide a way to alert system administrator of unexpected events
51
+ happening with the process. Notifications can use multiple gateways, including
52
+ email and twitter [direct message].
53
+
43
54
  ## Getting started
44
55
 
45
56
  Cognizant is written in the Ruby programming language, and hence depends on
@@ -73,17 +84,44 @@ The daemon, with it's default options, requires superuser access to certain syst
73
84
 
74
85
  To start without superuser access, specify these file and directory config variables to where the user starting it has write access:
75
86
 
76
- $ cognizantd ~/.cognizant/cognizantd.yml
87
+ $ cognizantd ./examples/cognizantd.yml
77
88
 
78
89
  # assuming that:
79
90
 
80
- $ cat ~/.cognizant/cognizantd.yml
91
+ $ cat ~/.examples/cognizantd.yml # find this file in source code for latest version
81
92
  ---
82
93
  socket: ~/.cognizant/cognizantd.sock
83
94
  pidfile: ~/.cognizant/cognizantd.pid
84
95
  logfile: ~/.cognizant/cognizantd.log
85
96
  pids_dir: ~/.cognizant/pids/
86
97
  logs_dir: ~/.cognizant/logs/
98
+
99
+ monitor: {
100
+ redis-server-1: {
101
+ group: redis,
102
+ start_command: /usr/local/bin/redis-server -,
103
+ start_with_input: "daemonize no\nport 6666",
104
+ ping_command: redis-cli -p 6666 PING,
105
+ stop_signals: [TERM, INT]
106
+ },
107
+ redis-server-2: {
108
+ group: redis,
109
+ start_command: /usr/local/bin/redis-server -,
110
+ start_with_input: "daemonize no\nport 7777",
111
+ ping_command: redis-cli -p 7777 PING,
112
+ stop_command: redis-cli -p 7777 SHUTDOWN
113
+ },
114
+ sleep: {
115
+ start_command: sleep 3,
116
+ checks: {
117
+ flapping: {
118
+ times: 4,
119
+ within: 15, # Seconds.
120
+ retry_after: 30 # Seconds.
121
+ }
122
+ }
123
+ }
124
+ }
87
125
 
88
126
  or
89
127
 
@@ -91,56 +129,76 @@ or
91
129
  $ echo <<EOF | cognizantd -
92
130
  ---
93
131
  socket: ~/.cognizant/cognizantd.sock
94
- pidfile: ~/.cognizant/cognizantd.pid
95
- logfile: ~/.cognizant/cognizantd.log
96
- pids_dir: ~/.cognizant/pids/
97
- logs_dir: ~/.cognizant/logs/
132
+ ...
133
+ monitor: {
134
+ ...
135
+ ...
136
+ }
98
137
  EOF
99
138
 
139
+ Process information can also be provided via Ruby code. See `load` command below.
140
+
100
141
  ## Using the administration utility
101
142
 
102
143
  Cognizant can be administered using the `cognizant` command line utility. This is an application for performing administration tasks like monitoring, starting, stopping processes or loading configuration and processes' information.
103
144
 
104
- Here's how you tell cognizant to start monitoring a new process:
145
+ Here are some basic operational commands:
105
146
 
106
- $ cognizant monitor --name resque-worker-1 \
107
- --group resque \
108
- --chdir /apps/example/current/ \
109
- --start_command "bundle exec rake resque:work"
147
+ $ cognizant monitor redis # by group name
148
+ $ cognizant restart redis-server-1 # by process name
110
149
 
111
- Now check it's status:
150
+ To get cognizant to ignore a particular process' state:
112
151
 
113
- $ cognizant status resque-worker-1
114
- ---
115
- resque-worker-1: {
116
- state: running,
117
- uptime: 3600 # 1 hour
118
- }
152
+ $ cognizant unmonitor sleep-10
119
153
 
120
- Or check status of all processes:
154
+ Now check status of all managed processes:
121
155
 
122
- $ cognizant status resque-worker-1
123
- ---
124
- redis-server: {
125
- state: running,
126
- uptime: 5400 # 1 hour 30 minutes
127
- },
128
- resque-worker-1: {
129
- group: resque,
130
- state: running,
131
- uptime: 3600 # 1 hour
132
- },
133
- resque-worker-2: {
134
- group: resque,
135
- state: stoppped,
136
- uptime: 0
137
- }
156
+ $ cognizant status
157
+ +----------------+-------+--------------------------------------+
158
+ | Process | Group | State |
159
+ +----------------+-------+--------------------------------------+
160
+ | redis-server-1 | redis | running since 1 minute |
161
+ +----------------+-------+--------------------------------------+
162
+ | redis-server-2 | redis | running since 2 minutes |
163
+ +----------------+-------+--------------------------------------+
164
+ | sleep-10 | | unmonitored since less than a minute |
165
+ +----------------+-------+--------------------------------------+
166
+ 2012-11-23 01:16:18 +0530
167
+
168
+ Here's how you tell cognizant to start monitoring new processes:
169
+
170
+ $ cognizant load ./examples/redis-server.rb # find this file in source code
171
+
172
+ All of the available commands are:
173
+
174
+ - `help` - Shows a list of commands or help for one command
175
+ - `status [name]` - Display status of managed process(es) or group(s)
176
+ - `load ./cog.rb` - Loads the process information from specified Ruby file
177
+ - `monitor name` - Monitor the specified process or group
178
+ - `unmonitor name` - Unmonitor the specified process or group
179
+ - `start name` - Start the specified process or group
180
+ - `stop name` - Stop the specified process or group
181
+ - `restart name` - Restart the specified process or group
182
+ - `shutdown` - Stop the monitoring daemon without affecting processes
183
+
184
+ See `cognizant help` for options.
185
+
186
+ ## Contributing
187
+
188
+ Contributions are definitely welcome. To contribute, just follow the usual
189
+ workflow:
190
+
191
+ 1. Fork Cognizant
192
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
193
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
194
+ 4. Push to the branch (`git push origin my-new-feature`)
195
+ 5. Create new Github pull request
138
196
 
139
- ### Works anywhere
197
+ ## Compatibility
140
198
 
141
- Cognizant can be used on any operating system where Ruby 1.9+ works.
199
+ Cognizant was developed and tested under Ruby 1.9.2-p290.
142
200
 
143
- ### What are the other programs similar to cognizant?
201
+ ## Similar programs
144
202
 
145
203
  - Monit
146
204
  - God (Ruby)
@@ -151,10 +209,13 @@ Cognizant can be used on any operating system where Ruby 1.9+ works.
151
209
  - Systemd
152
210
  - Launchd
153
211
 
154
- ### Which one of these should I be using?
212
+ ### Links
155
213
 
156
- The one that gets your job done efficiently.
214
+ - Documentation: http://rubydoc.info/github/Gurpartap/cognizant/frames
215
+ - Source: https://github.com/Gurpartap/cognizant
216
+ - Rubygems: https://rubygems.org/gems/cognizant
157
217
 
158
- ### What does the term "cognizant" mean?
218
+ ## About
159
219
 
160
- If it matters, cognizant means "having knowledge or being aware of", according to Apple's Dictionary.
220
+ Cognizant is a project of [Gurpartap Singh](http://gurpartap.com/). Feel free
221
+ to get in touch.
data/bin/cognizant CHANGED
@@ -1,58 +1,178 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require "cognizant/version"
4
+ require "gli"
5
+ require "formatador"
6
+ require "socket"
7
+ require "json"
8
+
9
+ include GLI::App
10
+
3
11
  # Set the process name.
4
12
  $0 = File.basename(__FILE__)
5
13
 
6
- # Flush standard output/error immediately.
14
+ # Set to flush standard output/error immediately.
7
15
  $stdout.sync = true
8
16
  $stderr.sync = true
9
17
 
10
- begin
11
- require 'optparse'
18
+ program_desc "administration utility for cognizantd"
19
+ @version = Cognizant::VERSION
12
20
 
13
- options = {
14
- socket: "/var/run/cognizant/cognizantd.sock"
15
- }
21
+ sort_help :manually
16
22
 
17
- OptionParser.new do |opts|
18
- opts.banner = <<-EOF
19
- Usage:
20
- cognizant [OPTIONS] command
23
+ desc "The socket lock file of the daemon server"
24
+ arg_name "FILE"
25
+ flag :socket, :type => String, :default_value => "/var/run/cognizant/cognizantd.sock"
21
26
 
22
- Options:
23
- EOF
27
+ desc "The server address of the daemon server"
28
+ arg_name "ADDRESS"
29
+ flag "bind-address", :type => String
24
30
 
25
- opts.on("-s FILE", "--socket FILE", String, "The socket lock file for the server") do |value|
26
- options[:socket] = value
27
- end
31
+ desc "The server port of the daemon server"
32
+ arg_name "PORT"
33
+ flag :port, :type => Integer
28
34
 
29
- opts.on("-b ADDRESS", "--bind-address ADDRESS", String, "The interface to bind the TCP server to.") do |value|
30
- options[:bind_address] = value
31
- end
35
+ desc "Username to use for authentication with server"
36
+ arg_name "USERNAME"
37
+ flag :username, :type => String
32
38
 
33
- opts.on("-p PORT", "--port PORT", Integer, "The TCP port to start the server with.") do |value|
34
- options[:port] = value
35
- end
39
+ desc "Password to use for authentication with server"
40
+ arg_name "PASSWORD"
41
+ flag :password, :type => String
36
42
 
37
- opts.on("--username USERNAME", String, "Username for securing server access.") do |value|
38
- options[:username] = value
39
- end
43
+ desc "Print the version number and exit"
44
+ switch :version, :negatable => false
40
45
 
41
- opts.on("--password PASSWORD", String, "Password to accompany the username.") do |value|
42
- options[:password] = value
43
- end
46
+ desc "Turn on tracing, enabling full backtrace"
47
+ switch :trace, :negatable => false
48
+
49
+ desc "Display status of managed process(es) or group(s)"
50
+ arg_name "process_name", :optional
51
+ command :status do |c|
52
+ c.action do |global_options, options, args|
53
+ connect_and_perform(global_options, :status, args) do |output|
54
+ begin
55
+ JSON.parse(output)
44
56
 
45
- opts.on("-t", "--trace", "Turn on tracing, enable full backtrace.") do
46
- options[:trace] = true
57
+ status_data = JSON.parse(output)
58
+ status_data.each_with_index do |process, index|
59
+ status_data[index]["State"] = "[green]#{process["State"]}[/] since #{distance_of_time_in_words(Time.now.to_i - process["Since"])}"
60
+ status_data[index]["Memory"] = number_to_human_size(process["Memory"] * 1024) # Convert kilobytes to bytes.
61
+ end
62
+
63
+ formatador = Formatador.new
64
+ formatador.display_line
65
+ formatador.display_table(status_data, ["Process", "Group", "State", "PID", "% CPU", "Memory"])
66
+ formatador.display_line(Time.now)
67
+ formatador.display_line
68
+ rescue => e
69
+ Formatador.display_line("[red]#{output}[/]")
70
+ end
47
71
  end
72
+ end
73
+ end
74
+
75
+ desc "Loads the process information from specified Ruby file"
76
+ arg_name "file"
77
+ command :load do |c|
78
+ c.action do |global_options, options, args|
79
+ connect_and_perform(global_options, :load, args)
80
+ end
81
+ end
82
+
83
+ desc "Monitor the specified process or group"
84
+ arg_name "process_name"
85
+ command :monitor do |c|
86
+ c.action do |global_options, options, args|
87
+ connect_and_perform(global_options, :monitor, args)
88
+ end
89
+ end
90
+
91
+ desc "Unmonitor the specified process or group"
92
+ arg_name "process_name"
93
+ command :unmonitor do |c|
94
+ c.action do |global_options, options, args|
95
+ connect_and_perform(global_options, :unmonitor, args)
96
+ end
97
+ end
48
98
 
49
- opts.on("-v", "--version", "Print the version number and exit.") do
50
- require 'cognizant/version'
51
- $stdout.puts Cognizant::VERSION
52
- exit(0)
99
+ desc "Start the specified process or group"
100
+ arg_name "process_name"
101
+ command :start do |c|
102
+ c.action do |global_options, options, args|
103
+ connect_and_perform(global_options, :start, args)
104
+ end
105
+ end
106
+
107
+ desc "Stop the specified process or group"
108
+ arg_name "process_name"
109
+ command :stop do |c|
110
+ c.action do |global_options, options, args|
111
+ connect_and_perform(global_options, :stop, args)
112
+ end
113
+ end
114
+
115
+ desc "Restart the specified process or group"
116
+ arg_name "process_name"
117
+ command :restart do |c|
118
+ c.action do |global_options, options, args|
119
+ connect_and_perform(global_options, :restart, args)
120
+ end
121
+ end
122
+
123
+ desc "Stop the monitoring daemon without affecting processes"
124
+ command :shutdown do |c|
125
+ c.action do |global_options, options, args|
126
+ connect_and_perform(global_options, :shutdown, args)
127
+ end
128
+ end
129
+
130
+ def connect_and_perform(global_options, task, args, &block)
131
+ output_handler = Proc.new do |socket|
132
+ socket.write("#{task.to_s} #{args.join(' ')}")
133
+ socket.flush
134
+ output = socket.gets
135
+ if block
136
+ block.call(output)
137
+ else
138
+ Formatador.display_line(output)
53
139
  end
54
- end.parse!
140
+ end
55
141
 
56
- require 'cognizant'
57
- Cognizant.add_process(options)
142
+ if global_options[:socket]
143
+ output_handler.call(UNIXSocket.new(global_options[:socket]))
144
+ else
145
+ output_handler.call(TCPSocket.new(global_options["bind-address"], global_options["port"]))
146
+ end
58
147
  end
148
+
149
+ def distance_of_time_in_words(seconds)
150
+ minutes = seconds / 60
151
+ return nil if minutes < 0
152
+ case minutes
153
+ when 0 then "less than a minute"
154
+ when 1..59 then pluralize((minutes/1).floor, "minute", "minutes")
155
+ when 60..1439 then pluralize((minutes/60).floor, "hour", "hours")
156
+ when 1440..11519 then pluralize((minutes/1440).floor, "day", "days")
157
+ when 11520..43199 then pluralize((minutes/11520).floor, "week", "weeks")
158
+ when 43200..525599 then pluralize((minutes/43200).floor, "month", "months")
159
+ else pluralize((minutes/525600).floor, "year", "years")
160
+ end
161
+ end
162
+
163
+ SIZE_PREFIX = %w(TiB GiB MiB KiB Bytes).freeze
164
+ def number_to_human_size(size)
165
+ size = size.to_f
166
+ i = SIZE_PREFIX.length - 1
167
+ while size > 512 && i > 0
168
+ i -= 1
169
+ size /= 1024
170
+ end
171
+ ((size > 9 || size.modulo(1) < 0.1 ? "%d" : "%.1f") % size) + " " + SIZE_PREFIX[i]
172
+ end
173
+
174
+ def pluralize(count, singular, plural)
175
+ "#{count || 0} " + ((count == 1 || count =~ /^1(\.0+)?$/) ? singular : plural)
176
+ end
177
+
178
+ exit run(ARGV)
data/bin/cognizantd CHANGED
@@ -8,27 +8,34 @@ $stdout.sync = true
8
8
  $stderr.sync = true
9
9
 
10
10
  begin
11
- require 'optparse'
11
+ require "optparse"
12
+ require "cognizant/version"
12
13
 
13
14
  options = {}
14
15
 
15
16
  OptionParser.new do |opts|
16
17
  opts.banner = <<-EOF
17
- Usage:
18
- cognizantd [OPTIONS] [CONFIG | -]
18
+ NAME
19
+ cognizantd - system utility daemon to supervise your processes
19
20
 
20
- Options:
21
+ SYNOPSIS:
22
+ cognizantd [global options] [config file | -]
23
+
24
+ VERSION
25
+ #{Cognizant::VERSION}
26
+
27
+ GLOBAL OPTIONS:
21
28
  EOF
22
29
 
23
- opts.on("--[no-]daemonize", "Whether or not to daemonize cognizant into background.") do |value|
30
+ opts.on("--[no-]daemonize", "Whether or not to daemonize cognizantd into background.") do |value|
24
31
  options[:daemonize] = value
25
32
  end
26
33
 
27
- opts.on("--pidfile FILE", String, "The pid lock file for the daemon.") do |value|
34
+ opts.on("--pidfile FILE", String, "The pid (process identifier) lock file for the daemon.") do |value|
28
35
  options[:pidfile] = value
29
36
  end
30
37
 
31
- opts.on("--logfile FILE", String, "The file to log the daemon's operations information into.") do |value|
38
+ opts.on("--logfile FILE", String, "The file to log the daemon's operational information into.") do |value|
32
39
  options[:logfile] = value
33
40
  end
34
41
 
@@ -89,23 +96,26 @@ begin
89
96
  end
90
97
 
91
98
  opts.on("-v", "--version", "Print the version number and exit.") do
92
- require 'cognizant/version'
99
+ require "cognizant/version"
93
100
  $stdout.puts Cognizant::VERSION
94
101
  exit(0)
95
102
  end
96
103
  end.parse!
97
104
 
98
105
  if config_file = ARGV.shift
106
+ require "cognizant/util/symbolize_hash_keys"
107
+
99
108
  if config_file.eql?("-")
100
109
  config = YAML.load(ARGF.read)
101
110
  else
102
111
  config = YAML.load_file(config_file)
103
112
  end
104
113
  config = config.inject({}) { |c,(k,v)| c[k.gsub("-", "_").to_sym] = v; c }
114
+ config.deep_symbolize_keys!
105
115
  options = config.merge(options)
106
116
  end
107
117
 
108
- require 'cognizant/server'
118
+ require "cognizant/server"
109
119
  Cognizant::Server.start(options)
110
120
  rescue => exception
111
121
  if exception.instance_of?(SystemExit)
data/cognizant.gemspec CHANGED
@@ -4,9 +4,9 @@ require File.expand_path('../lib/cognizant/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Gurpartap Singh"]
6
6
  gem.email = ["contact@gurpartap.com"]
7
- gem.description = "Process monitoring and management framework"
8
- gem.summary = "Cognizant is an advanced and efficient process monitoring and management framework."
9
- gem.homepage = "http://gurpartap.github.com/cognizant/"
7
+ gem.description = "Cognizant is a process management system utility that supervises your processes, ensuring their state based on a flexible criteria."
8
+ gem.summary = "Cognizant is a process management system utility that supervises your processes, ensuring their state based on a flexible criteria."
9
+ gem.homepage = "http://github.com/Gurpartap/cognizant"
10
10
 
11
11
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
12
  gem.files = `git ls-files`.split("\n")
@@ -19,6 +19,12 @@ Gem::Specification.new do |gem|
19
19
  gem.add_development_dependency "redcarpet"
20
20
  gem.add_development_dependency "yard"
21
21
 
22
+ # cognizantd
22
23
  gem.add_dependency "eventmachine"
23
24
  gem.add_dependency "state_machine"
25
+ gem.add_dependency "activesupport"
26
+
27
+ # cognizant
28
+ gem.add_dependency "gli"
29
+ gem.add_dependency "formatador"
24
30
  end
@@ -7,17 +7,44 @@ pids_dir: ~/.cognizant/pids/
7
7
  logs_dir: ~/.cognizant/logs/
8
8
 
9
9
  monitor: {
10
- redis-server: {
10
+ redis-server-1: {
11
+ autostart: false,
12
+ group: redis,
11
13
  start_command: /usr/local/bin/redis-server -,
12
- start_with_input: daemonize no,
13
- ping_command: redis-cli PING,
14
- autostart: true,
15
- stop_timeout: 5,
16
- start_timeout: 2,
17
- restart_timeout: 2
14
+ start_with_input: "daemonize no\nport 6666",
15
+ ping_command: redis-cli -p 6666 PING,
16
+ stop_signals: [TERM, INT],
17
+ checks: {
18
+ cpu_usage: {
19
+ every: 3,
20
+ above: 60,
21
+ times: 3,
22
+ do: restart
23
+ },
24
+ memory_usage: {
25
+ every: 5, # Seconds.
26
+ above: 1220608, # Bytes.
27
+ times: [3, 5], # Three out of five times.
28
+ do: stop # Defaults to restart.
29
+ }
30
+ }
18
31
  },
19
- sleep-10: {
20
- start_command: sleep 10,
21
- autostart: true
32
+ redis-server-2: {
33
+ autostart: false,
34
+ group: redis,
35
+ start_command: /usr/local/bin/redis-server -,
36
+ start_with_input: "daemonize no\nport 7777",
37
+ ping_command: redis-cli -p 7777 PING,
38
+ stop_command: redis-cli -p 7777 SHUTDOWN
39
+ },
40
+ sleep: {
41
+ start_command: sleep 3,
42
+ checks: {
43
+ flapping: {
44
+ times: 4,
45
+ within: 15, # Seconds.
46
+ retry_after: 30 # Seconds.
47
+ }
48
+ }
22
49
  }
23
50
  }
@@ -1,11 +1,11 @@
1
- # 4 slave instances to master at port 6000.
2
- 5.times do |i|
3
- Cognizant.monitor "redis-server-600#{i}" do |process|
4
- process.group = "redis"
5
- process.uid = "redis"
6
- process.gid = "redis"
7
- process.start_command = "redis-server -"
8
- process.ping_command = "redis-cli -p 600#{i} PING"
1
+ # 2 slave instances to master at port 6000.
2
+ 3.times do |i|
3
+ Cognizant.monitor("redis-server-600#{i}") do |process|
4
+ process.group = "redis"
5
+ # process.uid = "redis"
6
+ # process.gid = "redis"
7
+ process.start_command = "redis-server -"
8
+ process.ping_command = "redis-cli -p 600#{i} PING"
9
9
 
10
10
  slaveof = i == 0 ? "" : "slaveof 127.0.0.1 6000"
11
11
  process.start_with_input = <<-heredoc
@@ -13,5 +13,16 @@
13
13
  port 600#{i}
14
14
  #{slaveof}
15
15
  heredoc
16
+
17
+ # process.on :always_true, :every => 2.seconds, :times => 3 do |p|
18
+ # `say "Boom!"`
19
+ # end
20
+
21
+ process.check(:flapping, :times => 2, :within => 30.seconds, :retry_after => 7.seconds)
22
+ process.check(:cpu_usage, :every => 3.seconds, :above => 60, :times => 3, :do => :restart)
23
+
24
+ process.check(:memory_usage, :every => 5.seconds, :above => 100.megabytes, :times => [3, 5]) do |p|
25
+ p.restart # Restart is the default anyways.
26
+ end
16
27
  end
17
28
  end