cognizant 0.0.2 → 0.0.3
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.
- 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
|