cognizant 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +4 -1
- data/{LICENSE → License.md} +4 -2
- data/Rakefile +5 -0
- data/Readme.md +95 -0
- data/bin/cognizant +76 -122
- data/bin/cognizantd +28 -61
- data/cognizant.gemspec +8 -4
- data/examples/apps/redis-server.cz +42 -0
- data/examples/apps/redis-server.yml +29 -0
- data/examples/apps/redis-server_dsl.cz +54 -0
- data/examples/apps/resque.cz +17 -0
- data/examples/apps/thin.cz +32 -0
- data/examples/apps/thin.yml +48 -0
- data/examples/cognizantd.yml +18 -47
- data/features/child_process.feature +62 -0
- data/features/commands.feature +65 -0
- data/features/cpu_usage.feature +45 -0
- data/features/daemon.feature +12 -0
- data/features/flapping.feature +39 -0
- data/features/memory_usage.feature +45 -0
- data/features/shell.feature +30 -0
- data/features/step_definitions/common_steps.rb +14 -0
- data/features/step_definitions/daemon_steps.rb +25 -0
- data/features/step_definitions/shell_steps.rb +96 -0
- data/features/support/env.rb +54 -0
- data/lib/cognizant.rb +1 -5
- data/lib/cognizant/application.rb +122 -0
- data/lib/cognizant/application/dsl_proxy.rb +23 -0
- data/lib/cognizant/client.rb +61 -0
- data/lib/cognizant/commands.rb +164 -0
- data/lib/cognizant/commands/actions.rb +30 -0
- data/lib/cognizant/commands/help.rb +10 -0
- data/lib/cognizant/commands/load.rb +10 -0
- data/lib/cognizant/commands/shutdown.rb +7 -0
- data/lib/cognizant/commands/status.rb +11 -0
- data/lib/cognizant/commands/use.rb +15 -0
- data/lib/cognizant/controller.rb +17 -0
- data/lib/cognizant/daemon.rb +279 -0
- data/lib/cognizant/interface.rb +17 -0
- data/lib/cognizant/log.rb +25 -0
- data/lib/cognizant/process.rb +138 -94
- data/lib/cognizant/process/actions.rb +30 -41
- data/lib/cognizant/process/actions/restart.rb +73 -17
- data/lib/cognizant/process/actions/start.rb +35 -12
- data/lib/cognizant/process/actions/stop.rb +38 -17
- data/lib/cognizant/process/attributes.rb +41 -10
- data/lib/cognizant/process/children.rb +36 -0
- data/lib/cognizant/process/{condition_check.rb → condition_delegate.rb} +11 -13
- data/lib/cognizant/process/conditions.rb +7 -4
- data/lib/cognizant/process/conditions/cpu_usage.rb +5 -6
- data/lib/cognizant/process/conditions/memory_usage.rb +2 -6
- data/lib/cognizant/process/dsl_proxy.rb +23 -0
- data/lib/cognizant/process/execution.rb +16 -9
- data/lib/cognizant/process/pid.rb +16 -6
- data/lib/cognizant/process/status.rb +14 -2
- data/lib/cognizant/process/trigger_delegate.rb +57 -0
- data/lib/cognizant/process/triggers.rb +19 -0
- data/lib/cognizant/process/triggers/flapping.rb +68 -0
- data/lib/cognizant/process/triggers/transition.rb +22 -0
- data/lib/cognizant/process/triggers/trigger.rb +15 -0
- data/lib/cognizant/shell.rb +142 -0
- data/lib/cognizant/system.rb +16 -0
- data/lib/cognizant/system/ps.rb +1 -1
- data/lib/cognizant/system/signal.rb +2 -2
- data/lib/cognizant/util/dsl_proxy_methods_handler.rb +25 -0
- data/lib/cognizant/util/fixnum_percent.rb +5 -0
- data/lib/cognizant/util/transform_hash_keys.rb +33 -0
- data/lib/cognizant/validations.rb +142 -142
- data/lib/cognizant/version.rb +1 -1
- metadata +131 -71
- data/README.md +0 -221
- data/examples/redis-server.rb +0 -28
- data/examples/resque.rb +0 -10
- data/images/logo-small.png +0 -0
- data/images/logo.png +0 -0
- data/images/logo.pxm +0 -0
- data/lib/cognizant/logging.rb +0 -33
- data/lib/cognizant/process/conditions/flapping.rb +0 -57
- data/lib/cognizant/process/conditions/trigger_condition.rb +0 -52
- data/lib/cognizant/server.rb +0 -14
- data/lib/cognizant/server/commands.rb +0 -80
- data/lib/cognizant/server/daemon.rb +0 -277
- data/lib/cognizant/server/interface.rb +0 -86
- data/lib/cognizant/util/symbolize_hash_keys.rb +0 -19
data/README.md
DELETED
@@ -1,221 +0,0 @@
|
|
1
|
-
# Cognizant: system utility to supervise your processes
|
2
|
-
|
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.
|
7
|
-
|
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
|
12
|
-
that something productive (like restart) is done when the process being
|
13
|
-
monitored matches a certain condition (like RAM, CPU usage or a custom
|
14
|
-
condition).
|
15
|
-
|
16
|
-
And if it matters, cognizant means "having knowledge or being aware of",
|
17
|
-
according to Apple's Dictionary.
|
18
|
-
|
19
|
-
Cognizant can be used to monitor any long running process, including the
|
20
|
-
following:
|
21
|
-
|
22
|
-
- Web servers (Nginx, Apache httpd, WebSocket, etc.)
|
23
|
-
- Databases (Redis, MongoDB, MySQL, PostgreSQL, etc.)
|
24
|
-
- Job workers (Resque, Sidekiq, Qless, etc.)
|
25
|
-
- Message queue applications (RabbitMQ, Beanstalkd, etc.)
|
26
|
-
- Logs collection daemons
|
27
|
-
- Or any other program that needs to keep running
|
28
|
-
|
29
|
-
### Monitoring
|
30
|
-
|
31
|
-
Cognizant can be used to monitor an application process' state so that it
|
32
|
-
is running at all times. When cognizant is instructed to monitor a process,
|
33
|
-
by default, the process will automatically be started. These processes are
|
34
|
-
automatically monitored for their state. i.e. a process is automatically
|
35
|
-
started again if it stops unexpectedly.
|
36
|
-
|
37
|
-
### Conditions
|
38
|
-
|
39
|
-
Conditions provide a way to monitor and act on more than just the state of a
|
40
|
-
process. For example, conditions can monitor the resource utilization (RAM,
|
41
|
-
CPU, etc.) of the application process and restart it if it matches a
|
42
|
-
condition.
|
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
|
-
|
54
|
-
## Getting started
|
55
|
-
|
56
|
-
Cognizant is written in the Ruby programming language, and hence depends on
|
57
|
-
it. Ensure that you have Ruby 1.9+ installed and run:
|
58
|
-
|
59
|
-
$ gem install cognizant
|
60
|
-
|
61
|
-
## Architecture overview
|
62
|
-
|
63
|
-
_____
|
64
|
-
___________ |
|
65
|
-
____________ ____________ | | |
|
66
|
-
| | | | -----> | Process A | |
|
67
|
-
| Admin | | Monitoring | |___________| |
|
68
|
-
| Utility | -----> | Daemon | ___________ | -- Managed Processes
|
69
|
-
| >_ | | | | | |
|
70
|
-
|____________| |____________| -----> | Process B | |
|
71
|
-
|___________| |
|
72
|
-
_____|
|
73
|
-
|
74
|
-
Since cognizant administration and process monitoring are two separate concerns, they are serviced by separate applications, `cognizant` and `cognizantd`, respectively.
|
75
|
-
|
76
|
-
## Starting the monitoring daemon
|
77
|
-
|
78
|
-
Cognizant runs the monitoring essentials through the `cognizantd` daemon application, which also maintains a server for accepting commands from the `cognizant` administration utility.
|
79
|
-
|
80
|
-
The daemon, with it's default options, requires superuser access to certain system directories for storing logs and pid files. It can be started as follows:
|
81
|
-
|
82
|
-
$ sudo cognizantd # ubuntu, debian, os x, etc.
|
83
|
-
$ su -c 'cognizantd' # amazon linux, centos, rhel, etc.
|
84
|
-
|
85
|
-
To start without superuser access, specify these file and directory config variables to where the user starting it has write access:
|
86
|
-
|
87
|
-
$ cognizantd ./examples/cognizantd.yml
|
88
|
-
|
89
|
-
# assuming that:
|
90
|
-
|
91
|
-
$ cat ~/.examples/cognizantd.yml # find this file in source code for latest version
|
92
|
-
---
|
93
|
-
socket: ~/.cognizant/cognizantd.sock
|
94
|
-
pidfile: ~/.cognizant/cognizantd.pid
|
95
|
-
logfile: ~/.cognizant/cognizantd.log
|
96
|
-
pids_dir: ~/.cognizant/pids/
|
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
|
-
}
|
125
|
-
|
126
|
-
or
|
127
|
-
|
128
|
-
# pass config directly into the daemon's STDIN
|
129
|
-
$ echo <<EOF | cognizantd -
|
130
|
-
---
|
131
|
-
socket: ~/.cognizant/cognizantd.sock
|
132
|
-
...
|
133
|
-
monitor: {
|
134
|
-
...
|
135
|
-
...
|
136
|
-
}
|
137
|
-
EOF
|
138
|
-
|
139
|
-
Process information can also be provided via Ruby code. See `load` command below.
|
140
|
-
|
141
|
-
## Using the administration utility
|
142
|
-
|
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.
|
144
|
-
|
145
|
-
Here are some basic operational commands:
|
146
|
-
|
147
|
-
$ cognizant monitor redis # by group name
|
148
|
-
$ cognizant restart redis-server-1 # by process name
|
149
|
-
|
150
|
-
To get cognizant to ignore a particular process' state:
|
151
|
-
|
152
|
-
$ cognizant unmonitor sleep-10
|
153
|
-
|
154
|
-
Now check status of all managed processes:
|
155
|
-
|
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
|
196
|
-
|
197
|
-
## Compatibility
|
198
|
-
|
199
|
-
Cognizant was developed and tested under Ruby 1.9.2-p290.
|
200
|
-
|
201
|
-
## Similar programs
|
202
|
-
|
203
|
-
- Monit
|
204
|
-
- God (Ruby)
|
205
|
-
- Bluepill (Ruby)
|
206
|
-
- Supervisord (Python)
|
207
|
-
- Upstart
|
208
|
-
- SysV Init
|
209
|
-
- Systemd
|
210
|
-
- Launchd
|
211
|
-
|
212
|
-
### Links
|
213
|
-
|
214
|
-
- Documentation: http://rubydoc.info/github/Gurpartap/cognizant/frames
|
215
|
-
- Source: https://github.com/Gurpartap/cognizant
|
216
|
-
- Rubygems: https://rubygems.org/gems/cognizant
|
217
|
-
|
218
|
-
## About
|
219
|
-
|
220
|
-
Cognizant is a project of [Gurpartap Singh](http://gurpartap.com/). Feel free
|
221
|
-
to get in touch.
|
data/examples/redis-server.rb
DELETED
@@ -1,28 +0,0 @@
|
|
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
|
-
|
10
|
-
slaveof = i == 0 ? "" : "slaveof 127.0.0.1 6000"
|
11
|
-
process.start_with_input = <<-heredoc
|
12
|
-
daemonize no
|
13
|
-
port 600#{i}
|
14
|
-
#{slaveof}
|
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
|
27
|
-
end
|
28
|
-
end
|
data/examples/resque.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
5.times do |i|
|
2
|
-
Cognizant.monitor "resque-worker-#{i}" do |process|
|
3
|
-
process.group = "resque"
|
4
|
-
process.uid = "deploy"
|
5
|
-
process.gid = "deploy"
|
6
|
-
process.chdir = "/apps/example/current/"
|
7
|
-
process.env = { "QUEUE" => "*", "RACK_ENV" => "production" }
|
8
|
-
process.start_command = "bundle exec rake resque:work"
|
9
|
-
end
|
10
|
-
end
|
data/images/logo-small.png
DELETED
Binary file
|
data/images/logo.png
DELETED
Binary file
|
data/images/logo.pxm
DELETED
Binary file
|
data/lib/cognizant/logging.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require "logger"
|
2
|
-
|
3
|
-
module Cognizant
|
4
|
-
module Logging
|
5
|
-
extend self
|
6
|
-
|
7
|
-
def add_log_adapter(file)
|
8
|
-
@files ||= Array.new
|
9
|
-
@files << file unless @files.include?(file)
|
10
|
-
@logger = nil
|
11
|
-
end
|
12
|
-
|
13
|
-
def log
|
14
|
-
@files ||= Array.new($stdout)
|
15
|
-
@logger ||= Logger.new(Files.new(*@files))
|
16
|
-
end
|
17
|
-
alias :logger :log
|
18
|
-
|
19
|
-
class Files
|
20
|
-
def initialize(*files)
|
21
|
-
@files = files
|
22
|
-
end
|
23
|
-
|
24
|
-
def write(*args)
|
25
|
-
@files.each { |t| t.write(*args) }
|
26
|
-
end
|
27
|
-
|
28
|
-
def close
|
29
|
-
@files.each(&:close)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require "cognizant/util/rotational_array"
|
2
|
-
|
3
|
-
module Cognizant
|
4
|
-
class Process
|
5
|
-
module Conditions
|
6
|
-
class Flapping < TriggerCondition
|
7
|
-
TRIGGER_STATES = [:starting, :restarting]
|
8
|
-
|
9
|
-
attr_accessor :times, :within, :retry_after
|
10
|
-
attr_reader :timeline
|
11
|
-
|
12
|
-
def initialize(process, options = {})
|
13
|
-
options = { :times => 5, :within => 1, :retry_after => 5 }.merge(options)
|
14
|
-
|
15
|
-
options.each_pair do |name, value|
|
16
|
-
self.send("#{name}=", value) if self.respond_to?("#{name}=")
|
17
|
-
end
|
18
|
-
|
19
|
-
@timeline = Util::RotationalArray.new(@times)
|
20
|
-
super
|
21
|
-
end
|
22
|
-
|
23
|
-
def notify(transition)
|
24
|
-
if TRIGGER_STATES.include?(transition.to_name)
|
25
|
-
self.timeline << Time.now.to_i
|
26
|
-
self.check_flapping
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def reset!
|
31
|
-
@timeline.clear
|
32
|
-
super
|
33
|
-
end
|
34
|
-
|
35
|
-
def check_flapping
|
36
|
-
# The process has not flapped if we haven't encountered enough incidents.
|
37
|
-
return unless (@timeline.compact.length == self.times)
|
38
|
-
|
39
|
-
# Check if the incident happend within the timeframe.
|
40
|
-
duration = (@timeline.last - @timeline.first) <= self.within
|
41
|
-
|
42
|
-
if duration
|
43
|
-
puts "Flapping detected: retrying in #{self.retry_after} seconds"
|
44
|
-
|
45
|
-
self.schedule_event(:start, self.retry_after) unless self.retry_after == 0 # retry_after zero means "do not retry, ever".
|
46
|
-
self.schedule_event(:unmonitor, 0)
|
47
|
-
|
48
|
-
@timeline.clear
|
49
|
-
|
50
|
-
# This will prevent a transition from happening in the process state_machine.
|
51
|
-
throw :halt
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Cognizant
|
2
|
-
class Process
|
3
|
-
module Conditions
|
4
|
-
class TriggerCondition
|
5
|
-
attr_accessor :process, :mutex, :scheduled_events
|
6
|
-
|
7
|
-
def initialize(process, options = {})
|
8
|
-
self.process = process
|
9
|
-
self.mutex = Mutex.new
|
10
|
-
self.scheduled_events = []
|
11
|
-
end
|
12
|
-
|
13
|
-
def reset!
|
14
|
-
self.cancel_all_events
|
15
|
-
end
|
16
|
-
|
17
|
-
def notify(transition)
|
18
|
-
raise "Implement in subclass"
|
19
|
-
end
|
20
|
-
|
21
|
-
def dispatch!(event)
|
22
|
-
self.process.dispatch!(event, self.class.name.split("::").last)
|
23
|
-
end
|
24
|
-
|
25
|
-
def schedule_event(event, delay)
|
26
|
-
# TODO: Maybe wrap this in a ScheduledEvent class with methods like cancel.
|
27
|
-
thread = Thread.new(self) do |trigger|
|
28
|
-
begin
|
29
|
-
sleep delay.to_f
|
30
|
-
trigger.dispatch!(event)
|
31
|
-
trigger.mutex.synchronize do
|
32
|
-
trigger.scheduled_events.delete_if { |_, thread| thread == Thread.current }
|
33
|
-
end
|
34
|
-
rescue StandardError => e
|
35
|
-
puts(e)
|
36
|
-
puts(e.backtrace.join("\n"))
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
self.scheduled_events.push([event, thread])
|
41
|
-
end
|
42
|
-
|
43
|
-
def cancel_all_events
|
44
|
-
puts "Canceling all scheduled events"
|
45
|
-
self.mutex.synchronize do
|
46
|
-
self.scheduled_events.each {|_, thread| thread.kill}
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
data/lib/cognizant/server.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require "json"
|
2
|
-
require "cognizant/system"
|
3
|
-
|
4
|
-
module Cognizant
|
5
|
-
module Server
|
6
|
-
module Commands
|
7
|
-
def self.load(config_file)
|
8
|
-
Cognizant::Server.daemon.load(config_file)
|
9
|
-
# yield("OK")
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.status(*args)
|
13
|
-
output_processes = []
|
14
|
-
if args.size > 0
|
15
|
-
Cognizant::Server.daemon.processes.values.each do |process|
|
16
|
-
output_processes << process if args.include?(process.name) or args.include?(process.group)
|
17
|
-
end
|
18
|
-
if output_processes.size == 0
|
19
|
-
raise("ERROR: No such process")
|
20
|
-
# yield("OK")
|
21
|
-
end
|
22
|
-
else
|
23
|
-
output_processes = Cognizant::Server.daemon.processes.values
|
24
|
-
end
|
25
|
-
|
26
|
-
output = []
|
27
|
-
output_processes.each do |process|
|
28
|
-
pid = process.read_pid
|
29
|
-
output << {
|
30
|
-
"Process" => process.name,
|
31
|
-
"PID" => pid,
|
32
|
-
"Group" => process.group,
|
33
|
-
"State" => process.state,
|
34
|
-
"Since" => process.last_transition_time,
|
35
|
-
"% CPU" => System.cpu_usage(pid).to_f,
|
36
|
-
"Memory" => System.memory_usage(pid).to_f # in KBs.
|
37
|
-
}
|
38
|
-
end
|
39
|
-
yield(output.to_json)
|
40
|
-
# yield("OK")
|
41
|
-
end
|
42
|
-
|
43
|
-
%w(monitor start stop restart unmonitor).each do |action|
|
44
|
-
class_eval <<-END
|
45
|
-
def self.#{action}(*args)
|
46
|
-
unless args.size > 0
|
47
|
-
raise("ERROR: Missing process name")
|
48
|
-
return # yield("OK")
|
49
|
-
end
|
50
|
-
output_processes = []
|
51
|
-
Cognizant::Server.daemon.processes.values.each do |process|
|
52
|
-
if args.include?(process.name) or args.include?(process.group)
|
53
|
-
output_processes << process
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
if output_processes.size == 0
|
58
|
-
raise("ERROR: No such process")
|
59
|
-
# yield("OK")
|
60
|
-
else
|
61
|
-
output_processes.each do |process|
|
62
|
-
process.handle_user_command(:#{action})
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
END
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.shutdown
|
70
|
-
Cognizant::Server.daemon.shutdown
|
71
|
-
# yield("OK")
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.method_missing(command, *args)
|
75
|
-
raise("ERROR: Unknown command '#{command}'")
|
76
|
-
# yield("OK")
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|