failbot 1.1.5 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90628071f00b062ad9f21fae9244d905c2f38ceb
4
- data.tar.gz: d54bf144087e7a9bac861e838faa7e64ccc7deb8
3
+ metadata.gz: 2c43604c17fd3f70e059393df33105ff1859a525
4
+ data.tar.gz: b6001b69118747ba9a4f852b8cb06411aa7ccddb
5
5
  SHA512:
6
- metadata.gz: 851ec7c6a661593e9edc3ffee53799c3ceab8cde34c14a0109f8ecbdb84e95f38a304600f1671d9b2a720ccf2e09a8857d75426bff3d5197fd9d5b71182f2759
7
- data.tar.gz: f47a0e5f9f083b44380f76818392e8e98bc61fc19d7871c71d205c0e92006598b3283c58ab868c243b41efc858e2fb620d566a046f177d14497b76223deeaf35
6
+ metadata.gz: 74a8815c07c15e8df64e60e278140b7c85ad46f354ac514a31f5f27bbeee625f8f8abc7efdcd3c6290bcfbc86d02494e78f1d87a8b3e2281313bd75132a80263
7
+ data.tar.gz: f43c79a47c6c371dd3c7c8581a13fce6dffd3b7a31c29a8e521bdcba457b15a44152b4474988b5f993a56de41dfe53e843af4a6184a48fe0f46a38c7bbc0b66d
data/lib/failbot.rb CHANGED
@@ -17,7 +17,6 @@ module Failbot
17
17
  autoload :Haystack, 'failbot/haystack'
18
18
 
19
19
  autoload :FileBackend, 'failbot/file_backend'
20
- autoload :HerokuBackend, 'failbot/heroku_backend'
21
20
  autoload :HTTPBackend, 'failbot/http_backend'
22
21
  autoload :MemoryBackend, 'failbot/memory_backend'
23
22
  autoload :JSONBackend, 'failbot/json_backend'
@@ -126,6 +125,29 @@ module Failbot
126
125
  @context = [context[0]]
127
126
  end
128
127
 
128
+ # Public: your last chance to modify the context that is to be reported with an exception.
129
+ #
130
+ # The key value pairs that are returned from your block will get squashed into the context,
131
+ # replacing the values of any keys that were already present.
132
+ #
133
+ # Example:
134
+ #
135
+ # Failbot.before_report do |exception, context|
136
+ # # context is { "a" => 1, "b" => 2 }
137
+ # { :a => 0, :c => 3 }
138
+ # end
139
+ #
140
+ # context gets reported as { "a" => 0, "b" => "2", "c" => 3 }
141
+ #
142
+ def before_report(&block)
143
+ @before_report = block
144
+ end
145
+
146
+ # For tests
147
+ def clear_before_report
148
+ @before_report = nil
149
+ end
150
+
129
151
  # Public: Sends an exception to the exception tracking service along
130
152
  # with a hash of custom attributes to be included with the report. When the
131
153
  # raise_errors option is set, this method raises the exception instead of
@@ -145,7 +167,7 @@ module Failbot
145
167
  # Returns nothing.
146
168
  def report(e, other = {})
147
169
  if @raise_errors
148
- squash_context(exception_info(e), other) # surface problems squashing
170
+ squash_contexts(context, exception_info(e), other) # surface problems squashing
149
171
  raise e
150
172
  else
151
173
  report!(e, other)
@@ -154,7 +176,17 @@ module Failbot
154
176
 
155
177
  def report!(e, other = {})
156
178
  return unless @report_errors
157
- data = squash_context(exception_info(e), other)
179
+ data = squash_contexts(context, exception_info(e), other)
180
+
181
+ if @before_report
182
+ data = squash_contexts(data, @before_report.call(e, data))
183
+ end
184
+
185
+ if @app_override
186
+ data = data.merge("app" => @app_override)
187
+ end
188
+
189
+ data = sanitize(data)
158
190
 
159
191
  if already_reporting
