sentry-raven 0.3.1 → 0.4.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.
Potentially problematic release.
This version of sentry-raven might be problematic. Click here for more details.
- data/README.md +61 -9
- data/bin/raven +55 -0
- data/lib/raven.rb +13 -7
- data/lib/raven/backtrace.rb +121 -0
- data/lib/raven/client.rb +8 -3
- data/lib/raven/configuration.rb +19 -1
- data/lib/raven/event.rb +45 -50
- data/lib/raven/interfaces/stack_trace.rb +8 -2
- data/lib/raven/sidekiq.rb +18 -0
- data/lib/raven/version.rb +1 -1
- metadata +13 -11
data/README.md
CHANGED
@@ -79,14 +79,58 @@ Raven.configure do |config|
|
|
79
79
|
# manually configure environment if ENV['RACK_ENV'] is not defined
|
80
80
|
config.current_environment = 'production'
|
81
81
|
end
|
82
|
+
```
|
83
|
+
|
84
|
+
## Capturing Events
|
85
|
+
|
86
|
+
Many implementations will automatically capture uncaught exceptions (such as Rails, Sidekiq or by using
|
87
|
+
the Rack middleware). Sometimes you may want to catch those exceptions, but still report on them.
|
88
|
+
|
89
|
+
Several helps are available to assist with this.
|
82
90
|
|
83
|
-
|
91
|
+
### Capture Exceptions in a Block
|
84
92
|
|
85
|
-
|
93
|
+
```ruby
|
94
|
+
Raven.capture do
|
95
|
+
# capture any exceptions which happen during execution of this block
|
86
96
|
1 / 0
|
87
97
|
end
|
88
98
|
```
|
89
99
|
|
100
|
+
### Capture an Exception by Value
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
begin
|
104
|
+
1 / 0
|
105
|
+
rescue ZeroDivisionError => exception
|
106
|
+
Raven.capture_exception(exception)
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
### Additional Context
|
111
|
+
|
112
|
+
Additional context can be passed to the capture methods.
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
Raven.capture_message("My event", {
|
116
|
+
:logger => 'logger',
|
117
|
+
:extra => {
|
118
|
+
'my_custom_variable' => 'value'
|
119
|
+
},
|
120
|
+
:tags => {
|
121
|
+
'environment' => 'production',
|
122
|
+
}
|
123
|
+
})
|
124
|
+
```
|
125
|
+
|
126
|
+
The following attributes are available:
|
127
|
+
|
128
|
+
* `logger`: the logger name to record this event under
|
129
|
+
* `level`: a string representing the level of this event (fatal, error, warning, info, debug)
|
130
|
+
* `server_name`: the hostname of the server
|
131
|
+
* `tags`: a mapping of tags describing this event
|
132
|
+
* `extra`: a mapping of arbitrary context
|
133
|
+
|
90
134
|
## Testing
|
91
135
|
|
92
136
|
```bash
|
@@ -127,7 +171,7 @@ end
|
|
127
171
|
## Sanitizing Data (Processors)
|
128
172
|
|
129
173
|
If you need to sanitize or pre-process (before its sent to the server) data, you can do so using the Processors
|
130
|
-
implementation. By default, a single processor is installed (Raven::
|
174
|
+
implementation. By default, a single processor is installed (Raven::Processor::SanitizeData), which will attempt to
|
131
175
|
sanitize keys that match various patterns (e.g. password) and values that resemble credit card numbers.
|
132
176
|
|
133
177
|
To specify your own (or to remove the defaults), simply pass them with your configuration:
|
@@ -137,14 +181,22 @@ require 'raven'
|
|
137
181
|
|
138
182
|
Raven.configure do |config|
|
139
183
|
config.dsn = 'http://public:secret@example.com/project-id'
|
140
|
-
config.processors = [Raven::
|
184
|
+
config.processors = [Raven::Processor::SanitizeData]
|
141
185
|
end
|
186
|
+
```
|
187
|
+
|
188
|
+
## Command Line Interface
|
189
|
+
|
190
|
+
Raven includes a basic CLI for testing your DSN:
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
ruby -Ilib ./bin/raven test <DSN>
|
194
|
+
```
|
142
195
|
|
143
196
|
Resources
|
144
197
|
---------
|
145
198
|
|
146
|
-
*
|
147
|
-
*
|
148
|
-
*
|
149
|
-
*
|
150
|
-
|
199
|
+
* [Bug Tracker](http://github.com/getsentry/raven-ruby/issues>)
|
200
|
+
* [Code](http://github.com/getsentry/raven-ruby>)
|
201
|
+
* [Mailing List](https://groups.google.com/group/getsentry>)
|
202
|
+
* [IRC](irc://irc.freenode.net/sentry>) (irc.freenode.net, #sentry)
|
data/bin/raven
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "raven"
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
|
8
|
+
parser = OptionParser.new do |opt|
|
9
|
+
opt.banner = "Usage: raven COMMAND [OPTIONS]"
|
10
|
+
opt.separator ""
|
11
|
+
opt.separator "Commands"
|
12
|
+
opt.separator " test: send a test event"
|
13
|
+
opt.separator ""
|
14
|
+
opt.separator "Options"
|
15
|
+
|
16
|
+
# opt.on("-e","--environment ENVIRONMENT","which environment you want server run") do |environment|
|
17
|
+
# options[:environment] = environment
|
18
|
+
# end
|
19
|
+
|
20
|
+
# opt.on("-d","--daemon","runing on daemon mode?") do
|
21
|
+
# options[:daemon] = true
|
22
|
+
# end
|
23
|
+
|
24
|
+
opt.on("-h","--help","help") do
|
25
|
+
puts parser
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
parser.parse!
|
30
|
+
|
31
|
+
case ARGV[0]
|
32
|
+
when "test"
|
33
|
+
dsn = ARGV[1] if ARGV.length > 1
|
34
|
+
if !dsn
|
35
|
+
puts "Usage: raven test <dsn>"
|
36
|
+
else
|
37
|
+
Raven.configure do |config|
|
38
|
+
config.dsn = dsn
|
39
|
+
config.current_environment = 'production'
|
40
|
+
end
|
41
|
+
|
42
|
+
puts "Sending test event"
|
43
|
+
|
44
|
+
begin
|
45
|
+
1 / 0
|
46
|
+
rescue ZeroDivisionError => exception
|
47
|
+
Raven.capture_exception(exception)
|
48
|
+
end
|
49
|
+
|
50
|
+
puts "Done!"
|
51
|
+
|
52
|
+
end
|
53
|
+
else
|
54
|
+
puts parser
|
55
|
+
end
|
data/lib/raven.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'raven/version'
|
2
|
+
require 'raven/backtrace'
|
2
3
|
require 'raven/configuration'
|
3
4
|
require 'raven/logger'
|
4
5
|
require 'raven/client'
|
@@ -11,6 +12,8 @@ require 'raven/interfaces/http'
|
|
11
12
|
require 'raven/processors/sanitizedata'
|
12
13
|
|
13
14
|
require 'raven/railtie' if defined?(Rails::Railtie)
|
15
|
+
require 'raven/sidekiq' if defined?(Sidekiq)
|
16
|
+
|
14
17
|
|
15
18
|
module Raven
|
16
19
|
class << self
|
@@ -66,14 +69,14 @@ module Raven
|
|
66
69
|
# Raven.capture do
|
67
70
|
# MyApp.run
|
68
71
|
# end
|
69
|
-
def capture(&block)
|
72
|
+
def capture(options={}, &block)
|
70
73
|
if block
|
71
74
|
begin
|
72
75
|
block.call
|
73
76
|
rescue Error => e
|
74
77
|
raise # Don't capture Raven errors
|
75
78
|
rescue Exception => e
|
76
|
-
|
79
|
+
capture_exception(e, options)
|
77
80
|
raise
|
78
81
|
end
|
79
82
|
else
|
@@ -81,21 +84,24 @@ module Raven
|
|
81
84
|
at_exit do
|
82
85
|
if $!
|
83
86
|
logger.debug "Caught a post-mortem exception: #{$!.inspect}"
|
84
|
-
|
87
|
+
capture_exception($!, options)
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|
88
91
|
end
|
89
92
|
|
90
|
-
def
|
91
|
-
evt = Event.capture_exception(exception)
|
93
|
+
def capture_exception(exception, options={})
|
94
|
+
evt = Event.capture_exception(exception, options)
|
92
95
|
send(evt) if evt
|
93
96
|
end
|
94
97
|
|
95
|
-
def
|
96
|
-
evt = Event.capture_message(message)
|
98
|
+
def capture_message(message, options={})
|
99
|
+
evt = Event.capture_message(message, options)
|
97
100
|
send(evt) if evt
|
98
101
|
end
|
99
102
|
|
103
|
+
# For cross-language compat
|
104
|
+
alias :captureException :capture_exception
|
105
|
+
alias :captureMessage :capture_message
|
100
106
|
end
|
101
107
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
## Inspired by Rails' and Airbrake's backtrace parsers.
|
2
|
+
|
3
|
+
module Raven
|
4
|
+
|
5
|
+
# Front end to parsing the backtrace for each notice
|
6
|
+
class Backtrace
|
7
|
+
|
8
|
+
# Handles backtrace parsing line by line
|
9
|
+
class Line
|
10
|
+
|
11
|
+
# regexp (optionnally allowing leading X: for windows support)
|
12
|
+
INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$}.freeze
|
13
|
+
|
14
|
+
APP_DIRS_PATTERN = /^\/?(bin|app|config|lib|test)/
|
15
|
+
|
16
|
+
# The file portion of the line (such as app/models/user.rb)
|
17
|
+
attr_reader :file
|
18
|
+
|
19
|
+
# The line number portion of the line
|
20
|
+
attr_reader :number
|
21
|
+
|
22
|
+
# The method of the line (such as index)
|
23
|
+
attr_reader :method
|
24
|
+
|
25
|
+
# Parses a single line of a given backtrace
|
26
|
+
# @param [String] unparsed_line The raw line from +caller+ or some backtrace
|
27
|
+
# @return [Line] The parsed backtrace line
|
28
|
+
def self.parse(unparsed_line)
|
29
|
+
_, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
|
30
|
+
new(file, number, method)
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(file, number, method)
|
34
|
+
self.file = file
|
35
|
+
self.number = number.to_i
|
36
|
+
self.method = method
|
37
|
+
end
|
38
|
+
|
39
|
+
def in_app
|
40
|
+
if self.file =~ APP_DIRS_PATTERN
|
41
|
+
true
|
42
|
+
else
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Reconstructs the line in a readable fashion
|
48
|
+
def to_s
|
49
|
+
"#{file}:#{number}:in `#{method}'"
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
to_s == other.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
"<Line:#{to_s}>"
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
attr_writer :file, :number, :method
|
63
|
+
end
|
64
|
+
|
65
|
+
# holder for an Array of Backtrace::Line instances
|
66
|
+
attr_reader :lines
|
67
|
+
|
68
|
+
def self.parse(ruby_backtrace, opts = {})
|
69
|
+
ruby_lines = split_multiline_backtrace(ruby_backtrace)
|
70
|
+
|
71
|
+
filters = opts[:filters] || []
|
72
|
+
filtered_lines = ruby_lines.to_a.map do |line|
|
73
|
+
filters.inject(line) do |line, proc|
|
74
|
+
proc.call(line)
|
75
|
+
end
|
76
|
+
end.compact
|
77
|
+
|
78
|
+
lines = filtered_lines.collect do |unparsed_line|
|
79
|
+
Line.parse(unparsed_line)
|
80
|
+
end
|
81
|
+
|
82
|
+
instance = new(lines)
|
83
|
+
end
|
84
|
+
|
85
|
+
def initialize(lines)
|
86
|
+
self.lines = lines
|
87
|
+
end
|
88
|
+
|
89
|
+
def inspect
|
90
|
+
"<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_s
|
94
|
+
content = []
|
95
|
+
lines.each do |line|
|
96
|
+
content << line
|
97
|
+
end
|
98
|
+
content.join("\n")
|
99
|
+
end
|
100
|
+
|
101
|
+
def ==(other)
|
102
|
+
if other.respond_to?(:lines)
|
103
|
+
lines == other.lines
|
104
|
+
else
|
105
|
+
false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
attr_writer :lines
|
112
|
+
|
113
|
+
def self.split_multiline_backtrace(backtrace)
|
114
|
+
if backtrace.to_a.size == 1
|
115
|
+
backtrace.to_a.first.split(/\n\s*/)
|
116
|
+
else
|
117
|
+
backtrace
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/lib/raven/client.rb
CHANGED
@@ -29,9 +29,14 @@ module Raven
|
|
29
29
|
|
30
30
|
Raven.logger.debug "Raven client connecting to #{self.configuration[:server]}"
|
31
31
|
|
32
|
-
@conn ||= Faraday.new(
|
33
|
-
|
34
|
-
|
32
|
+
@conn ||= Faraday.new(
|
33
|
+
:url => self.configuration[:server],
|
34
|
+
:ssl => {:verify => self.configuration.ssl_verification}
|
35
|
+
) do |builder|
|
36
|
+
builder.adapter Faraday.default_adapter
|
37
|
+
builder.options[:timeout] = self.configuration.timeout if self.configuration.timeout
|
38
|
+
builder.options[:open_timeout] = self.configuration.open_timeout if self.configuration.open_timeout
|
39
|
+
end
|
35
40
|
end
|
36
41
|
|
37
42
|
|
data/lib/raven/configuration.rb
CHANGED
@@ -31,16 +31,34 @@ module Raven
|
|
31
31
|
# Processors to run on data before sending upstream
|
32
32
|
attr_accessor :processors
|
33
33
|
|
34
|
+
# Timeout when waiting for the server to return data in seconds
|
35
|
+
attr_accessor :timeout
|
36
|
+
|
37
|
+
# Timeout waiting for the connection to open in seconds
|
38
|
+
attr_accessor :open_timeout
|
39
|
+
|
40
|
+
# Should the SSL certificate of the server be verified?
|
41
|
+
attr_accessor :ssl_verification
|
42
|
+
|
34
43
|
attr_reader :current_environment
|
35
44
|
|
45
|
+
IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
|
46
|
+
'ActionController::RoutingError',
|
47
|
+
'ActionController::InvalidAuthenticityToken',
|
48
|
+
'CGI::Session::CookieStore::TamperedWithCookie',
|
49
|
+
'ActionController::UnknownAction',
|
50
|
+
'AbstractController::ActionNotFound',
|
51
|
+
'Mongoid::Errors::DocumentNotFound']
|
52
|
+
|
36
53
|
def initialize
|
37
54
|
self.server = ENV['SENTRY_DSN'] if ENV['SENTRY_DSN']
|
38
55
|
@context_lines = 3
|
39
56
|
self.environments = %w[ production ]
|
40
57
|
self.current_environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
41
58
|
self.send_modules = true
|
42
|
-
self.excluded_exceptions =
|
59
|
+
self.excluded_exceptions = IGNORE_DEFAULT
|
43
60
|
self.processors = [Raven::Processor::SanitizeData]
|
61
|
+
self.ssl_verification = true
|
44
62
|
end
|
45
63
|
|
46
64
|
def server=(value)
|
data/lib/raven/event.rb
CHANGED
@@ -15,16 +15,17 @@ module Raven
|
|
15
15
|
"warn" => 30,
|
16
16
|
"warning" => 30,
|
17
17
|
"error" => 40,
|
18
|
+
"fatal" => 50,
|
18
19
|
}
|
19
20
|
|
20
21
|
BACKTRACE_RE = /^(.+?):(\d+)(?::in `(.+?)')?$/
|
21
22
|
|
22
23
|
attr_reader :id
|
23
24
|
attr_accessor :project, :message, :timestamp, :level
|
24
|
-
attr_accessor :logger, :culprit, :server_name, :modules, :extra
|
25
|
+
attr_accessor :logger, :culprit, :server_name, :modules, :extra, :tags
|
25
26
|
|
26
|
-
def initialize(options={},
|
27
|
-
@configuration = configuration || Raven.configuration
|
27
|
+
def initialize(options={}, &block)
|
28
|
+
@configuration = options[:configuration] || Raven.configuration
|
28
29
|
@interfaces = {}
|
29
30
|
|
30
31
|
@id = options[:id] || UUIDTools::UUID.random_create.hexdigest
|
@@ -34,6 +35,7 @@ module Raven
|
|
34
35
|
@logger = options[:logger] || 'root'
|
35
36
|
@culprit = options[:culprit]
|
36
37
|
@extra = options[:extra]
|
38
|
+
@tags = options[:tags]
|
37
39
|
|
38
40
|
# Try to resolve the hostname to an FQDN, but fall back to whatever the load name is
|
39
41
|
hostname = Socket.gethostname
|
@@ -85,31 +87,45 @@ module Raven
|
|
85
87
|
data['server_name'] = self.server_name if self.server_name
|
86
88
|
data['modules'] = self.modules if self.modules
|
87
89
|
data['extra'] = self.extra if self.extra
|
90
|
+
data['tags'] = self.tags if self.tags
|
88
91
|
@interfaces.each_pair do |name, int_data|
|
89
92
|
data[name] = int_data.to_hash
|
90
93
|
end
|
91
94
|
data
|
92
95
|
end
|
93
96
|
|
94
|
-
def self.capture_exception(exc,
|
95
|
-
configuration
|
97
|
+
def self.capture_exception(exc, options={}, &block)
|
98
|
+
configuration = options[:configuration] || Raven.configuration
|
96
99
|
if exc.is_a?(Raven::Error)
|
97
100
|
# Try to prevent error reporting loops
|
98
101
|
Raven.logger.info "Refusing to capture Raven error: #{exc.inspect}"
|
99
102
|
return nil
|
100
103
|
end
|
101
|
-
if configuration[:excluded_exceptions].
|
104
|
+
if configuration[:excluded_exceptions].any? { |x| x === exc || x == exc.class.name }
|
102
105
|
Raven.logger.info "User excluded error: #{exc.inspect}"
|
103
106
|
return nil
|
104
107
|
end
|
105
|
-
|
108
|
+
|
109
|
+
context_lines = configuration[:context_lines]
|
110
|
+
|
111
|
+
new(options) do |evt|
|
106
112
|
evt.message = "#{exc.class.to_s}: #{exc.message}"
|
107
|
-
evt.level = :error
|
113
|
+
evt.level = options[:level] || :error
|
108
114
|
evt.parse_exception(exc)
|
109
115
|
if (exc.backtrace)
|
110
116
|
evt.interface :stack_trace do |int|
|
111
|
-
|
112
|
-
|
117
|
+
backtrace = Backtrace.parse(exc.backtrace)
|
118
|
+
int.frames = backtrace.lines.reverse.map do |line|
|
119
|
+
int.frame do |frame|
|
120
|
+
frame.abs_path = line.file
|
121
|
+
frame.function = line.method
|
122
|
+
frame.lineno = line.number
|
123
|
+
frame.in_app = line.in_app
|
124
|
+
if context_lines
|
125
|
+
frame.pre_context, frame.context_line, frame.post_context = \
|
126
|
+
evt.get_context(frame.abs_path, frame.lineno, context_lines)
|
127
|
+
end
|
128
|
+
end
|
113
129
|
end
|
114
130
|
evt.culprit = evt.get_culprit(int.frames)
|
115
131
|
end
|
@@ -118,9 +134,8 @@ module Raven
|
|
118
134
|
end
|
119
135
|
end
|
120
136
|
|
121
|
-
def self.capture_rack_exception(exc, rack_env,
|
122
|
-
|
123
|
-
capture_exception(exc, configuration) do |evt|
|
137
|
+
def self.capture_rack_exception(exc, rack_env, options={}, &block)
|
138
|
+
capture_exception(exc, options) do |evt|
|
124
139
|
evt.interface :http do |int|
|
125
140
|
int.from_rack(rack_env)
|
126
141
|
end
|
@@ -128,20 +143,30 @@ module Raven
|
|
128
143
|
end
|
129
144
|
end
|
130
145
|
|
131
|
-
def self.capture_message(message,
|
132
|
-
|
133
|
-
self.new({}, configuration) do |evt|
|
146
|
+
def self.capture_message(message, options={})
|
147
|
+
new(options) do |evt|
|
134
148
|
evt.message = message
|
135
|
-
evt.level = :error
|
149
|
+
evt.level = options[:level] || :error
|
136
150
|
evt.interface :message do |int|
|
137
151
|
int.message = message
|
138
152
|
end
|
139
153
|
end
|
140
154
|
end
|
141
155
|
|
156
|
+
# Because linecache can go to hell
|
157
|
+
def self._source_lines(path, from, to)
|
158
|
+
end
|
159
|
+
|
160
|
+
def get_context(filename, lineno, context)
|
161
|
+
lines = (2 * context + 1).times.map do |i|
|
162
|
+
Raven::LineCache::getline(filename, lineno - context + i)
|
163
|
+
end
|
164
|
+
[lines[0..(context-1)], lines[context], lines[(context+1)..-1]]
|
165
|
+
end
|
166
|
+
|
142
167
|
def get_culprit(frames)
|
143
|
-
|
144
|
-
|
168
|
+
lastframe = frames[-1]
|
169
|
+
"#{lastframe.filename} in #{lastframe.function}" if lastframe
|
145
170
|
end
|
146
171
|
|
147
172
|
def parse_exception(exception)
|
@@ -152,42 +177,12 @@ module Raven
|
|
152
177
|
end
|
153
178
|
end
|
154
179
|
|
155
|
-
def parse_backtrace_line(line, frame)
|
156
|
-
md = BACKTRACE_RE.match(line)
|
157
|
-
raise Error.new("Unable to parse backtrace line: #{line.inspect}") unless md
|
158
|
-
frame.abs_path = md[1]
|
159
|
-
frame.lineno = md[2].to_i
|
160
|
-
frame.function = md[3] if md[3]
|
161
|
-
frame.filename = strip_load_path_from(frame.abs_path)
|
162
|
-
if context_lines = @configuration[:context_lines]
|
163
|
-
frame.pre_context, frame.context_line, frame.post_context = \
|
164
|
-
get_context(frame.abs_path, frame.lineno, context_lines)
|
165
|
-
end
|
166
|
-
frame
|
167
|
-
end
|
168
|
-
|
169
180
|
# For cross-language compat
|
170
181
|
class << self
|
171
|
-
alias :
|
182
|
+
alias :captureException :capture_exception
|
172
183
|
alias :captureMessage :capture_message
|
173
184
|
end
|
174
185
|
|
175
186
|
private
|
176
|
-
|
177
|
-
# Because linecache can go to hell
|
178
|
-
def self._source_lines(path, from, to)
|
179
|
-
end
|
180
|
-
|
181
|
-
def get_context(path, line, context)
|
182
|
-
lines = (2 * context + 1).times.map do |i|
|
183
|
-
Raven::LineCache::getline(path, line - context + i)
|
184
|
-
end
|
185
|
-
[lines[0..(context-1)], lines[context], lines[(context+1)..-1]]
|
186
|
-
end
|
187
|
-
|
188
|
-
def strip_load_path_from(path)
|
189
|
-
prefix = $:.select {|s| path.start_with?(s)}.sort_by {|s| s.length}.last
|
190
|
-
prefix ? path[prefix.chomp(File::SEPARATOR).length+1..-1] : path
|
191
|
-
end
|
192
187
|
end
|
193
188
|
end
|
@@ -27,23 +27,29 @@ module Raven
|
|
27
27
|
# Not actually an interface, but I want to use the same style
|
28
28
|
class Frame < Interface
|
29
29
|
property :abs_path
|
30
|
-
property :filename, :required => true
|
31
30
|
property :function
|
32
31
|
property :vars
|
33
32
|
property :pre_context
|
34
33
|
property :post_context
|
35
34
|
property :context_line
|
36
35
|
property :lineno, :required => true
|
36
|
+
property :in_app
|
37
37
|
|
38
38
|
def initialize(*arguments)
|
39
|
-
self.vars= {}
|
39
|
+
self.vars = {}
|
40
40
|
self.pre_context = []
|
41
41
|
self.post_context = []
|
42
42
|
super(*arguments)
|
43
43
|
end
|
44
44
|
|
45
|
+
def filename
|
46
|
+
prefix = $:.select {|s| self.abs_path.start_with?(s)}.sort_by {|s| s.length}.last
|
47
|
+
prefix ? self.abs_path[prefix.chomp(File::SEPARATOR).length+1..-1] : self.abs_path
|
48
|
+
end
|
49
|
+
|
45
50
|
def to_hash
|
46
51
|
data = super
|
52
|
+
data['filename'] = self.filename
|
47
53
|
data.delete('vars') unless self.vars && !self.vars.empty?
|
48
54
|
data.delete('pre_context') unless self.pre_context && !self.pre_context.empty?
|
49
55
|
data.delete('post_context') unless self.post_context && !self.post_context.empty?
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Raven
|
2
|
+
class Sidekiq
|
3
|
+
def call(worker, msg, queue)
|
4
|
+
begin
|
5
|
+
yield
|
6
|
+
rescue => ex
|
7
|
+
Raven.capture_exception(ex, :extra => {:sidekiq => msg})
|
8
|
+
raise
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
::Sidekiq.configure_server do |config|
|
15
|
+
config.server_middleware do |chain|
|
16
|
+
chain.add ::Raven::Sidekiq
|
17
|
+
end
|
18
|
+
end
|
data/lib/raven/version.rb
CHANGED
metadata
CHANGED
@@ -4,17 +4,18 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Noah Kantrowitz
|
13
|
+
- David Cramer
|
13
14
|
autorequire:
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date:
|
18
|
+
date: 2013-01-04 00:00:00 -08:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -22,14 +23,13 @@ dependencies:
|
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
25
|
requirements:
|
25
|
-
- -
|
26
|
+
- - ">="
|
26
27
|
- !ruby/object:Gem::Version
|
27
28
|
segments:
|
28
29
|
- 0
|
29
|
-
-
|
30
|
-
-
|
31
|
-
|
32
|
-
version: 0.8.0.rc2
|
30
|
+
- 7
|
31
|
+
- 6
|
32
|
+
version: 0.7.6
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
@@ -71,14 +71,15 @@ dependencies:
|
|
71
71
|
version_requirements: *id004
|
72
72
|
description:
|
73
73
|
email: noah@coderanger.net
|
74
|
-
executables:
|
75
|
-
|
74
|
+
executables:
|
75
|
+
- raven
|
76
76
|
extensions: []
|
77
77
|
|
78
78
|
extra_rdoc_files:
|
79
79
|
- README.md
|
80
80
|
- LICENSE
|
81
81
|
files:
|
82
|
+
- lib/raven/backtrace.rb
|
82
83
|
- lib/raven/client.rb
|
83
84
|
- lib/raven/configuration.rb
|
84
85
|
- lib/raven/error.rb
|
@@ -95,6 +96,7 @@ files:
|
|
95
96
|
- lib/raven/rack.rb
|
96
97
|
- lib/raven/rails/middleware/debug_exceptions_catcher.rb
|
97
98
|
- lib/raven/railtie.rb
|
99
|
+
- lib/raven/sidekiq.rb
|
98
100
|
- lib/raven/version.rb
|
99
101
|
- lib/raven.rb
|
100
102
|
- lib/sentry-raven.rb
|