sentry-raven 2.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/raven/base.rb +8 -0
- data/lib/raven/configuration.rb +12 -3
- data/lib/raven/context.rb +27 -6
- data/lib/raven/event.rb +42 -24
- data/lib/raven/integrations/sidekiq.rb +47 -41
- data/lib/raven/{interfaces.rb → interface.rb} +8 -15
- data/lib/raven/interfaces/exception.rb +5 -4
- data/lib/raven/interfaces/http.rb +6 -11
- data/lib/raven/interfaces/message.rb +10 -6
- data/lib/raven/interfaces/single_exception.rb +1 -1
- data/lib/raven/interfaces/stack_trace.rb +5 -4
- data/lib/raven/transports/http.rb +2 -0
- data/lib/raven/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca26b5db2081fdbbdc2d2de7bbd580f1efcbd3f2
|
4
|
+
data.tar.gz: b95c0447aa43feb90d16585803a8815e218390c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49d734c72e306caf5e6a760ee9e76e787eb865f33542929b43ee244b7596607b7f9a13b1d77f531d25de4d09a04d15ca87fab96438379a4fc621b17f8e9c0959
|
7
|
+
data.tar.gz: 9c299e76d4f1081225fd7950a09434564bc4a805bc77673efe2a501af4446297c876bc68edd88267d429d35fa1ac20f24903c0193393b7ec0e85e07f3c9b36c5
|
data/lib/raven/base.rb
CHANGED
@@ -90,5 +90,13 @@ module Raven
|
|
90
90
|
opts[:to].send(:include, opts[:from].const_get("Old" + module_name))
|
91
91
|
end
|
92
92
|
end
|
93
|
+
|
94
|
+
def sys_command(unix_command, win_command = nil)
|
95
|
+
unix_result = `#{unix_command} 2>&1` rescue nil # redirect stderr to stdout
|
96
|
+
return unix_result if unix_result != "" && unix_result
|
97
|
+
return if win_command.nil?
|
98
|
+
win_result = `#{win_command}` rescue nil
|
99
|
+
win_result != "" && win_result
|
100
|
+
end
|
93
101
|
end
|
94
102
|
end
|
data/lib/raven/configuration.rb
CHANGED
@@ -267,15 +267,24 @@ module Raven
|
|
267
267
|
end
|
268
268
|
|
269
269
|
def detect_release
|
270
|
-
|
270
|
+
detect_release_from_git ||
|
271
271
|
detect_release_from_capistrano ||
|
272
|
-
|
272
|
+
detect_release_from_heroku
|
273
273
|
end
|
274
274
|
|
275
275
|
private
|
276
276
|
|
277
277
|
def detect_release_from_heroku
|
278
|
-
|
278
|
+
sys_dyno_info = File.read("/etc/heroku/dyno").strip if File.directory?("/etc/heroku") rescue nil
|
279
|
+
return unless sys_dyno_info
|
280
|
+
|
281
|
+
# being overly cautious, because if we raise an error Raven won't start
|
282
|
+
begin
|
283
|
+
hash = JSON.parse(sys_dyno_info)
|
284
|
+
hash && hash["release"] && hash["release"]["commit"]
|
285
|
+
rescue JSON::JSONError
|
286
|
+
Raven.logger.error "Cannot parse Heroku JSON: #{sys_dyno_info}"
|
287
|
+
end
|
279
288
|
end
|
280
289
|
|
281
290
|
def detect_release_from_capistrano
|
data/lib/raven/context.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
1
3
|
module Raven
|
2
4
|
class Context
|
3
5
|
def self.current
|
@@ -8,14 +10,33 @@ module Raven
|
|
8
10
|
Thread.current[:sentry_context] = nil
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
attr_accessor :rack_env, :user
|
13
|
+
attr_accessor :extra, :os, :rack_env, :runtime, :tags, :user
|
13
14
|
|
14
15
|
def initialize
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
self.extra = {}
|
17
|
+
self.os = self.class.os_context
|
18
|
+
self.rack_env = nil
|
19
|
+
self.runtime = self.class.runtime_context
|
20
|
+
self.tags = {}
|
21
|
+
self.user = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def os_context
|
26
|
+
@os_context ||= {
|
27
|
+
"name" => Raven.sys_command("uname -s") || RbConfig::CONFIG["host_os"],
|
28
|
+
"version" => Raven.sys_command("uname -v"),
|
29
|
+
"build" => Raven.sys_command("uname -r"),
|
30
|
+
"kernel_version" => Raven.sys_command("uname -a", "ver")
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def runtime_context
|
35
|
+
@runtime_context ||= {
|
36
|
+
"name" => RbConfig::CONFIG["ruby_install_name"],
|
37
|
+
"version" => Raven.sys_command("ruby -v")
|
38
|
+
}
|
39
|
+
end
|
19
40
|
end
|
20
41
|
end
|
21
42
|
end
|
data/lib/raven/event.rb
CHANGED
@@ -21,11 +21,12 @@ module Raven
|
|
21
21
|
BACKTRACE_RE = /^(.+?):(\d+)(?::in `(.+?)')?$/
|
22
22
|
|
23
23
|
PLATFORM = "ruby".freeze
|
24
|
+
SDK = { "name" => "sentry-raven", "version" => Raven::VERSION }.freeze
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
:
|
28
|
-
:
|
26
|
+
attr_accessor :id, :timestamp, :time_spent, :level, :logger,
|
27
|
+
:culprit, :server_name, :release, :modules, :extra, :tags,
|
28
|
+
:context, :configuration, :checksum, :fingerprint, :environment,
|
29
|
+
:os, :runtime, :breadcrumbs, :user, :backtrace
|
29
30
|
|
30
31
|
def initialize(init = {})
|
31
32
|
@configuration = Raven.configuration
|
@@ -33,8 +34,6 @@ module Raven
|
|
33
34
|
@breadcrumbs = Raven.breadcrumbs
|
34
35
|
@context = Raven.context
|
35
36
|
@id = SecureRandom.uuid.delete("-")
|
36
|
-
@project = nil
|
37
|
-
@message = nil
|
38
37
|
@timestamp = Time.now.utc
|
39
38
|
@time_spent = nil
|
40
39
|
@level = :error
|
@@ -43,9 +42,11 @@ module Raven
|
|
43
42
|
@server_name = @configuration.server_name
|
44
43
|
@release = @configuration.release
|
45
44
|
@modules = list_gem_specs if @configuration.send_modules
|
46
|
-
@user = {}
|
47
|
-
@extra = {}
|
48
|
-
@
|
45
|
+
@user = {} # TODO: contexts
|
46
|
+
@extra = {} # TODO: contexts
|
47
|
+
@os = {} # TODO: contexts
|
48
|
+
@runtime = {} # TODO: contexts
|
49
|
+
@tags = {} # TODO: contexts
|
49
50
|
@checksum = nil
|
50
51
|
@fingerprint = nil
|
51
52
|
@environment = @configuration.current_environment
|
@@ -58,15 +59,17 @@ module Raven
|
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
|
-
if @context.rack_env
|
62
|
+
if @context.rack_env # TODO: contexts
|
62
63
|
@context.user[:ip_address] = calculate_real_ip_from_rack
|
63
64
|
end
|
64
65
|
|
65
|
-
init.each_pair { |key, val|
|
66
|
+
init.each_pair { |key, val| public_send(key.to_s + "=", val) }
|
66
67
|
|
67
|
-
@user = @context.user.merge(@user)
|
68
|
-
@extra = @context.extra.merge(@extra)
|
69
|
-
@tags = @configuration.tags.merge(@context.tags).merge(@tags)
|
68
|
+
@user = @context.user.merge(@user) # TODO: contexts
|
69
|
+
@extra = @context.extra.merge(@extra) # TODO: contexts
|
70
|
+
@tags = @configuration.tags.merge(@context.tags).merge(@tags) # TODO: contexts
|
71
|
+
@os = @context.os # TODO: contexts
|
72
|
+
@runtime = @context.runtime # TODO: contexts
|
70
73
|
|
71
74
|
# Some type coercion
|
72
75
|
@timestamp = @timestamp.strftime('%Y-%m-%dT%H:%M:%S') if @timestamp.is_a?(Time)
|
@@ -74,6 +77,18 @@ module Raven
|
|
74
77
|
@level = LOG_LEVELS[@level.to_s.downcase] if @level.is_a?(String) || @level.is_a?(Symbol)
|
75
78
|
end
|
76
79
|
|
80
|
+
def message
|
81
|
+
@interfaces[:logentry] && @interfaces[:logentry].unformatted_message
|
82
|
+
end
|
83
|
+
|
84
|
+
def message=(args)
|
85
|
+
message, params = *args
|
86
|
+
interface(:message) do |int|
|
87
|
+
int.message = message
|
88
|
+
int.params = params
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
77
92
|
class << self
|
78
93
|
def from_exception(exc, options = {}, &block)
|
79
94
|
exception_context = get_exception_context(exc) || {}
|
@@ -107,11 +122,8 @@ module Raven
|
|
107
122
|
|
108
123
|
new(options) do |evt|
|
109
124
|
evt.configuration = configuration
|
110
|
-
evt.message = message
|
111
125
|
evt.level = options[:level] || :error
|
112
|
-
evt.
|
113
|
-
int.message = message
|
114
|
-
end
|
126
|
+
evt.message = message, options[:message_params] || []
|
115
127
|
if options[:backtrace]
|
116
128
|
evt.interface(:stacktrace) do |int|
|
117
129
|
stacktrace_interface_from(int, evt, options[:backtrace])
|
@@ -196,10 +208,10 @@ module Raven
|
|
196
208
|
end
|
197
209
|
|
198
210
|
def interface(name, value = nil, &block)
|
199
|
-
int =
|
211
|
+
int = Interface.registered[name]
|
200
212
|
raise(Error, "Unknown interface: #{name}") unless int
|
201
|
-
@interfaces[int.
|
202
|
-
@interfaces[int.
|
213
|
+
@interfaces[int.sentry_alias] = int.new(value, &block) if value || block
|
214
|
+
@interfaces[int.sentry_alias]
|
203
215
|
end
|
204
216
|
|
205
217
|
def [](key)
|
@@ -213,13 +225,17 @@ module Raven
|
|
213
225
|
def to_hash
|
214
226
|
data = {
|
215
227
|
:event_id => @id,
|
216
|
-
:message => @message,
|
217
228
|
:timestamp => @timestamp,
|
218
229
|
:time_spent => @time_spent,
|
219
230
|
:level => @level,
|
220
|
-
:
|
221
|
-
:
|
231
|
+
:platform => PLATFORM,
|
232
|
+
:sdk => SDK,
|
233
|
+
:contexts => {
|
234
|
+
:os => @os,
|
235
|
+
:runtime => @runtime
|
236
|
+
}
|
222
237
|
}
|
238
|
+
|
223
239
|
data[:logger] = @logger if @logger
|
224
240
|
data[:culprit] = @culprit if @culprit
|
225
241
|
data[:server_name] = @server_name if @server_name
|
@@ -232,9 +248,11 @@ module Raven
|
|
232
248
|
data[:user] = @user if @user
|
233
249
|
data[:breadcrumbs] = @breadcrumbs.to_hash unless @breadcrumbs.empty?
|
234
250
|
data[:checksum] = @checksum if @checksum
|
251
|
+
|
235
252
|
@interfaces.each_pair do |name, int_data|
|
236
253
|
data[name.to_sym] = int_data.to_hash
|
237
254
|
end
|
255
|
+
data[:message] = message
|
238
256
|
data
|
239
257
|
end
|
240
258
|
|
@@ -3,56 +3,62 @@ require 'sidekiq'
|
|
3
3
|
|
4
4
|
module Raven
|
5
5
|
class Sidekiq
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
Raven.capture_exception(
|
11
|
-
|
12
|
-
|
6
|
+
ACTIVEJOB_RESERVED_PREFIX = "_aj_".freeze
|
7
|
+
|
8
|
+
def call(ex, context)
|
9
|
+
context = filter_context(context)
|
10
|
+
Raven.capture_exception(
|
11
|
+
ex,
|
12
|
+
:message => ex.message,
|
13
|
+
:extra => { :sidekiq => context },
|
14
|
+
:culprit => culprit_from_context(context)
|
15
|
+
)
|
13
16
|
ensure
|
14
17
|
Context.clear!
|
15
18
|
BreadcrumbBuffer.clear!
|
16
19
|
end
|
17
|
-
end
|
18
|
-
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
private
|
22
|
+
|
23
|
+
# Once an ActiveJob is queued, ActiveRecord references get serialized into
|
24
|
+
# some internal reserved keys, such as _aj_globalid.
|
25
|
+
#
|
26
|
+
# The problem is, if this job in turn gets queued back into ActiveJob with
|
27
|
+
# these magic reserved keys, ActiveJob will throw up and error. We want to
|
28
|
+
# capture these and mutate the keys so we can sanely report it.
|
29
|
+
def filter_context(context)
|
30
|
+
case context
|
31
|
+
when Array
|
32
|
+
context.map { |arg| filter_context(arg) }
|
33
|
+
when Hash
|
34
|
+
Hash[context.map { |key, value| filter_context_hash(key, value) }]
|
35
|
+
else
|
36
|
+
context
|
37
|
+
end
|
25
38
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
Raven.capture_exception(ex, :extra => {
|
31
|
-
:sidekiq => filter_context(context)
|
32
|
-
})
|
39
|
+
|
40
|
+
def filter_context_hash(key, value)
|
41
|
+
(key = key[3..-1]) if key [0..3] == ACTIVEJOB_RESERVED_PREFIX
|
42
|
+
[key, filter_context(value)]
|
33
43
|
end
|
34
|
-
end
|
35
|
-
end
|
36
44
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
+
# this will change in the future:
|
46
|
+
# https://github.com/mperham/sidekiq/pull/3161
|
47
|
+
def culprit_from_context(context)
|
48
|
+
classname = (context["class"] || (context["job"] && context["job"]["class"]))
|
49
|
+
if classname
|
50
|
+
"Sidekiq/#{classname}"
|
51
|
+
elsif context["event"]
|
52
|
+
"Sidekiq/#{context['event']}"
|
53
|
+
else
|
54
|
+
"Sidekiq"
|
55
|
+
end
|
56
|
+
end
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# these are declared as private, and I don't think it's wise
|
53
|
-
# to keep chasing what this list is. But they all use a common prefix, so
|
54
|
-
# we want to strip this becuase ActiveJob will complain.
|
55
|
-
# e.g.: _aj_globalid -> _globalid
|
56
|
-
(key = key[3..-1]) if key [0..3] == "_aj_"
|
57
|
-
[key, filter_context(value)]
|
60
|
+
if Sidekiq::VERSION > '3'
|
61
|
+
Sidekiq.configure_server do |config|
|
62
|
+
config.error_handlers << Raven::Sidekiq.new
|
63
|
+
end
|
58
64
|
end
|
@@ -1,6 +1,4 @@
|
|
1
1
|
module Raven
|
2
|
-
INTERFACES = {} # rubocop:disable Style/MutableConstant
|
3
|
-
|
4
2
|
class Interface
|
5
3
|
def initialize(attributes = nil)
|
6
4
|
attributes.each do |attr, value|
|
@@ -10,23 +8,18 @@ module Raven
|
|
10
8
|
yield self if block_given?
|
11
9
|
end
|
12
10
|
|
13
|
-
def self.
|
14
|
-
|
11
|
+
def self.inherited(klass)
|
12
|
+
name = klass.name.split("::").last.downcase.gsub("interface", "")
|
13
|
+
registered[name.to_sym] = klass
|
14
|
+
super
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def self.registered
|
18
|
+
@@registered ||= {} # rubocop:disable Style/ClassVars
|
19
19
|
end
|
20
|
-
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
INTERFACES[key.to_s] = klass
|
25
|
-
INTERFACES[klass.name] = klass
|
21
|
+
def to_hash
|
22
|
+
Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] }]
|
26
23
|
end
|
27
24
|
end
|
28
|
-
|
29
|
-
def self.find_interface(name)
|
30
|
-
INTERFACES[name.to_s]
|
31
|
-
end
|
32
25
|
end
|
@@ -1,16 +1,17 @@
|
|
1
|
-
require 'raven/
|
1
|
+
require 'raven/interface'
|
2
2
|
|
3
3
|
module Raven
|
4
4
|
class ExceptionInterface < Interface
|
5
|
-
name 'exception'
|
6
5
|
attr_accessor :values
|
7
6
|
|
7
|
+
def self.sentry_alias
|
8
|
+
:exception
|
9
|
+
end
|
10
|
+
|
8
11
|
def to_hash(*args)
|
9
12
|
data = super(*args)
|
10
13
|
data[:values] = data[:values].map(&:to_hash) if data[:values]
|
11
14
|
data
|
12
15
|
end
|
13
16
|
end
|
14
|
-
|
15
|
-
register_interface :exception => ExceptionInterface
|
16
17
|
end
|
@@ -1,15 +1,8 @@
|
|
1
|
-
require 'raven/
|
1
|
+
require 'raven/interface'
|
2
2
|
|
3
3
|
module Raven
|
4
4
|
class HttpInterface < Interface
|
5
|
-
|
6
|
-
attr_accessor :url
|
7
|
-
attr_accessor :method
|
8
|
-
attr_accessor :data
|
9
|
-
attr_accessor :query_string
|
10
|
-
attr_accessor :cookies
|
11
|
-
attr_accessor :headers
|
12
|
-
attr_accessor :env
|
5
|
+
attr_accessor :url, :method, :data, :query_string, :cookies, :headers, :env
|
13
6
|
|
14
7
|
def initialize(*arguments)
|
15
8
|
self.headers = {}
|
@@ -17,7 +10,9 @@ module Raven
|
|
17
10
|
self.cookies = nil
|
18
11
|
super(*arguments)
|
19
12
|
end
|
20
|
-
end
|
21
13
|
|
22
|
-
|
14
|
+
def self.sentry_alias
|
15
|
+
:request
|
16
|
+
end
|
17
|
+
end
|
23
18
|
end
|
@@ -1,16 +1,20 @@
|
|
1
|
-
require 'raven/
|
1
|
+
require 'raven/interface'
|
2
2
|
|
3
3
|
module Raven
|
4
4
|
class MessageInterface < Interface
|
5
|
-
|
6
|
-
attr_accessor :message
|
7
|
-
attr_accessor :params
|
5
|
+
attr_accessor :message, :params
|
8
6
|
|
9
7
|
def initialize(*arguments)
|
10
8
|
self.params = []
|
11
9
|
super(*arguments)
|
12
10
|
end
|
13
|
-
end
|
14
11
|
|
15
|
-
|
12
|
+
def unformatted_message
|
13
|
+
message % params
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.sentry_alias
|
17
|
+
:logentry
|
18
|
+
end
|
19
|
+
end
|
16
20
|
end
|
@@ -1,8 +1,7 @@
|
|
1
|
-
require 'raven/
|
1
|
+
require 'raven/interface'
|
2
2
|
|
3
3
|
module Raven
|
4
4
|
class StacktraceInterface < Interface
|
5
|
-
name 'stacktrace'
|
6
5
|
attr_accessor :frames
|
7
6
|
|
8
7
|
def initialize(*arguments)
|
@@ -10,6 +9,10 @@ module Raven
|
|
10
9
|
super(*arguments)
|
11
10
|
end
|
12
11
|
|
12
|
+
def self.sentry_alias
|
13
|
+
:stacktrace
|
14
|
+
end
|
15
|
+
|
13
16
|
def to_hash(*args)
|
14
17
|
data = super(*args)
|
15
18
|
data[:frames] = data[:frames].map(&:to_hash)
|
@@ -71,6 +74,4 @@ module Raven
|
|
71
74
|
end
|
72
75
|
end
|
73
76
|
end
|
74
|
-
|
75
|
-
register_interface :stack_trace => StacktraceInterface
|
76
77
|
end
|
data/lib/raven/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sentry-raven
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sentry Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -149,7 +149,7 @@ files:
|
|
149
149
|
- lib/raven/integrations/rake.rb
|
150
150
|
- lib/raven/integrations/sidekiq.rb
|
151
151
|
- lib/raven/integrations/tasks.rb
|
152
|
-
- lib/raven/
|
152
|
+
- lib/raven/interface.rb
|
153
153
|
- lib/raven/interfaces/exception.rb
|
154
154
|
- lib/raven/interfaces/http.rb
|
155
155
|
- lib/raven/interfaces/message.rb
|