dosire-god 0.7.10 → 0.7.12
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/lib/god.rb +2 -1
- data/lib/god/conditions/http_response_body.rb +165 -0
- metadata +2 -1
data/lib/god.rb
CHANGED
@@ -46,7 +46,8 @@ require 'god/conditions/always'
|
|
46
46
|
require 'god/conditions/lambda'
|
47
47
|
require 'god/conditions/degrading_lambda'
|
48
48
|
require 'god/conditions/flapping'
|
49
|
-
require 'god/conditions/http_response_code'
|
49
|
+
require 'god/conditions/http_response_code'
|
50
|
+
require 'god/conditions/http_response_body'
|
50
51
|
require 'god/conditions/disk_usage'
|
51
52
|
require 'god/conditions/complex'
|
52
53
|
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module God
|
4
|
+
module Conditions
|
5
|
+
|
6
|
+
# Condition Symbol :http_response_code
|
7
|
+
# Type: Poll
|
8
|
+
#
|
9
|
+
# Trigger based on the body of an HTTP response.
|
10
|
+
#
|
11
|
+
# Paramaters
|
12
|
+
# Required
|
13
|
+
# +host+ is the hostname to connect [required]
|
14
|
+
# --one of code_is or code_is_not--
|
15
|
+
# +code_is+ trigger if the response code matches this string
|
16
|
+
# e.g. '500'
|
17
|
+
# +code_is_not+ trigger if the response code does not match this string
|
18
|
+
# e.g. '200'
|
19
|
+
# Optional
|
20
|
+
# +port+ is the port to connect (default 80)
|
21
|
+
# +path+ is the path to connect (default '/')
|
22
|
+
# +headers+ is the hash of HTTP headers to send (default none)
|
23
|
+
# +times+ is the number of times after which to trigger (default 1)
|
24
|
+
# e.g. 3 (times in a row) or [3, 5] (three out of fives times)
|
25
|
+
# +timeout+ is the time to wait for a connection (default 60.seconds)
|
26
|
+
#
|
27
|
+
# Examples
|
28
|
+
#
|
29
|
+
# Trigger if the response code from www.example.com/foo/bar
|
30
|
+
# is not a 200 (or if the connection is refused or times out:
|
31
|
+
#
|
32
|
+
# on.condition(:http_response_code) do |c|
|
33
|
+
# c.host = 'www.example.com'
|
34
|
+
# c.path = '/foo/bar'
|
35
|
+
# c.code_is_not = 200
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Trigger if the response code is a 404 or a 500 (will not
|
39
|
+
# be triggered by a connection refusal or timeout):
|
40
|
+
#
|
41
|
+
# on.condition(:http_response_code) do |c|
|
42
|
+
# c.host = 'www.example.com'
|
43
|
+
# c.path = '/foo/bar'
|
44
|
+
# c.code_is = [404, 500]
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# Trigger if the response code is not a 200 five times in a row:
|
48
|
+
#
|
49
|
+
# on.condition(:http_response_code) do |c|
|
50
|
+
# c.host = 'www.example.com'
|
51
|
+
# c.path = '/foo/bar'
|
52
|
+
# c.code_is_not = 200
|
53
|
+
# c.times = 5
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# Trigger if the response code is not a 200 or does not respond
|
57
|
+
# within 10 seconds:
|
58
|
+
#
|
59
|
+
# on.condition(:http_response_code) do |c|
|
60
|
+
# c.host = 'www.example.com'
|
61
|
+
# c.path = '/foo/bar'
|
62
|
+
# c.code_is_not = 200
|
63
|
+
# c.timeout = 10
|
64
|
+
# end
|
65
|
+
class HttpResponseBody < PollCondition
|
66
|
+
attr_accessor :code_is, # e.g. 500 or '500' or [404, 500] or %w{404 500}
|
67
|
+
:code_is_not, # e.g. 200 or '200' or [200, 302] or %w{200 302}
|
68
|
+
:times, # e.g. 3 or [3, 5]
|
69
|
+
:host, # e.g. www.example.com
|
70
|
+
:port, # e.g. 8080
|
71
|
+
:timeout, # e.g. 60.seconds
|
72
|
+
:path, # e.g. '/'
|
73
|
+
:headers # e.g. {'Host' => 'myvirtual.mydomain.com'}
|
74
|
+
|
75
|
+
def initialize
|
76
|
+
super
|
77
|
+
self.port = 80
|
78
|
+
self.path = '/'
|
79
|
+
self.headers = {}
|
80
|
+
self.times = [1, 1]
|
81
|
+
self.timeout = 60.seconds
|
82
|
+
end
|
83
|
+
|
84
|
+
def prepare
|
85
|
+
if self.times.kind_of?(Integer)
|
86
|
+
self.times = [self.times, self.times]
|
87
|
+
end
|
88
|
+
|
89
|
+
@timeline = Timeline.new(self.times[1])
|
90
|
+
@history = Timeline.new(self.times[1])
|
91
|
+
end
|
92
|
+
|
93
|
+
def reset
|
94
|
+
@timeline.clear
|
95
|
+
@history.clear
|
96
|
+
end
|
97
|
+
|
98
|
+
def valid?
|
99
|
+
valid = true
|
100
|
+
valid &= complain("Attribute 'host' must be specified", self) if self.host.nil?
|
101
|
+
valid &= complain("One (and only one) of attributes 'code_is' and 'code_is_not' must be specified", self) if
|
102
|
+
(self.code_is.nil? && self.code_is_not.nil?) || (self.code_is && self.code_is_not)
|
103
|
+
valid
|
104
|
+
end
|
105
|
+
|
106
|
+
def test
|
107
|
+
response = nil
|
108
|
+
|
109
|
+
Net::HTTP.start(self.host, self.port) do |http|
|
110
|
+
http.read_timeout = self.timeout
|
111
|
+
response = http.get(self.path)
|
112
|
+
end
|
113
|
+
|
114
|
+
actual_response_code = response.body[5,10].to_s
|
115
|
+
if self.code_is && actual_response_code.include?(self.code_is)
|
116
|
+
pass(actual_response_code)
|
117
|
+
elsif self.code_is_not && !actual_response_code.include?(self.code_is_not)
|
118
|
+
pass(actual_response_code)
|
119
|
+
else
|
120
|
+
fail(actual_response_code)
|
121
|
+
end
|
122
|
+
rescue Errno::ECONNREFUSED
|
123
|
+
self.code_is ? fail('Refused') : pass('Refused')
|
124
|
+
rescue Errno::ECONNRESET
|
125
|
+
self.code_is ? fail('Reset') : pass('Reset')
|
126
|
+
rescue EOFError
|
127
|
+
self.code_is ? fail('EOF') : pass('EOF')
|
128
|
+
rescue Timeout::Error
|
129
|
+
self.code_is ? fail('Timeout') : pass('Timeout')
|
130
|
+
rescue Errno::ETIMEDOUT
|
131
|
+
self.code_is ? fail('Timedout') : pass('Timedout')
|
132
|
+
rescue Exception => failure
|
133
|
+
self.code_is ? fail(failure.class.name) : pass(failure.class.name)
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def pass(code)
|
139
|
+
@timeline << true
|
140
|
+
if @timeline.select { |x| x }.size >= self.times.first
|
141
|
+
self.info = "http response abnormal #{history(code, true)}"
|
142
|
+
true
|
143
|
+
else
|
144
|
+
self.info = "http response nominal #{history(code, true)}"
|
145
|
+
false
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def fail(code)
|
150
|
+
@timeline << false
|
151
|
+
self.info = "http response nominal #{history(code, false)}"
|
152
|
+
false
|
153
|
+
end
|
154
|
+
|
155
|
+
def history(code, passed)
|
156
|
+
entry = code.to_s.dup
|
157
|
+
entry = '*' + entry if passed
|
158
|
+
@history << entry
|
159
|
+
'[' + @history.join(", ") + ']'
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dosire-god
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Preston-Werner
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- lib/god/conditions/disk_usage.rb
|
53
53
|
- lib/god/conditions/flapping.rb
|
54
54
|
- lib/god/conditions/http_response_code.rb
|
55
|
+
- lib/god/conditions/http_response_body.rb
|
55
56
|
- lib/god/conditions/lambda.rb
|
56
57
|
- lib/god/conditions/memory_usage.rb
|
57
58
|
- lib/god/conditions/process_exits.rb
|