160
192
  logger.warn "FAILBOT: asked to report while reporting! #{data.inspect}" rescue nil
@@ -222,28 +254,39 @@ module Failbot
222
254
  # stack hashes.
223
255
  #
224
256
  # Returns a Hash with all keys and values.
225
- def squash_context(*other)
226
- merged = {}
227
- (context + other).each do |hash|
257
+ def squash_contexts(*contexts_to_squash)
258
+ squashed = {}
259
+
260
+ contexts_to_squash.flatten.each do |hash|
228
261
  hash.each do |key, value|
229
262
  value = (value.call rescue nil) if value.kind_of?(Proc)
230
- merged[key.to_s] =
231
- case value
232
- when Time
233
- value.iso8601
234
- when Date
235
- value.strftime("%F") # equivalent to %Y-%m-%d
236
- when Numeric
237
- value
238
- when String, true, false
239
- value.to_s
240
- else
241
- value.inspect
242
- end
263
+ squashed[key.to_s] = value
243
264
  end
244
265
  end
245
- merged["app"] = @app_override if @app_override
246
- merged
266
+
267
+ squashed
268
+ end
269
+
270
+ def sanitize(attrs)
271
+ result = {}
272
+
273
+ attrs.each do |key, value|
274
+ result[key] =
275
+ case value
276
+ when Time
277
+ value.iso8601
278
+ when Date
279
+ value.strftime("%F") # equivalent to %Y-%m-%d
280
+ when Numeric
281
+ value
282
+ when String, true, false
283
+ value.to_s
284
+ else
285
+ value.inspect
286
+ end
287
+ end
288
+
289
+ result
247
290
  end
248
291
 
249
292
  # Extract exception info into a simple Hash.
@@ -40,8 +40,6 @@ module Failbot
40
40
  # memory - Dummy backend that simply save exceptions in memory. Typically
41
41
  # used in testing environments.
42
42
  #
43
- # heroku - In-process posting for outside of vpn apps
44
- #
45
43
  # file - Append JSON-encoded exceptions to a file.
46
44
  #
47
45
  # Returns the String backend name. See also `Failbot.backend`.
@@ -108,12 +106,6 @@ module Failbot
108
106
  Failbot::MemoryBackend.new
109
107
  when 'file'
110
108
  Failbot::FileBackend.new(config['file_path'])
111
- when 'heroku', 'http'
112
- if backend_name == "heroku"
113
- warn "The Failbot \"heroku\" backend is deprecated. Use \"http\" " \
114
- "instead. #{caller[1]}"
115
- end
116
- Failbot::HerokuBackend.new(config['haystack'])
117
109
  else
118
110
  raise ArgumentError, "Unknown backend: #{backend_name.inspect}"
119
111
  end
@@ -23,5 +23,9 @@ module Failbot
23
23
  end
24
24
  reports
25
25
  end
26
+
27
+ def ping
28
+ raise StandardError, "cannot write to #{@path}" unless File.writable?(@path)
29
+ end
26
30
  end
27
31
  end
@@ -20,9 +20,28 @@ module Failbot
20
20
  # make a post
21
21
  post = Net::HTTP::Post.new(@url.path)
22
22
  post.set_form_data('json' => Yajl.dump(data))
23
+ response = send_request(post)
23
24
 
25
+ # Raise if the exception doesn't make it to Haystack, ensures the failure
26
+ # is logged
27
+ raise StandardError, "couldn't send exception to Haystack" unless response.code == "201"
28
+ end
29
+
30
+ def self.send_data(data)
31
+ new(Failbot.haystack).send_data(data)
32
+ end
33
+
34
+ def ping
35
+ request = Net::HTTP::Head.new('/')
36
+ response = send_request(request)
37
+ raise StandardError, "haystack returned #{response.code}" unless response.code == "200"
38
+ end
39
+
40
+ private
41
+
42
+ def send_request(request)
24
43
  if user && password
25
- post.basic_auth(user, password)
44
+ request.basic_auth(user, password)
26
45
  end
27
46
 
