sentry-raven 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
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
|