eye 0.1.11
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/.gitignore +31 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +132 -0
- data/Rakefile +18 -0
- data/bin/eye +282 -0
- data/bin/loader_eye +56 -0
- data/examples/processes/em.rb +56 -0
- data/examples/processes/forking.rb +20 -0
- data/examples/processes/sample.rb +144 -0
- data/examples/rbenv.eye +11 -0
- data/examples/test.eye +65 -0
- data/examples/unicorn.eye +29 -0
- data/eye.gemspec +37 -0
- data/lib/eye.rb +25 -0
- data/lib/eye/application.rb +65 -0
- data/lib/eye/checker.rb +118 -0
- data/lib/eye/checker/cpu.rb +27 -0
- data/lib/eye/checker/file_ctime.rb +29 -0
- data/lib/eye/checker/file_size.rb +38 -0
- data/lib/eye/checker/http.rb +94 -0
- data/lib/eye/checker/memory.rb +27 -0
- data/lib/eye/checker/socket.rb +148 -0
- data/lib/eye/checker/validation.rb +49 -0
- data/lib/eye/child_process.rb +75 -0
- data/lib/eye/client.rb +32 -0
- data/lib/eye/control.rb +2 -0
- data/lib/eye/controller.rb +43 -0
- data/lib/eye/controller/commands.rb +64 -0
- data/lib/eye/controller/helpers.rb +61 -0
- data/lib/eye/controller/load.rb +224 -0
- data/lib/eye/controller/send_command.rb +88 -0
- data/lib/eye/controller/status.rb +136 -0
- data/lib/eye/dsl.rb +52 -0
- data/lib/eye/dsl/application_opts.rb +33 -0
- data/lib/eye/dsl/chain.rb +12 -0
- data/lib/eye/dsl/child_process_opts.rb +7 -0
- data/lib/eye/dsl/config_opts.rb +11 -0
- data/lib/eye/dsl/group_opts.rb +27 -0
- data/lib/eye/dsl/helpers.rb +12 -0
- data/lib/eye/dsl/main.rb +58 -0
- data/lib/eye/dsl/opts.rb +88 -0
- data/lib/eye/dsl/process_opts.rb +21 -0
- data/lib/eye/dsl/pure_opts.rb +132 -0
- data/lib/eye/dsl/validate.rb +41 -0
- data/lib/eye/group.rb +125 -0
- data/lib/eye/group/chain.rb +68 -0
- data/lib/eye/io/unix_server.rb +44 -0
- data/lib/eye/io/unix_socket.rb +39 -0
- data/lib/eye/loader.rb +13 -0
- data/lib/eye/logger.rb +80 -0
- data/lib/eye/process.rb +83 -0
- data/lib/eye/process/child.rb +61 -0
- data/lib/eye/process/commands.rb +256 -0
- data/lib/eye/process/config.rb +70 -0
- data/lib/eye/process/controller.rb +72 -0
- data/lib/eye/process/data.rb +46 -0
- data/lib/eye/process/monitor.rb +97 -0
- data/lib/eye/process/notify.rb +17 -0
- data/lib/eye/process/scheduler.rb +50 -0
- data/lib/eye/process/states.rb +92 -0
- data/lib/eye/process/states_history.rb +62 -0
- data/lib/eye/process/system.rb +60 -0
- data/lib/eye/process/trigger.rb +32 -0
- data/lib/eye/process/watchers.rb +67 -0
- data/lib/eye/server.rb +51 -0
- data/lib/eye/settings.rb +35 -0
- data/lib/eye/system.rb +145 -0
- data/lib/eye/system_resources.rb +83 -0
- data/lib/eye/trigger.rb +53 -0
- data/lib/eye/trigger/flapping.rb +24 -0
- data/lib/eye/utils.rb +5 -0
- data/lib/eye/utils/alive_array.rb +31 -0
- data/lib/eye/utils/celluloid_chain.rb +51 -0
- data/lib/eye/utils/leak_19.rb +7 -0
- data/lib/eye/utils/tail.rb +20 -0
- data/spec/checker/cpu_spec.rb +58 -0
- data/spec/checker/file_ctime_spec.rb +34 -0
- data/spec/checker/file_size_spec.rb +107 -0
- data/spec/checker/http_spec.rb +109 -0
- data/spec/checker/memory_spec.rb +64 -0
- data/spec/checker/socket_spec.rb +116 -0
- data/spec/checker_spec.rb +188 -0
- data/spec/child_process/child_process_spec.rb +46 -0
- data/spec/client_server_spec.rb +34 -0
- data/spec/controller/commands_spec.rb +92 -0
- data/spec/controller/controller_spec.rb +133 -0
- data/spec/controller/find_objects_spec.rb +150 -0
- data/spec/controller/group_spec.rb +110 -0
- data/spec/controller/intergration_spec.rb +327 -0
- data/spec/controller/load_spec.rb +326 -0
- data/spec/controller/races_spec.rb +70 -0
- data/spec/controller/stop_on_delete_spec.rb +157 -0
- data/spec/dsl/chain_spec.rb +140 -0
- data/spec/dsl/checks_spec.rb +202 -0
- data/spec/dsl/config_spec.rb +44 -0
- data/spec/dsl/dsl_spec.rb +73 -0
- data/spec/dsl/getter_spec.rb +223 -0
- data/spec/dsl/integration_spec.rb +311 -0
- data/spec/dsl/load_spec.rb +52 -0
- data/spec/dsl/process_spec.rb +330 -0
- data/spec/dsl/sub_procs_spec.rb +93 -0
- data/spec/dsl/with_server_spec.rb +104 -0
- data/spec/example/em.rb +57 -0
- data/spec/example/forking.rb +20 -0
- data/spec/example/sample.rb +154 -0
- data/spec/fixtures/dsl/0.rb +8 -0
- data/spec/fixtures/dsl/0a.rb +8 -0
- data/spec/fixtures/dsl/0c.rb +8 -0
- data/spec/fixtures/dsl/1.rb +5 -0
- data/spec/fixtures/dsl/bad.eye +6 -0
- data/spec/fixtures/dsl/configs/1.eye +3 -0
- data/spec/fixtures/dsl/configs/2.eye +1 -0
- data/spec/fixtures/dsl/configs/3.eye +1 -0
- data/spec/fixtures/dsl/configs/4.eye +3 -0
- data/spec/fixtures/dsl/empty.eye +20 -0
- data/spec/fixtures/dsl/include_test.eye +5 -0
- data/spec/fixtures/dsl/include_test/1.rb +6 -0
- data/spec/fixtures/dsl/include_test/ha.rb +4 -0
- data/spec/fixtures/dsl/include_test2.eye +5 -0
- data/spec/fixtures/dsl/integration.eye +30 -0
- data/spec/fixtures/dsl/integration2.eye +32 -0
- data/spec/fixtures/dsl/integration_locks.eye +30 -0
- data/spec/fixtures/dsl/integration_sor.eye +32 -0
- data/spec/fixtures/dsl/integration_sor2.eye +27 -0
- data/spec/fixtures/dsl/integration_sor3.eye +32 -0
- data/spec/fixtures/dsl/load.eye +25 -0
- data/spec/fixtures/dsl/load2.eye +7 -0
- data/spec/fixtures/dsl/load2_dup2.eye +13 -0
- data/spec/fixtures/dsl/load2_dup_pid.eye +7 -0
- data/spec/fixtures/dsl/load3.eye +10 -0
- data/spec/fixtures/dsl/load4.eye +7 -0
- data/spec/fixtures/dsl/load5.eye +8 -0
- data/spec/fixtures/dsl/load6.eye +17 -0
- data/spec/fixtures/dsl/load_dubls.eye +36 -0
- data/spec/fixtures/dsl/load_dup_ex_names.eye +15 -0
- data/spec/fixtures/dsl/load_error.eye +5 -0
- data/spec/fixtures/dsl/load_error_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_error_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_folder/load3.eye +10 -0
- data/spec/fixtures/dsl/load_folder/load4.eye +7 -0
- data/spec/fixtures/dsl/load_int.eye +8 -0
- data/spec/fixtures/dsl/load_int2.eye +13 -0
- data/spec/fixtures/dsl/load_logger.eye +26 -0
- data/spec/fixtures/dsl/load_logger2.eye +3 -0
- data/spec/fixtures/dsl/long_load.eye +5 -0
- data/spec/fixtures/dsl/subfolder1/proc1.rb +3 -0
- data/spec/fixtures/dsl/subfolder2.eye +9 -0
- data/spec/fixtures/dsl/subfolder2/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder2/proc2.rb +3 -0
- data/spec/fixtures/dsl/subfolder2/sub/proc3.rb +6 -0
- data/spec/fixtures/dsl/subfolder3.eye +8 -0
- data/spec/fixtures/dsl/subfolder3/common.rb +1 -0
- data/spec/fixtures/dsl/subfolder3/proc4.rb +3 -0
- data/spec/fixtures/dsl/subfolder3/sub/proc5.rb +6 -0
- data/spec/fixtures/dsl/subfolder4.eye +6 -0
- data/spec/fixtures/dsl/subfolder4/a.rb +2 -0
- data/spec/fixtures/dsl/subfolder4/b.rb +1 -0
- data/spec/fixtures/dsl/subfolder4/c.rb +1 -0
- data/spec/mock_spec.rb +32 -0
- data/spec/process/checks/child_checks_spec.rb +79 -0
- data/spec/process/checks/cpu_spec.rb +114 -0
- data/spec/process/checks/ctime_spec.rb +43 -0
- data/spec/process/checks/fsize_spec.rb +22 -0
- data/spec/process/checks/http_spec.rb +52 -0
- data/spec/process/checks/intergration_spec.rb +32 -0
- data/spec/process/checks/memory_spec.rb +113 -0
- data/spec/process/child_process_spec.rb +125 -0
- data/spec/process/config_spec.rb +75 -0
- data/spec/process/controller_spec.rb +173 -0
- data/spec/process/monitoring_spec.rb +180 -0
- data/spec/process/restart_spec.rb +174 -0
- data/spec/process/scheduler_spec.rb +150 -0
- data/spec/process/start_spec.rb +261 -0
- data/spec/process/states_history_spec.rb +118 -0
- data/spec/process/stop_spec.rb +150 -0
- data/spec/process/system_spec.rb +100 -0
- data/spec/process/triggers/flapping_spec.rb +81 -0
- data/spec/process/update_config_spec.rb +63 -0
- data/spec/spec_helper.rb +120 -0
- data/spec/support/rr_celluloid.rb +36 -0
- data/spec/support/scheduler_hack.rb +16 -0
- data/spec/support/spec_support.rb +164 -0
- data/spec/system_resources_spec.rb +59 -0
- data/spec/system_spec.rb +170 -0
- data/spec/utils/alive_array_spec.rb +50 -0
- data/spec/utils/celluloid_chain_spec.rb +82 -0
- data/spec/utils/tail_spec.rb +21 -0
- metadata +558 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
class Eye::Application
|
2
|
+
|
3
|
+
attr_reader :groups, :name
|
4
|
+
|
5
|
+
include Eye::Logger::Helpers
|
6
|
+
|
7
|
+
def initialize(name, config = {})
|
8
|
+
@groups = Eye::Utils::AliveArray.new
|
9
|
+
@name = name
|
10
|
+
@logger = Eye::Logger.new(full_name)
|
11
|
+
@config = config
|
12
|
+
debug 'created'
|
13
|
+
end
|
14
|
+
|
15
|
+
def full_name
|
16
|
+
@name
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_config(cfg)
|
20
|
+
@config = cfg
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_group(group)
|
24
|
+
@groups << group
|
25
|
+
end
|
26
|
+
|
27
|
+
def status_data(debug = false)
|
28
|
+
h = { name: @name, type: :application, subtree: @groups.map{|gr| gr.status_data(debug) }}
|
29
|
+
h.merge!(debug: debug_data) if debug
|
30
|
+
h
|
31
|
+
end
|
32
|
+
|
33
|
+
def status_data_short
|
34
|
+
h = Hash.new 0
|
35
|
+
@groups.each do |c|
|
36
|
+
c.processes.each do |p|
|
37
|
+
h[p.state] += 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
str = h.sort_by{|a,b| a}.map{|k, v| "#{k}:#{v}" } * ', '
|
41
|
+
{ name: @name, type: :application, state: str}
|
42
|
+
end
|
43
|
+
|
44
|
+
def debug_data
|
45
|
+
end
|
46
|
+
|
47
|
+
def send_command(command, *args)
|
48
|
+
debug "send_command #{command} #{args}"
|
49
|
+
|
50
|
+
@groups.each do |group|
|
51
|
+
group.send_command(command, *args)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def alive?
|
56
|
+
true # emulate celluloid actor method
|
57
|
+
end
|
58
|
+
|
59
|
+
def sub_object?(obj)
|
60
|
+
res = @groups.include?(obj)
|
61
|
+
res = @groups.any?{|gr| gr.sub_object?(obj)} if !res
|
62
|
+
res
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
data/lib/eye/checker.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
class Eye::Checker
|
2
|
+
include Eye::Logger::Helpers
|
3
|
+
|
4
|
+
autoload :Validation, 'eye/checker/validation'
|
5
|
+
|
6
|
+
autoload :Memory, 'eye/checker/memory'
|
7
|
+
autoload :Cpu, 'eye/checker/cpu'
|
8
|
+
autoload :Http, 'eye/checker/http'
|
9
|
+
autoload :FileCTime, 'eye/checker/file_ctime'
|
10
|
+
autoload :FileSize, 'eye/checker/file_size'
|
11
|
+
autoload :Socket, 'eye/checker/socket'
|
12
|
+
|
13
|
+
TYPES = {:memory => "Memory", :cpu => "Cpu", :http => "Http",
|
14
|
+
:ctime => "FileCTime", :fsize => "FileSize", :socket => "Socket"}
|
15
|
+
|
16
|
+
attr_accessor :value, :values, :options, :pid, :type
|
17
|
+
|
18
|
+
def self.get_class(type)
|
19
|
+
klass = eval("Eye::Checker::#{TYPES[type]}") rescue nil
|
20
|
+
raise "Unknown checker #{type}" unless klass
|
21
|
+
klass
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.create(pid, options = {}, logger_prefix = nil)
|
25
|
+
get_class(options[:type]).new(pid, options, logger_prefix)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.validate!(options)
|
29
|
+
get_class(options[:type]).validate(options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(pid, options = {}, logger_prefix = nil)
|
33
|
+
@pid = pid
|
34
|
+
@options = options
|
35
|
+
@type = options[:type]
|
36
|
+
|
37
|
+
@logger = Eye::Logger.new(logger_prefix, "check:#{check_name}")
|
38
|
+
debug "create checker, with #{options}"
|
39
|
+
|
40
|
+
@value = nil
|
41
|
+
@values = Eye::Utils::Tail.new(max_tries)
|
42
|
+
end
|
43
|
+
|
44
|
+
def last_human_values
|
45
|
+
h_values = @values.map do |v|
|
46
|
+
sign = v[:good] ? '' : '*'
|
47
|
+
sign + human_value(v[:value]).to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
'[' + h_values * ', ' + ']'
|
51
|
+
end
|
52
|
+
|
53
|
+
def check
|
54
|
+
@value = get_value
|
55
|
+
@values << {:value => @value, :good => good?(value)}
|
56
|
+
|
57
|
+
result = true
|
58
|
+
|
59
|
+
if @values.size == max_tries
|
60
|
+
bad_count = @values.count{|v| !v[:good] }
|
61
|
+
result = false if bad_count >= min_tries
|
62
|
+
end
|
63
|
+
|
64
|
+
info "#{last_human_values} => #{result ? 'OK' : 'Fail'}"
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_value
|
69
|
+
raise 'Realize me'
|
70
|
+
end
|
71
|
+
|
72
|
+
def human_value(value)
|
73
|
+
value.to_s
|
74
|
+
end
|
75
|
+
|
76
|
+
# true if check ok
|
77
|
+
# false if check bad
|
78
|
+
def good?(value)
|
79
|
+
raise 'Realize me'
|
80
|
+
end
|
81
|
+
|
82
|
+
def check_name
|
83
|
+
self.class.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
def max_tries
|
87
|
+
@max_tries ||= if times
|
88
|
+
if times.is_a?(Array)
|
89
|
+
times[-1].to_i
|
90
|
+
else
|
91
|
+
times.to_i
|
92
|
+
end
|
93
|
+
else
|
94
|
+
1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def min_tries
|
99
|
+
@min_tries ||= if times
|
100
|
+
if times.is_a?(Array)
|
101
|
+
times[0].to_i
|
102
|
+
else
|
103
|
+
max_tries
|
104
|
+
end
|
105
|
+
else
|
106
|
+
max_tries
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def previous_value
|
111
|
+
@values[-1][:value] if @values.present?
|
112
|
+
end
|
113
|
+
|
114
|
+
extend Eye::Checker::Validation
|
115
|
+
param :every, [Fixnum, Float], false, 5
|
116
|
+
param :times, [Fixnum, Array]
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Eye::Checker::Cpu < Eye::Checker
|
2
|
+
|
3
|
+
# checks :cpu, :every => 3.seconds, :below => 80, :times => [3,5]
|
4
|
+
|
5
|
+
param :below, [Fixnum, Float], true
|
6
|
+
|
7
|
+
def check_name
|
8
|
+
"cpu(#{human_value(below)})"
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_value
|
12
|
+
Eye::SystemResources.cpu(@pid).to_i # nil => 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def human_value(value)
|
16
|
+
"#{value}%"
|
17
|
+
end
|
18
|
+
|
19
|
+
def good?(value)
|
20
|
+
if below
|
21
|
+
value < below
|
22
|
+
else
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Eye::Checker::FileCTime < Eye::Checker
|
2
|
+
|
3
|
+
# Check that file changes (log for example)
|
4
|
+
|
5
|
+
# checks :ctime, :every => 5.seconds, :file => "/tmp/1.log", :times => [3,5]
|
6
|
+
|
7
|
+
param :file, [String], true
|
8
|
+
|
9
|
+
def check_name
|
10
|
+
'ctime'
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_value
|
14
|
+
File.ctime(file) rescue nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def human_value(value)
|
18
|
+
if value == nil
|
19
|
+
'Err'
|
20
|
+
else
|
21
|
+
value.strftime('%H:%M')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def good?(value)
|
26
|
+
value.to_i > previous_value.to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Eye::Checker::FileSize < Eye::Checker
|
2
|
+
|
3
|
+
# Check that file size changed (log for example)
|
4
|
+
|
5
|
+
# checks :fsize, :every => 5.seconds, :file => "/tmp/1.log", :times => [3,5],
|
6
|
+
# :below => 30.kilobytes, :above => 10.kilobytes
|
7
|
+
|
8
|
+
param :file, [String], true
|
9
|
+
param :below, [Fixnum, Float]
|
10
|
+
param :above, [Fixnum, Float]
|
11
|
+
|
12
|
+
def check_name
|
13
|
+
'fsize'
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_value
|
17
|
+
File.size(file) rescue nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def human_value(value)
|
21
|
+
"#{value.to_i / 1024}Kb"
|
22
|
+
end
|
23
|
+
|
24
|
+
def good?(value)
|
25
|
+
return true unless previous_value
|
26
|
+
|
27
|
+
diff = value.to_i - previous_value.to_i
|
28
|
+
|
29
|
+
return true if diff < 0 # case when logger nulled
|
30
|
+
|
31
|
+
return false if below && diff > below
|
32
|
+
return false if above && diff < above
|
33
|
+
return false if diff == 0
|
34
|
+
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
class Eye::Checker::Http < Eye::Checker
|
4
|
+
|
5
|
+
# checks :http, :every => 5.seconds, :times => 1,
|
6
|
+
# :url => "http://127.0.0.1:3000/", :kind => :success, :pattern => /OK/, :timeout => 3.seconds
|
7
|
+
|
8
|
+
param :url, String, true
|
9
|
+
param :pattern, [String, Regexp]
|
10
|
+
param :kind
|
11
|
+
param :timeout, [Fixnum, Float]
|
12
|
+
param :open_timeout, [Fixnum, Float]
|
13
|
+
param :read_timeout, [Fixnum, Float]
|
14
|
+
|
15
|
+
attr_reader :session, :uri
|
16
|
+
|
17
|
+
def check_name
|
18
|
+
'http'
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(*args)
|
22
|
+
super
|
23
|
+
|
24
|
+
@uri = URI.parse(url) rescue URI.parse('http://127.0.0.1')
|
25
|
+
@pattern = pattern
|
26
|
+
@kind = case kind
|
27
|
+
when Fixnum then Net::HTTPResponse::CODE_TO_OBJ[kind]
|
28
|
+
when String, Symbol then Net.const_get("HTTP#{kind.to_s.camelize}") rescue Net::HTTPSuccess
|
29
|
+
else
|
30
|
+
Net::HTTPSuccess
|
31
|
+
end
|
32
|
+
@open_timeout = (open_timeout || timeout || 5).to_i
|
33
|
+
@read_timeout = (read_timeout || timeout || 30).to_i
|
34
|
+
|
35
|
+
@session = Net::HTTP.new(@uri.host, @uri.port)
|
36
|
+
if @uri.scheme == 'https'
|
37
|
+
require 'net/https'
|
38
|
+
@session.use_ssl=true
|
39
|
+
@session.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
40
|
+
end
|
41
|
+
@session.open_timeout = @open_timeout
|
42
|
+
@session.read_timeout = @read_timeout
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_value
|
46
|
+
Celluloid::Future.new{ get_value_sync }.value
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_value_sync
|
50
|
+
res = @session.start do |http|
|
51
|
+
http.get(@uri.path)
|
52
|
+
end
|
53
|
+
|
54
|
+
{:result => res}
|
55
|
+
|
56
|
+
rescue Timeout::Error
|
57
|
+
debug 'Timeout error'
|
58
|
+
{:exception => :timeout}
|
59
|
+
|
60
|
+
rescue => ex
|
61
|
+
error "Exception #{ex.message}"
|
62
|
+
{:exception => ex.message}
|
63
|
+
end
|
64
|
+
|
65
|
+
def good?(value)
|
66
|
+
return false unless value[:result]
|
67
|
+
return false unless value[:result].kind_of?(@kind)
|
68
|
+
|
69
|
+
if @pattern
|
70
|
+
if @pattern.is_a?(Regexp)
|
71
|
+
@pattern === value[:result].body
|
72
|
+
else
|
73
|
+
value[:result].body.include?(@pattern.to_s)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def human_value(value)
|
81
|
+
if !value.is_a?(Hash)
|
82
|
+
'-'
|
83
|
+
elsif value[:exception]
|
84
|
+
if value[:exception] == :timeout
|
85
|
+
'T-out'
|
86
|
+
else
|
87
|
+
'Err'
|
88
|
+
end
|
89
|
+
else
|
90
|
+
"#{value[:result].code}=#{value[:result].body.size/ 1024}Kb"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Eye::Checker::Memory < Eye::Checker
|
2
|
+
|
3
|
+
# checks :memory, :every => 3.seconds, :below => 80.megabytes, :times => [3,5]
|
4
|
+
|
5
|
+
param :below, [Fixnum, Float], true
|
6
|
+
|
7
|
+
def check_name
|
8
|
+
"memory(#{human_value(below)})"
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_value
|
12
|
+
Eye::SystemResources.memory(@pid).to_i * 1024
|
13
|
+
end
|
14
|
+
|
15
|
+
def human_value(value)
|
16
|
+
"#{value.to_i / 1024 / 1024}Mb"
|
17
|
+
end
|
18
|
+
|
19
|
+
def good?(value)
|
20
|
+
if below
|
21
|
+
value < below
|
22
|
+
else
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
class Eye::Checker::Socket < Eye::Checker
|
2
|
+
|
3
|
+
# checks :socket, :every => 5.seconds, :times => 1,
|
4
|
+
# :addr => "unix:/var/run/daemon.sock", :timeout => 3.seconds,
|
5
|
+
#
|
6
|
+
# Available parameters:
|
7
|
+
# :addr the socket addr to open. The format is tcp://<host>:<port> or unix:<path>
|
8
|
+
# :timeout generic timeout for opening the socket or reading data
|
9
|
+
# :open_timeout override generic timeout for the connection
|
10
|
+
# :read_timeout override generic timeout for data read/write
|
11
|
+
# :send_data after connection send this data
|
12
|
+
# :expect_data after sending :send_data expect this response. Can be a string, Regexp or a Proc
|
13
|
+
# :protocol way of pack,unpack messages (default = socket default), example: :protocol => :em_object
|
14
|
+
|
15
|
+
param :addr, String, true
|
16
|
+
param :timeout, [Fixnum, Float]
|
17
|
+
param :open_timeout, [Fixnum, Float]
|
18
|
+
param :read_timeout, [Fixnum, Float]
|
19
|
+
param :send_data
|
20
|
+
param :expect_data, [String, Regexp, Proc]
|
21
|
+
param :protocol, [Symbol]
|
22
|
+
|
23
|
+
def check_name
|
24
|
+
'socket'
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(*args)
|
28
|
+
super
|
29
|
+
@open_timeout = (open_timeout || 1).to_i
|
30
|
+
@read_timeout = (read_timeout || timeout || 5).to_i
|
31
|
+
|
32
|
+
if addr =~ %r[\Atcp://(.*?):(.*?)\z]
|
33
|
+
@socket_family = :tcp
|
34
|
+
@socket_addr = $1
|
35
|
+
@socket_port = $2.to_i
|
36
|
+
elsif addr =~ %r[\Aunix:(.*)\z]
|
37
|
+
@socket_family = :unix
|
38
|
+
@socket_path = $1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_value
|
43
|
+
Celluloid::Future.new{ get_value_sync }.value
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_value_sync
|
47
|
+
sock = Timeout::timeout(@open_timeout) do
|
48
|
+
if @socket_family == :tcp
|
49
|
+
TCPSocket.open(@socket_addr, @socket_port)
|
50
|
+
elsif @socket_family == :unix
|
51
|
+
UNIXSocket.open(@socket_path)
|
52
|
+
else
|
53
|
+
raise "Unknown socket addr #{addr}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if send_data
|
58
|
+
Timeout::timeout(@read_timeout) do
|
59
|
+
_write_data(sock, send_data)
|
60
|
+
{ :result => _read_data(sock) }
|
61
|
+
end
|
62
|
+
else
|
63
|
+
{ :result => :listen }
|
64
|
+
end
|
65
|
+
|
66
|
+
rescue Timeout::Error
|
67
|
+
debug 'Timeout error'
|
68
|
+
{ :exception => :timeout }
|
69
|
+
|
70
|
+
rescue Exception => e
|
71
|
+
warn "Exception #{e.message}"
|
72
|
+
{ :exception => e.message }
|
73
|
+
|
74
|
+
ensure
|
75
|
+
sock.close if sock
|
76
|
+
end
|
77
|
+
|
78
|
+
def good?(value)
|
79
|
+
return false if !value[:result]
|
80
|
+
|
81
|
+
if expect_data
|
82
|
+
if expect_data.is_a?(Proc)
|
83
|
+
match = begin
|
84
|
+
!!expect_data[value[:result]]
|
85
|
+
rescue Timeout::Error, Exception => ex
|
86
|
+
error "proc match failed with #{ex.message}"
|
87
|
+
return false
|
88
|
+
end
|
89
|
+
|
90
|
+
warn "proc #{expect_data} not matched (#{value[:result].truncate(30)}) answer" unless match
|
91
|
+
return match
|
92
|
+
end
|
93
|
+
|
94
|
+
return true if expect_data.is_a?(Regexp) && expect_data.match(value[:result])
|
95
|
+
return true if value[:result].to_s == expect_data.to_s
|
96
|
+
|
97
|
+
warn "#{expect_data} not matched (#{value[:result].truncate(30)}) answer"
|
98
|
+
return false
|
99
|
+
end
|
100
|
+
|
101
|
+
return true
|
102
|
+
end
|
103
|
+
|
104
|
+
def human_value(value)
|
105
|
+
if !value.is_a?(Hash)
|
106
|
+
'-'
|
107
|
+
elsif value[:exception]
|
108
|
+
if value[:exception] == :timeout
|
109
|
+
'T-out'
|
110
|
+
else
|
111
|
+
"Err(#{value[:exception]})"
|
112
|
+
end
|
113
|
+
else
|
114
|
+
if value[:result] == :listen
|
115
|
+
"listen"
|
116
|
+
else
|
117
|
+
"#{value[:result].to_s.size}b"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def _write_data(socket, data)
|
125
|
+
case protocol
|
126
|
+
when :em_object
|
127
|
+
data = Marshal.dump(data)
|
128
|
+
socket.write([data.bytesize, data].pack('Na*'))
|
129
|
+
else
|
130
|
+
socket.write(data.to_s)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def _read_data(socket)
|
135
|
+
case protocol
|
136
|
+
when :em_object
|
137
|
+
content = ""
|
138
|
+
msg_size = socket.recv(4).unpack('N')[0] rescue 0
|
139
|
+
content << socket.recv(msg_size - content.length) while content.length < msg_size
|
140
|
+
if content.present?
|
141
|
+
Marshal.load(content) rescue 'corrupted_marshal'
|
142
|
+
end
|
143
|
+
else
|
144
|
+
socket.readline.chop
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|