28
47
  # make request
@@ -32,15 +51,7 @@ module Failbot
32
51
  http.use_ssl = true if @url.scheme == "https"
33
52
 
34
53
  # push it through
35
- response = http.request(post)
36
-
37
- # Raise if the exception doesn't make it to Haystack, ensures the failure
38
- # is logged
39
- raise StandardError, "couldn't send exception to Haystack" unless response.code == "201"
40
- end
41
-
42
- def self.send_data(data)
43
- new(Failbot.haystack).send_data(data)
54
+ http.request(request)
44
55
  end
45
56
  end
46
57
  end
@@ -15,5 +15,9 @@ module Failbot
15
15
  def reports
16
16
  []
17
17
  end
18
+
19
+ def ping
20
+ @haystack.ping
21
+ end
18
22
  end
19
23
  end
@@ -15,14 +15,46 @@ module Failbot
15
15
  end
16
16
 
17
17
  def report(data)
18
- @socket = TCPSocket.new @host, @port
19
18
  payload = Yajl.dump(data)
20
- @socket.send(payload, 0)
21
- @socket.close
19
+
20
+ response = socket do |s|
21
+ s.send(payload, 0)
22
+ nil
23
+ end
22
24
  end
23
25
 
24
26
  def reports
25
27
  raise NotImplementedError
26
28
  end
29
+
30
+ def ping
31
+ response = socket do |s|
32
+ s.send("PING", 0)
33
+ s.close_write
34
+ s.read
35
+ end
36
+
37
+ raise StandardError, "failbotd didn't respond to PING, #{response} returned" unless response.start_with?("PONG")
38
+ end
39
+
40
+ private
41
+
42
+ # Connect to failbotd and yield the connection.
43
+ #
44
+ # Messages are framed by closing the write end of the socket, both ends of
45
+ # the socket are closed upon return from the block.
46
+ #
47
+ # block :: TCPSocket -> AnyType
48
+ # A block invoked invoked with an open socket to failbotd. The
49
+ # return value is returned from this method.
50
+ #
51
+ # Returns the return value of the block.
52
+ def socket(&block)
53
+ socket = TCPSocket.new @host, @port
54
+ response = yield socket
55
+ response
56
+ ensure
57
+ socket.close
58
+ end
27
59
  end
28
60
  end
@@ -18,5 +18,9 @@ module Failbot
18
18
 
19
19
  @reports << data
20
20
  end
21
+
22
+ def ping
23
+ # nop
24
+ end
21
25
  end
22
26
  end
@@ -35,7 +35,7 @@ module Failbot
35
35
  :method => request.request_method,
36
36
  :user_agent => env['HTTP_USER_AGENT'],
37
37
  :params => filtered_parameters(env, params),
38
- :session => (request.session.to_hash rescue nil),
38
+ :session => filtered_parameters(env, (request.session.to_hash rescue {})),
39
39
  :referrer => request.referrer,
40
40
  :remote_ip => request.ip,
41
41
  :url => request.url
@@ -1,3 +1,3 @@
1
1
  module Failbot
2
- VERSION = "1.1.5"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: failbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "@rtomayko"
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-05-26 00:00:00.000000000 Z
13
+ date: 2015-08-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: yajl-ruby
@@ -81,7 +81,6 @@ files:
81
81
  - lib/failbot/failbot.yml
82
82
  - lib/failbot/file_backend.rb
83
83
  - lib/failbot/haystack.rb
84
- - lib/failbot/heroku_backend.rb
85
84
  - lib/failbot/http_backend.rb
86
85
  - lib/failbot/json_backend.rb
87
86
  - lib/failbot/memory_backend.rb
@@ -1,15 +0,0 @@
1
- module Failbot
2
- class HerokuBackend
3
- def initialize(url)
4
- @hubble = Failbot::Haystack.new(url)
5
- end
6
-
7
- def report(data)
8
- @hubble.send_data(data)
9
- end
10
-
11
- def reports
12
- []
13
- end
14
- end
15
- end