alec-gem 2.7.2
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 +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +74 -0
- data/.travis.yml +47 -0
- data/Gemfile +38 -0
- data/Gemfile.lock +215 -0
- data/LICENSE +201 -0
- data/README.md +132 -0
- data/Rakefile +29 -0
- data/alec-gem.gemspec +22 -0
- data/changelog.md +442 -0
- data/docs/Makefile +130 -0
- data/docs/breadcrumbs.rst +51 -0
- data/docs/conf.py +228 -0
- data/docs/config.rst +260 -0
- data/docs/context.rst +141 -0
- data/docs/index.rst +113 -0
- data/docs/install.rst +40 -0
- data/docs/integrations/heroku.rst +11 -0
- data/docs/integrations/index.rst +59 -0
- data/docs/integrations/puma.rst +30 -0
- data/docs/integrations/rack.rst +27 -0
- data/docs/integrations/rails.rst +62 -0
- data/docs/make.bat +155 -0
- data/docs/processors.rst +124 -0
- data/docs/sentry-doc-config.json +31 -0
- data/docs/usage.rst +176 -0
- data/exe/raven +32 -0
- data/lib/raven.rb +3 -0
- data/lib/raven/backtrace.rb +137 -0
- data/lib/raven/base.rb +106 -0
- data/lib/raven/breadcrumbs.rb +76 -0
- data/lib/raven/breadcrumbs/activesupport.rb +19 -0
- data/lib/raven/breadcrumbs/logger.rb +93 -0
- data/lib/raven/cli.rb +59 -0
- data/lib/raven/client.rb +142 -0
- data/lib/raven/configuration.rb +434 -0
- data/lib/raven/context.rb +43 -0
- data/lib/raven/event.rb +259 -0
- data/lib/raven/instance.rb +221 -0
- data/lib/raven/integrations/delayed_job.rb +58 -0
- data/lib/raven/integrations/rack-timeout.rb +19 -0
- data/lib/raven/integrations/rack.rb +139 -0
- data/lib/raven/integrations/rails.rb +79 -0
- data/lib/raven/integrations/rails/active_job.rb +59 -0
- data/lib/raven/integrations/rails/controller_methods.rb +13 -0
- data/lib/raven/integrations/rails/controller_transaction.rb +13 -0
- data/lib/raven/integrations/rails/overrides/debug_exceptions_catcher.rb +31 -0
- data/lib/raven/integrations/rails/overrides/streaming_reporter.rb +23 -0
- data/lib/raven/integrations/railties.rb +1 -0
- data/lib/raven/integrations/rake.rb +18 -0
- data/lib/raven/integrations/sidekiq.rb +87 -0
- data/lib/raven/integrations/tasks.rb +11 -0
- data/lib/raven/interface.rb +25 -0
- data/lib/raven/interfaces/exception.rb +15 -0
- data/lib/raven/interfaces/http.rb +16 -0
- data/lib/raven/interfaces/message.rb +20 -0
- data/lib/raven/interfaces/single_exception.rb +14 -0
- data/lib/raven/interfaces/stack_trace.rb +69 -0
- data/lib/raven/linecache.rb +41 -0
- data/lib/raven/logger.rb +19 -0
- data/lib/raven/processor.rb +15 -0
- data/lib/raven/processor/cookies.rb +26 -0
- data/lib/raven/processor/http_headers.rb +55 -0
- data/lib/raven/processor/post_data.rb +22 -0
- data/lib/raven/processor/removecircularreferences.rb +17 -0
- data/lib/raven/processor/removestacktrace.rb +24 -0
- data/lib/raven/processor/sanitizedata.rb +88 -0
- data/lib/raven/processor/utf8conversion.rb +52 -0
- data/lib/raven/transports.rb +15 -0
- data/lib/raven/transports/dummy.rb +16 -0
- data/lib/raven/transports/http.rb +68 -0
- data/lib/raven/utils/deep_merge.rb +22 -0
- data/lib/raven/utils/real_ip.rb +62 -0
- data/lib/raven/version.rb +5 -0
- data/lib/sentry-raven-without-integrations.rb +1 -0
- data/lib/sentry-raven.rb +1 -0
- data/pkg/sentry-raven-2.7.2.gem +0 -0
- metadata +143 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'delayed_job'
|
2
|
+
|
3
|
+
module Delayed
|
4
|
+
module Plugins
|
5
|
+
class Raven < ::Delayed::Plugin
|
6
|
+
callbacks do |lifecycle|
|
7
|
+
lifecycle.around(:invoke_job) do |job, *args, &block|
|
8
|
+
begin
|
9
|
+
# Forward the call to the next callback in the callback chain
|
10
|
+
block.call(job, *args)
|
11
|
+
|
12
|
+
rescue Exception => exception
|
13
|
+
# Log error to Sentry
|
14
|
+
extra = {
|
15
|
+
:delayed_job => {
|
16
|
+
:id => job.id,
|
17
|
+
:priority => job.priority,
|
18
|
+
:attempts => job.attempts,
|
19
|
+
:run_at => job.run_at,
|
20
|
+
:locked_at => job.locked_at,
|
21
|
+
:locked_by => job.locked_by,
|
22
|
+
:queue => job.queue,
|
23
|
+
:created_at => job.created_at
|
24
|
+
}
|
25
|
+
}
|
26
|
+
# last_error can be nil
|
27
|
+
extra[:last_error] = job.last_error[0...1000] if job.last_error
|
28
|
+
# handlers are YAML objects in strings, we definitely can't
|
29
|
+
# report all of that or the event will get truncated randomly
|
30
|
+
extra[:handler] = job.handler[0...1000] if job.handler
|
31
|
+
|
32
|
+
if job.respond_to?('payload_object') && job.payload_object.respond_to?('job_data')
|
33
|
+
extra[:active_job] = job.payload_object.job_data
|
34
|
+
end
|
35
|
+
::Raven.capture_exception(exception,
|
36
|
+
:logger => 'delayed_job',
|
37
|
+
:tags => {
|
38
|
+
:delayed_job_queue => job.queue,
|
39
|
+
:delayed_job_id => job.id
|
40
|
+
},
|
41
|
+
:extra => extra)
|
42
|
+
|
43
|
+
# Make sure we propagate the failure!
|
44
|
+
raise exception
|
45
|
+
ensure
|
46
|
+
::Raven::Context.clear!
|
47
|
+
::Raven::BreadcrumbBuffer.clear!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Register DelayedJob Raven plugin
|
57
|
+
#
|
58
|
+
Delayed::Worker.plugins << Delayed::Plugins::Raven
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# We need to do this because of the way integration loading works
|
2
|
+
require "rack/timeout/base" unless defined?(Rack::Timeout)
|
3
|
+
|
4
|
+
# This integration is a good example of how to change how exceptions
|
5
|
+
# get grouped by Sentry's UI. Simply override #raven_context in
|
6
|
+
# the exception class, and append something to the fingerprint
|
7
|
+
# that will distinguish exceptions in the way you desire.
|
8
|
+
module RackTimeoutExtensions
|
9
|
+
def raven_context
|
10
|
+
# Only rack-timeout 0.3.0+ provides the request environment, but we can't
|
11
|
+
# gate this based on a gem version constant because rack-timeout does
|
12
|
+
# not provide one.
|
13
|
+
{ :fingerprint => ["{{ default }}", env["REQUEST_URI"]] } if defined?(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Include is private in Ruby 1.9
|
18
|
+
Rack::Timeout::Error.__send__(:include, RackTimeoutExtensions)
|
19
|
+
Rack::Timeout::RequestTimeoutException.__send__(:include, RackTimeoutExtensions)
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'rack'
|
3
|
+
|
4
|
+
module Raven
|
5
|
+
# Middleware for Rack applications. Any errors raised by the upstream
|
6
|
+
# application will be delivered to Sentry and re-raised.
|
7
|
+
#
|
8
|
+
# Synopsis:
|
9
|
+
#
|
10
|
+
# require 'rack'
|
11
|
+
# require 'raven'
|
12
|
+
#
|
13
|
+
# Raven.configure do |config|
|
14
|
+
# config.server = 'http://my_dsn'
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# app = Rack::Builder.app do
|
18
|
+
# use Raven::Rack
|
19
|
+
# run lambda { |env| raise "Rack down" }
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Use a standard Raven.configure call to configure your server credentials.
|
23
|
+
class Rack
|
24
|
+
def self.capture_type(exception, env, options = {})
|
25
|
+
if env['raven.requested_at']
|
26
|
+
options[:time_spent] = Time.now - env['raven.requested_at']
|
27
|
+
end
|
28
|
+
Raven.capture_type(exception, options) do |evt|
|
29
|
+
evt.interface :http do |int|
|
30
|
+
int.from_rack(env)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
class << self
|
35
|
+
alias capture_message capture_type
|
36
|
+
alias capture_exception capture_type
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(app)
|
40
|
+
@app = app
|
41
|
+
end
|
42
|
+
|
43
|
+
def call(env)
|
44
|
+
# store the current environment in our local context for arbitrary
|
45
|
+
# callers
|
46
|
+
env['raven.requested_at'] = Time.now
|
47
|
+
Raven.rack_context(env)
|
48
|
+
Raven.context.transaction.push(env["PATH_INFO"]) if env["PATH_INFO"]
|
49
|
+
|
50
|
+
begin
|
51
|
+
response = @app.call(env)
|
52
|
+
rescue Error
|
53
|
+
raise # Don't capture Raven errors
|
54
|
+
rescue Exception => e
|
55
|
+
Raven::Rack.capture_exception(e, env)
|
56
|
+
raise
|
57
|
+
end
|
58
|
+
|
59
|
+
error = env['rack.exception'] || env['sinatra.error']
|
60
|
+
Raven::Rack.capture_exception(error, env) if error
|
61
|
+
|
62
|
+
response
|
63
|
+
ensure
|
64
|
+
Context.clear!
|
65
|
+
BreadcrumbBuffer.clear!
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module RackInterface
|
70
|
+
def from_rack(env_hash)
|
71
|
+
req = ::Rack::Request.new(env_hash)
|
72
|
+
|
73
|
+
self.url = req.scheme && req.url.split('?').first
|
74
|
+
self.method = req.request_method
|
75
|
+
self.query_string = req.query_string
|
76
|
+
self.data = read_data_from(req)
|
77
|
+
self.cookies = req.cookies
|
78
|
+
|
79
|
+
self.headers = format_headers_for_sentry(env_hash)
|
80
|
+
self.env = format_env_for_sentry(env_hash)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# See Sentry server default limits at
|
86
|
+
# https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py
|
87
|
+
def read_data_from(request)
|
88
|
+
if request.form_data?
|
89
|
+
request.POST
|
90
|
+
elsif request.body # JSON requests, etc
|
91
|
+
data = request.body.read(4096 * 4) # Sentry server limit
|
92
|
+
request.body.rewind
|
93
|
+
data
|
94
|
+
end
|
95
|
+
rescue IOError => ex
|
96
|
+
ex.message
|
97
|
+
end
|
98
|
+
|
99
|
+
def format_headers_for_sentry(env_hash)
|
100
|
+
env_hash.each_with_object({}) do |(key, value), memo|
|
101
|
+
begin
|
102
|
+
key = key.to_s # rack env can contain symbols
|
103
|
+
value = value.to_s
|
104
|
+
next unless key.upcase == key # Non-upper case stuff isn't either
|
105
|
+
|
106
|
+
# Rack adds in an incorrect HTTP_VERSION key, which causes downstream
|
107
|
+
# to think this is a Version header. Instead, this is mapped to
|
108
|
+
# env['SERVER_PROTOCOL']. But we don't want to ignore a valid header
|
109
|
+
# if the request has legitimately sent a Version header themselves.
|
110
|
+
# See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29
|
111
|
+
next if key == 'HTTP_VERSION' && value == env_hash['SERVER_PROTOCOL']
|
112
|
+
next if key == 'HTTP_COOKIE' # Cookies don't go here, they go somewhere else
|
113
|
+
|
114
|
+
next unless key.start_with?('HTTP_') || %w(CONTENT_TYPE CONTENT_LENGTH).include?(key)
|
115
|
+
# Rack stores headers as HTTP_WHAT_EVER, we need What-Ever
|
116
|
+
key = key.gsub("HTTP_", "")
|
117
|
+
key = key.split('_').map(&:capitalize).join('-')
|
118
|
+
memo[key] = value
|
119
|
+
rescue StandardError => e
|
120
|
+
# Rails adds objects to the Rack env that can sometimes raise exceptions
|
121
|
+
# when `to_s` is called.
|
122
|
+
# See: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L134
|
123
|
+
Raven.logger.warn("Error raised while formatting headers: #{e.message}")
|
124
|
+
next
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def format_env_for_sentry(env_hash)
|
130
|
+
env_hash.select do |k, _v|
|
131
|
+
%w(REMOTE_ADDR SERVER_NAME SERVER_PORT).include? k.to_s
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class HttpInterface
|
137
|
+
include RackInterface
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Raven
|
4
|
+
class Rails < ::Rails::Railtie
|
5
|
+
require 'raven/integrations/rails/overrides/streaming_reporter'
|
6
|
+
require 'raven/integrations/rails/controller_methods'
|
7
|
+
require 'raven/integrations/rails/controller_transaction'
|
8
|
+
|
9
|
+
initializer "raven.use_rack_middleware" do |app|
|
10
|
+
app.config.middleware.insert 0, Raven::Rack
|
11
|
+
end
|
12
|
+
|
13
|
+
initializer 'raven.action_controller' do
|
14
|
+
ActiveSupport.on_load :action_controller do
|
15
|
+
include Raven::Rails::ControllerMethods
|
16
|
+
include Raven::Rails::ControllerTransaction
|
17
|
+
if ::Rails::VERSION::STRING >= "4.0.0"
|
18
|
+
Raven.safely_prepend(
|
19
|
+
"StreamingReporter",
|
20
|
+
:from => Raven::Rails::Overrides,
|
21
|
+
:to => ActionController::Live
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
initializer 'raven.action_view' do
|
28
|
+
ActiveSupport.on_load :action_view do
|
29
|
+
Raven.safely_prepend(
|
30
|
+
"StreamingReporter",
|
31
|
+
:from => Raven::Rails::Overrides,
|
32
|
+
:to => ActionView::StreamingTemplateRenderer::Body
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
config.before_initialize do
|
38
|
+
Raven.configuration.logger = ::Rails.logger
|
39
|
+
end
|
40
|
+
|
41
|
+
config.after_initialize do
|
42
|
+
if Raven.configuration.rails_activesupport_breadcrumbs
|
43
|
+
require 'raven/breadcrumbs/activesupport'
|
44
|
+
Raven::ActiveSupportBreadcrumbs.inject
|
45
|
+
end
|
46
|
+
|
47
|
+
if Raven.configuration.rails_report_rescued_exceptions
|
48
|
+
require 'raven/integrations/rails/overrides/debug_exceptions_catcher'
|
49
|
+
if defined?(::ActionDispatch::DebugExceptions)
|
50
|
+
exceptions_class = ::ActionDispatch::DebugExceptions
|
51
|
+
elsif defined?(::ActionDispatch::ShowExceptions)
|
52
|
+
exceptions_class = ::ActionDispatch::ShowExceptions
|
53
|
+
end
|
54
|
+
|
55
|
+
Raven.safely_prepend(
|
56
|
+
"DebugExceptionsCatcher",
|
57
|
+
:from => Raven::Rails::Overrides,
|
58
|
+
:to => exceptions_class
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
initializer 'raven.active_job' do
|
64
|
+
ActiveSupport.on_load :active_job do
|
65
|
+
require 'raven/integrations/rails/active_job'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
rake_tasks do
|
70
|
+
require 'raven/integrations/tasks'
|
71
|
+
end
|
72
|
+
|
73
|
+
if defined?(runner)
|
74
|
+
runner do
|
75
|
+
Raven.capture
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Raven
|
2
|
+
class Rails
|
3
|
+
module ActiveJobExtensions
|
4
|
+
ALREADY_SUPPORTED_SENTRY_ADAPTERS = %w(
|
5
|
+
ActiveJob::QueueAdapters::SidekiqAdapter
|
6
|
+
ActiveJob::QueueAdapters::DelayedJobAdapter
|
7
|
+
).freeze
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
around_perform do |job, block|
|
12
|
+
capture_and_reraise_with_sentry(job, block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def capture_and_reraise_with_sentry(job, block)
|
18
|
+
block.call
|
19
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
20
|
+
return if rescue_with_handler(exception)
|
21
|
+
unless already_supported_by_specific_integration?(job)
|
22
|
+
Raven.capture_exception(exception, :extra => raven_context(job))
|
23
|
+
end
|
24
|
+
raise exception
|
25
|
+
ensure
|
26
|
+
Context.clear!
|
27
|
+
BreadcrumbBuffer.clear!
|
28
|
+
end
|
29
|
+
|
30
|
+
def already_supported_by_specific_integration?(job)
|
31
|
+
if ::Rails.version.to_f < 5.0
|
32
|
+
ALREADY_SUPPORTED_SENTRY_ADAPTERS.include?(job.class.queue_adapter.to_s)
|
33
|
+
else
|
34
|
+
ALREADY_SUPPORTED_SENTRY_ADAPTERS.include?(job.class.queue_adapter.class.to_s)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def raven_context(job)
|
39
|
+
ctx = {
|
40
|
+
:active_job => job.class.name,
|
41
|
+
:arguments => job.arguments,
|
42
|
+
:scheduled_at => job.scheduled_at,
|
43
|
+
:job_id => job.job_id,
|
44
|
+
:locale => job.locale
|
45
|
+
}
|
46
|
+
# Add provider_job_id details if Rails 5
|
47
|
+
if job.respond_to?(:provider_job_id)
|
48
|
+
ctx[:provider_job_id] = job.provider_job_id
|
49
|
+
end
|
50
|
+
|
51
|
+
ctx
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class ActiveJob::Base
|
58
|
+
include Raven::Rails::ActiveJobExtensions
|
59
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Raven
|
2
|
+
class Rails
|
3
|
+
module ControllerMethods
|
4
|
+
def capture_message(message, options = {})
|
5
|
+
Raven::Rack.capture_message(message, request.env, options)
|
6
|
+
end
|
7
|
+
|
8
|
+
def capture_exception(exception, options = {})
|
9
|
+
Raven::Rack.capture_exception(exception, request.env, options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Raven
|
2
|
+
class Rails
|
3
|
+
module ControllerTransaction
|
4
|
+
def self.included(base)
|
5
|
+
base.around_action do |controller, block|
|
6
|
+
Raven.context.transaction.push "#{controller.class}##{controller.action_name}"
|
7
|
+
block.call
|
8
|
+
Raven.context.transaction.pop
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Raven
|
2
|
+
class Rails
|
3
|
+
module Overrides
|
4
|
+
module DebugExceptionsCatcher
|
5
|
+
def render_exception(env_or_request, exception)
|
6
|
+
begin
|
7
|
+
env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
|
8
|
+
Raven::Rack.capture_exception(exception, env)
|
9
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
10
|
+
end
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module OldDebugExceptionsCatcher
|
16
|
+
def self.included(base)
|
17
|
+
base.send(:alias_method_chain, :render_exception, :raven)
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_exception_with_raven(env_or_request, exception)
|
21
|
+
begin
|
22
|
+
env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
|
23
|
+
Raven::Rack.capture_exception(exception, env)
|
24
|
+
rescue # rubocop:disable Lint/HandleExceptions
|
25
|
+
end
|
26
|
+
render_exception_without_raven(env_or_request, exception)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Raven
|
2
|
+
class Rails
|
3
|
+
module Overrides
|
4
|
+
module StreamingReporter
|
5
|
+
def log_error(exception)
|
6
|
+
Raven.capture_exception(exception)
|
7
|
+
super
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module OldStreamingReporter
|
12
|
+
def self.included(base)
|
13
|
+
base.send(:alias_method_chain, :log_error, :raven)
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_error_with_raven(exception)
|
17
|
+
Raven.capture_exception(exception)
|
18
|
+
log_error_without_raven(exception)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'raven/integrations/rails'
|