resurrected_god 0.14.0
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/Announce.txt +135 -0
- data/Gemfile +5 -0
- data/LICENSE +22 -0
- data/README.md +33 -0
- data/Rakefile +129 -0
- data/bin/god +134 -0
- data/doc/god.asciidoc +1592 -0
- data/doc/intro.asciidoc +20 -0
- data/ext/god/.gitignore +5 -0
- data/ext/god/extconf.rb +56 -0
- data/ext/god/kqueue_handler.c +133 -0
- data/ext/god/netlink_handler.c +182 -0
- data/lib/god/behavior.rb +52 -0
- data/lib/god/behaviors/clean_pid_file.rb +21 -0
- data/lib/god/behaviors/clean_unix_socket.rb +21 -0
- data/lib/god/behaviors/notify_when_flapping.rb +51 -0
- data/lib/god/cli/command.rb +268 -0
- data/lib/god/cli/run.rb +170 -0
- data/lib/god/cli/version.rb +23 -0
- data/lib/god/compat19.rb +33 -0
- data/lib/god/condition.rb +96 -0
- data/lib/god/conditions/always.rb +36 -0
- data/lib/god/conditions/complex.rb +86 -0
- data/lib/god/conditions/cpu_usage.rb +80 -0
- data/lib/god/conditions/degrading_lambda.rb +52 -0
- data/lib/god/conditions/disk_usage.rb +32 -0
- data/lib/god/conditions/file_mtime.rb +28 -0
- data/lib/god/conditions/file_touched.rb +44 -0
- data/lib/god/conditions/flapping.rb +128 -0
- data/lib/god/conditions/http_response_code.rb +184 -0
- data/lib/god/conditions/lambda.rb +25 -0
- data/lib/god/conditions/memory_usage.rb +82 -0
- data/lib/god/conditions/process_exits.rb +66 -0
- data/lib/god/conditions/process_running.rb +63 -0
- data/lib/god/conditions/socket_responding.rb +142 -0
- data/lib/god/conditions/tries.rb +44 -0
- data/lib/god/configurable.rb +57 -0
- data/lib/god/contact.rb +114 -0
- data/lib/god/contacts/airbrake.rb +44 -0
- data/lib/god/contacts/campfire.rb +121 -0
- data/lib/god/contacts/email.rb +130 -0
- data/lib/god/contacts/hipchat.rb +117 -0
- data/lib/god/contacts/jabber.rb +75 -0
- data/lib/god/contacts/prowl.rb +57 -0
- data/lib/god/contacts/scout.rb +55 -0
- data/lib/god/contacts/sensu.rb +59 -0
- data/lib/god/contacts/slack.rb +98 -0
- data/lib/god/contacts/statsd.rb +46 -0
- data/lib/god/contacts/twitter.rb +51 -0
- data/lib/god/contacts/webhook.rb +74 -0
- data/lib/god/driver.rb +238 -0
- data/lib/god/errors.rb +24 -0
- data/lib/god/event_handler.rb +112 -0
- data/lib/god/event_handlers/dummy_handler.rb +13 -0
- data/lib/god/event_handlers/kqueue_handler.rb +17 -0
- data/lib/god/event_handlers/netlink_handler.rb +13 -0
- data/lib/god/logger.rb +109 -0
- data/lib/god/metric.rb +87 -0
- data/lib/god/process.rb +381 -0
- data/lib/god/registry.rb +32 -0
- data/lib/god/simple_logger.rb +59 -0
- data/lib/god/socket.rb +113 -0
- data/lib/god/sugar.rb +62 -0
- data/lib/god/sys_logger.rb +45 -0
- data/lib/god/system/portable_poller.rb +42 -0
- data/lib/god/system/process.rb +50 -0
- data/lib/god/system/slash_proc_poller.rb +92 -0
- data/lib/god/task.rb +552 -0
- data/lib/god/timeline.rb +25 -0
- data/lib/god/trigger.rb +43 -0
- data/lib/god/version.rb +4 -0
- data/lib/god/watch.rb +340 -0
- data/lib/god.rb +777 -0
- data/test/configs/child_events/child_events.god +44 -0
- data/test/configs/child_events/simple_server.rb +3 -0
- data/test/configs/child_polls/child_polls.god +37 -0
- data/test/configs/child_polls/simple_server.rb +12 -0
- data/test/configs/complex/complex.god +59 -0
- data/test/configs/complex/simple_server.rb +3 -0
- data/test/configs/contact/contact.god +118 -0
- data/test/configs/contact/simple_server.rb +3 -0
- data/test/configs/daemon_events/daemon_events.god +37 -0
- data/test/configs/daemon_events/simple_server.rb +8 -0
- data/test/configs/daemon_events/simple_server_stop.rb +11 -0
- data/test/configs/daemon_polls/daemon_polls.god +17 -0
- data/test/configs/daemon_polls/simple_server.rb +6 -0
- data/test/configs/degrading_lambda/degrading_lambda.god +31 -0
- data/test/configs/degrading_lambda/tcp_server.rb +15 -0
- data/test/configs/keepalive/keepalive.god +9 -0
- data/test/configs/keepalive/keepalive.rb +12 -0
- data/test/configs/lifecycle/lifecycle.god +25 -0
- data/test/configs/matias/matias.god +50 -0
- data/test/configs/real.rb +59 -0
- data/test/configs/running_load/running_load.god +16 -0
- data/test/configs/stop_options/simple_server.rb +12 -0
- data/test/configs/stop_options/stop_options.god +39 -0
- data/test/configs/stress/simple_server.rb +3 -0
- data/test/configs/stress/stress.god +15 -0
- data/test/configs/task/logs/.placeholder +0 -0
- data/test/configs/task/task.god +26 -0
- data/test/configs/test.rb +61 -0
- data/test/configs/usr1_trapper.rb +10 -0
- data/test/helper.rb +172 -0
- data/test/suite.rb +6 -0
- data/test/test_airbrake.rb +14 -0
- data/test/test_behavior.rb +18 -0
- data/test/test_campfire.rb +22 -0
- data/test/test_condition.rb +52 -0
- data/test/test_conditions_disk_usage.rb +50 -0
- data/test/test_conditions_http_response_code.rb +109 -0
- data/test/test_conditions_process_running.rb +40 -0
- data/test/test_conditions_socket_responding.rb +176 -0
- data/test/test_conditions_tries.rb +67 -0
- data/test/test_contact.rb +109 -0
- data/test/test_driver.rb +26 -0
- data/test/test_email.rb +34 -0
- data/test/test_event_handler.rb +82 -0
- data/test/test_god.rb +710 -0
- data/test/test_god_system.rb +201 -0
- data/test/test_handlers_kqueue_handler.rb +16 -0
- data/test/test_hipchat.rb +23 -0
- data/test/test_jabber.rb +29 -0
- data/test/test_logger.rb +55 -0
- data/test/test_metric.rb +74 -0
- data/test/test_process.rb +263 -0
- data/test/test_prowl.rb +15 -0
- data/test/test_registry.rb +15 -0
- data/test/test_sensu.rb +11 -0
- data/test/test_slack.rb +57 -0
- data/test/test_socket.rb +34 -0
- data/test/test_statsd.rb +22 -0
- data/test/test_sugar.rb +42 -0
- data/test/test_system_portable_poller.rb +17 -0
- data/test/test_system_process.rb +30 -0
- data/test/test_task.rb +246 -0
- data/test/test_timeline.rb +37 -0
- data/test/test_trigger.rb +63 -0
- data/test/test_watch.rb +286 -0
- data/test/test_webhook.rb +22 -0
- metadata +476 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module God
|
|
2
|
+
module System
|
|
3
|
+
class PortablePoller
|
|
4
|
+
def initialize(pid)
|
|
5
|
+
@pid = pid
|
|
6
|
+
end
|
|
7
|
+
# Memory usage in kilobytes (resident set size)
|
|
8
|
+
def memory
|
|
9
|
+
ps_int('rss')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Percentage memory usage
|
|
13
|
+
def percent_memory
|
|
14
|
+
ps_float('%mem')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Percentage CPU usage
|
|
18
|
+
def percent_cpu
|
|
19
|
+
ps_float('%cpu')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def ps_int(keyword)
|
|
25
|
+
`ps -o #{keyword}= -p #{@pid}`.to_i
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def ps_float(keyword)
|
|
29
|
+
`ps -o #{keyword}= -p #{@pid}`.to_f
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def ps_string(keyword)
|
|
33
|
+
`ps -o #{keyword}= -p #{@pid}`.strip
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def time_string_to_seconds(text)
|
|
37
|
+
_, minutes, seconds, useconds = *text.match(/(\d+):(\d{2}).(\d{2})/)
|
|
38
|
+
(minutes.to_i * 60) + seconds.to_i
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module God
|
|
2
|
+
module System
|
|
3
|
+
|
|
4
|
+
class Process
|
|
5
|
+
def self.fetch_system_poller
|
|
6
|
+
@@poller ||= if SlashProcPoller.usable?
|
|
7
|
+
SlashProcPoller
|
|
8
|
+
else
|
|
9
|
+
PortablePoller
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(pid)
|
|
14
|
+
@pid = pid.to_i
|
|
15
|
+
@poller = self.class.fetch_system_poller.new(@pid)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Return true if this process is running, false otherwise
|
|
19
|
+
def exists?
|
|
20
|
+
!!::Process.kill(0, @pid) rescue false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Memory usage in kilobytes (resident set size)
|
|
24
|
+
def memory
|
|
25
|
+
@poller.memory
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Percentage memory usage
|
|
29
|
+
def percent_memory
|
|
30
|
+
@poller.percent_memory
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Percentage CPU usage
|
|
34
|
+
def percent_cpu
|
|
35
|
+
@poller.percent_cpu
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def fetch_system_poller
|
|
41
|
+
if SlashProcPoller.usable?
|
|
42
|
+
SlashProcPoller
|
|
43
|
+
else
|
|
44
|
+
PortablePoller
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module God
|
|
2
|
+
module System
|
|
3
|
+
class SlashProcPoller < PortablePoller
|
|
4
|
+
@@kb_per_page = 4 # TODO: Need to make this portable
|
|
5
|
+
@@hertz = 100
|
|
6
|
+
@@total_mem = nil
|
|
7
|
+
|
|
8
|
+
MeminfoPath = '/proc/meminfo'
|
|
9
|
+
UptimePath = '/proc/uptime'
|
|
10
|
+
|
|
11
|
+
RequiredPaths = [MeminfoPath, UptimePath]
|
|
12
|
+
|
|
13
|
+
# FreeBSD has /proc by default, but nothing mounted there!
|
|
14
|
+
# So we should check for the actual required paths!
|
|
15
|
+
# Returns true if +RequiredPaths+ are readable.
|
|
16
|
+
def self.usable?
|
|
17
|
+
RequiredPaths.all? do |path|
|
|
18
|
+
test(?r, path) && readable?(path)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def initialize(pid)
|
|
23
|
+
super(pid)
|
|
24
|
+
|
|
25
|
+
unless @@total_mem # in K
|
|
26
|
+
File.open(MeminfoPath) do |f|
|
|
27
|
+
@@total_mem = f.gets.split[1]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def memory
|
|
33
|
+
stat[:rss].to_i * @@kb_per_page
|
|
34
|
+
rescue # This shouldn't fail is there's an error (or proc doesn't exist)
|
|
35
|
+
0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def percent_memory
|
|
39
|
+
(memory / @@total_mem.to_f) * 100
|
|
40
|
+
rescue # This shouldn't fail is there's an error (or proc doesn't exist)
|
|
41
|
+
0
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# TODO: Change this to calculate the wma instead
|
|
45
|
+
def percent_cpu
|
|
46
|
+
stats = stat
|
|
47
|
+
total_time = stats[:utime].to_i + stats[:stime].to_i # in jiffies
|
|
48
|
+
seconds = uptime - stats[:starttime].to_i / @@hertz
|
|
49
|
+
if seconds == 0
|
|
50
|
+
0
|
|
51
|
+
else
|
|
52
|
+
((total_time * 1000 / @@hertz) / seconds) / 10
|
|
53
|
+
end
|
|
54
|
+
rescue # This shouldn't fail is there's an error (or proc doesn't exist)
|
|
55
|
+
0
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# Some systems (CentOS?) have a /proc, but they can hang when trying to
|
|
61
|
+
# read from them. Try to use this sparingly as it is expensive.
|
|
62
|
+
def self.readable?(path)
|
|
63
|
+
begin
|
|
64
|
+
Timeout.timeout(1) { File.read(path) }
|
|
65
|
+
rescue Timeout::Error
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# in seconds
|
|
71
|
+
def uptime
|
|
72
|
+
File.read(UptimePath).split[0].to_f
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def stat
|
|
76
|
+
stats = {}
|
|
77
|
+
stats[:pid], stats[:comm], stats[:state], stats[:ppid], stats[:pgrp],
|
|
78
|
+
stats[:session], stats[:tty_nr], stats[:tpgid], stats[:flags],
|
|
79
|
+
stats[:minflt], stats[:cminflt], stats[:majflt], stats[:cmajflt],
|
|
80
|
+
stats[:utime], stats[:stime], stats[:cutime], stats[:cstime],
|
|
81
|
+
stats[:priority], stats[:nice], _, stats[:itrealvalue],
|
|
82
|
+
stats[:starttime], stats[:vsize], stats[:rss], stats[:rlim],
|
|
83
|
+
stats[:startcode], stats[:endcode], stats[:startstack], stats[:kstkesp],
|
|
84
|
+
stats[:kstkeip], stats[:signal], stats[:blocked], stats[:sigignore],
|
|
85
|
+
stats[:sigcatch], stats[:wchan], stats[:nswap], stats[:cnswap],
|
|
86
|
+
stats[:exit_signal], stats[:processor], stats[:rt_priority],
|
|
87
|
+
stats[:policy] = File.read("/proc/#{@pid}/stat").scan(/\(.*?\)|\w+/)
|
|
88
|
+
stats
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|