dosire-god 0.7.10 → 0.7.12

Sign up to get free protection for your applications and to get access to all the features.
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.10
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