opbeat 2.0.0 → 3.0.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 +4 -4
- data/.gitignore +4 -3
- data/.travis.yml +19 -28
- data/.yardopts +3 -0
- data/Gemfile +4 -2
- data/HISTORY.md +3 -0
- data/LICENSE +7 -196
- data/README.md +96 -177
- data/Rakefile +19 -13
- data/gemfiles/Gemfile.base +28 -0
- data/gemfiles/Gemfile.rails-3.2.x +3 -0
- data/gemfiles/Gemfile.rails-4.0.x +3 -0
- data/gemfiles/Gemfile.rails-4.1.x +3 -0
- data/gemfiles/Gemfile.rails-4.2.x +3 -0
- data/lib/opbeat.rb +113 -93
- data/lib/opbeat/capistrano.rb +3 -4
- data/lib/opbeat/client.rb +243 -82
- data/lib/opbeat/configuration.rb +51 -64
- data/lib/opbeat/data_builders.rb +16 -0
- data/lib/opbeat/data_builders/error.rb +27 -0
- data/lib/opbeat/data_builders/transactions.rb +85 -0
- data/lib/opbeat/error.rb +1 -2
- data/lib/opbeat/error_message.rb +71 -0
- data/lib/opbeat/error_message/exception.rb +12 -0
- data/lib/opbeat/error_message/http.rb +62 -0
- data/lib/opbeat/error_message/stacktrace.rb +75 -0
- data/lib/opbeat/error_message/user.rb +23 -0
- data/lib/opbeat/filter.rb +53 -43
- data/lib/opbeat/http_client.rb +141 -0
- data/lib/opbeat/injections.rb +83 -0
- data/lib/opbeat/injections/json.rb +19 -0
- data/lib/opbeat/injections/net_http.rb +43 -0
- data/lib/opbeat/injections/redis.rb +23 -0
- data/lib/opbeat/injections/sequel.rb +32 -0
- data/lib/opbeat/injections/sinatra.rb +56 -0
- data/lib/opbeat/{capistrano → integration}/capistrano2.rb +6 -6
- data/lib/opbeat/{capistrano → integration}/capistrano3.rb +3 -3
- data/lib/opbeat/{integrations → integration}/delayed_job.rb +6 -11
- data/lib/opbeat/integration/rails/inject_exceptions_catcher.rb +23 -0
- data/lib/opbeat/integration/railtie.rb +53 -0
- data/lib/opbeat/integration/resque.rb +16 -0
- data/lib/opbeat/integration/sidekiq.rb +38 -0
- data/lib/opbeat/line_cache.rb +21 -0
- data/lib/opbeat/logging.rb +37 -0
- data/lib/opbeat/middleware.rb +59 -0
- data/lib/opbeat/normalizers.rb +65 -0
- data/lib/opbeat/normalizers/action_controller.rb +21 -0
- data/lib/opbeat/normalizers/action_view.rb +71 -0
- data/lib/opbeat/normalizers/active_record.rb +41 -0
- data/lib/opbeat/sql_summarizer.rb +27 -0
- data/lib/opbeat/subscriber.rb +80 -0
- data/lib/opbeat/tasks.rb +20 -18
- data/lib/opbeat/trace.rb +47 -0
- data/lib/opbeat/trace_helpers.rb +29 -0
- data/lib/opbeat/transaction.rb +99 -0
- data/lib/opbeat/util.rb +26 -0
- data/lib/opbeat/util/constantize.rb +54 -0
- data/lib/opbeat/util/inspector.rb +75 -0
- data/lib/opbeat/version.rb +1 -1
- data/lib/opbeat/worker.rb +55 -0
- data/opbeat.gemspec +6 -14
- data/spec/opbeat/client_spec.rb +216 -29
- data/spec/opbeat/configuration_spec.rb +34 -38
- data/spec/opbeat/data_builders/error_spec.rb +43 -0
- data/spec/opbeat/data_builders/transactions_spec.rb +51 -0
- data/spec/opbeat/error_message/exception_spec.rb +22 -0
- data/spec/opbeat/error_message/http_spec.rb +65 -0
- data/spec/opbeat/error_message/stacktrace_spec.rb +56 -0
- data/spec/opbeat/error_message/user_spec.rb +28 -0
- data/spec/opbeat/error_message_spec.rb +78 -0
- data/spec/opbeat/filter_spec.rb +21 -99
- data/spec/opbeat/http_client_spec.rb +64 -0
- data/spec/opbeat/injections/net_http_spec.rb +37 -0
- data/spec/opbeat/injections/sequel_spec.rb +33 -0
- data/spec/opbeat/injections/sinatra_spec.rb +13 -0
- data/spec/opbeat/injections_spec.rb +49 -0
- data/spec/opbeat/integration/delayed_job_spec.rb +35 -0
- data/spec/opbeat/integration/json_spec.rb +41 -0
- data/spec/opbeat/integration/rails_spec.rb +88 -0
- data/spec/opbeat/integration/redis_spec.rb +20 -0
- data/spec/opbeat/integration/resque_spec.rb +42 -0
- data/spec/opbeat/integration/sidekiq_spec.rb +40 -0
- data/spec/opbeat/integration/sinatra_spec.rb +66 -0
- data/spec/opbeat/line_cache_spec.rb +38 -0
- data/spec/opbeat/logging_spec.rb +47 -0
- data/spec/opbeat/middleware_spec.rb +32 -0
- data/spec/opbeat/normalizers/action_controller_spec.rb +32 -0
- data/spec/opbeat/normalizers/action_view_spec.rb +77 -0
- data/spec/opbeat/normalizers/active_record_spec.rb +70 -0
- data/spec/opbeat/normalizers_spec.rb +16 -0
- data/spec/opbeat/sql_summarizer_spec.rb +6 -0
- data/spec/opbeat/subscriber_spec.rb +83 -0
- data/spec/opbeat/trace_spec.rb +43 -0
- data/spec/opbeat/transaction_spec.rb +98 -0
- data/spec/opbeat/util/inspector_spec.rb +40 -0
- data/spec/opbeat/util_spec.rb +20 -0
- data/spec/opbeat/worker_spec.rb +54 -0
- data/spec/opbeat_spec.rb +49 -0
- data/spec/spec_helper.rb +79 -6
- metadata +89 -149
- data/Makefile +0 -3
- data/gemfiles/rails30.gemfile +0 -9
- data/gemfiles/rails31.gemfile +0 -9
- data/gemfiles/rails32.gemfile +0 -9
- data/gemfiles/rails40.gemfile +0 -9
- data/gemfiles/rails41.gemfile +0 -9
- data/gemfiles/rails42.gemfile +0 -9
- data/gemfiles/ruby192_rails31.gemfile +0 -10
- data/gemfiles/ruby192_rails32.gemfile +0 -10
- data/gemfiles/sidekiq31.gemfile +0 -11
- data/lib/opbeat/better_attr_accessor.rb +0 -44
- data/lib/opbeat/event.rb +0 -223
- data/lib/opbeat/integrations/resque.rb +0 -22
- data/lib/opbeat/integrations/sidekiq.rb +0 -32
- data/lib/opbeat/interfaces.rb +0 -35
- data/lib/opbeat/interfaces/exception.rb +0 -16
- data/lib/opbeat/interfaces/http.rb +0 -57
- data/lib/opbeat/interfaces/message.rb +0 -19
- data/lib/opbeat/interfaces/stack_trace.rb +0 -50
- data/lib/opbeat/linecache.rb +0 -25
- data/lib/opbeat/logger.rb +0 -21
- data/lib/opbeat/rack.rb +0 -46
- data/lib/opbeat/rails/middleware/debug_exceptions_catcher.rb +0 -22
- data/lib/opbeat/railtie.rb +0 -26
- data/spec/opbeat/better_attr_accessor_spec.rb +0 -99
- data/spec/opbeat/event_spec.rb +0 -138
- data/spec/opbeat/integrations/delayed_job_spec.rb +0 -38
- data/spec/opbeat/logger_spec.rb +0 -55
- data/spec/opbeat/opbeat_spec.rb +0 -64
- data/spec/opbeat/rack_spec.rb +0 -117
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Opbeat
|
|
2
|
+
module Injections
|
|
3
|
+
module Sequel
|
|
4
|
+
class Injector
|
|
5
|
+
KIND = 'db.sequel.sql'.freeze
|
|
6
|
+
|
|
7
|
+
def self.sql_parser
|
|
8
|
+
@sql_parser ||= SqlSummarizer.new(nil)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def install
|
|
12
|
+
require 'sequel/database/logging'
|
|
13
|
+
|
|
14
|
+
::Sequel::Database.class_eval do
|
|
15
|
+
alias log_yield_without_opb log_yield
|
|
16
|
+
|
|
17
|
+
def log_yield sql, args = nil, &block
|
|
18
|
+
log_yield_without_opb(sql, *args) do
|
|
19
|
+
sig = Opbeat::Injections::Sequel::Injector.sql_parser.signature_for(sql)
|
|
20
|
+
Opbeat.trace(sig, KIND, sql: sql) do
|
|
21
|
+
block.call
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
register 'Sequel', 'sequel', Sequel::Injector.new
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Opbeat
|
|
2
|
+
module Injections
|
|
3
|
+
module Sinatra
|
|
4
|
+
class Injector
|
|
5
|
+
def install
|
|
6
|
+
::Sinatra::Base.class_eval do
|
|
7
|
+
alias dispatch_without_opb! dispatch!
|
|
8
|
+
alias compile_template_with_opb compile_template
|
|
9
|
+
|
|
10
|
+
def dispatch!(*args, &block)
|
|
11
|
+
dispatch_without_opb!(*args, &block).tap do
|
|
12
|
+
if route = env['sinatra.route']
|
|
13
|
+
Opbeat.transaction(nil).endpoint = route
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def compile_template engine, data, opts, *args, &block
|
|
19
|
+
case data
|
|
20
|
+
when Symbol
|
|
21
|
+
opts[:__opbeat_template_sig] = data.to_s
|
|
22
|
+
else
|
|
23
|
+
opts[:__opbeat_template_sig] = "Inline #{engine}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
compile_template_with_opb(engine, data, opts, *args, &block)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Tilt
|
|
34
|
+
class Injector
|
|
35
|
+
KIND = 'template.view'
|
|
36
|
+
|
|
37
|
+
def install
|
|
38
|
+
::Tilt::Template.class_eval do
|
|
39
|
+
alias render_without_opb render
|
|
40
|
+
|
|
41
|
+
def render(*args, &block)
|
|
42
|
+
sig = options[:__opbeat_template_sig] || 'Uknown template'.freeze
|
|
43
|
+
|
|
44
|
+
Opbeat.trace sig, KIND do
|
|
45
|
+
render_without_opb(*args, &block)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
register 'Sinatra::Base', 'sinatra/base', Sinatra::Injector.new
|
|
54
|
+
register 'Tilt::Template', 'tilt/template', Tilt::Injector.new
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
require 'capistrano'
|
|
2
|
-
|
|
3
1
|
module Opbeat
|
|
2
|
+
# @api private
|
|
4
3
|
module Capistrano
|
|
5
4
|
def self.load_into(configuration)
|
|
6
5
|
|
|
@@ -17,13 +16,13 @@ module Opbeat
|
|
|
17
16
|
puts "Skipping Opbeat deployment notification because scm is not git."
|
|
18
17
|
next
|
|
19
18
|
end
|
|
20
|
-
|
|
19
|
+
|
|
21
20
|
branches = capture("cd #{current_release}; /usr/bin/env git branch --contains #{current_revision}").split
|
|
22
21
|
if branches.length == 1
|
|
23
22
|
branch = branch[0].sub("* ")
|
|
24
23
|
else
|
|
25
24
|
branch = nil
|
|
26
|
-
end
|
|
25
|
+
end
|
|
27
26
|
|
|
28
27
|
notify_command = "cd #{current_release}; REV=#{current_revision} "
|
|
29
28
|
notify_command << "BRANCH=#{branch} " if branch
|
|
@@ -32,9 +31,9 @@ module Opbeat
|
|
|
32
31
|
notify_command << "RAILS_ENV=#{rails_env} "
|
|
33
32
|
|
|
34
33
|
executable = fetch(:rake, 'bundle exec rake ')
|
|
35
|
-
notify_command << "#{executable} opbeat:
|
|
34
|
+
notify_command << "#{executable} opbeat:release"
|
|
36
35
|
capture notify_command, :once => true
|
|
37
|
-
|
|
36
|
+
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
end
|
|
@@ -45,3 +44,4 @@ end
|
|
|
45
44
|
if Capistrano::Configuration.instance
|
|
46
45
|
Opbeat::Capistrano.load_into(Capistrano::Configuration.instance)
|
|
47
46
|
end
|
|
47
|
+
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
namespace :opbeat do
|
|
2
|
-
desc "Notifies Opbeat of new
|
|
2
|
+
desc "Notifies Opbeat of new releases"
|
|
3
3
|
task :notify do
|
|
4
4
|
on roles(:app) do
|
|
5
5
|
|
|
6
6
|
scm = fetch(:scm)
|
|
7
7
|
if scm.to_s != "git"
|
|
8
|
-
info "Skipping Opbeat
|
|
8
|
+
info "Skipping Opbeat release because scm is not git."
|
|
9
9
|
next
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -14,7 +14,7 @@ namespace :opbeat do
|
|
|
14
14
|
|
|
15
15
|
within release_path do
|
|
16
16
|
with rails_env: fetch(:rails_env), rev: rev, branch: branch do
|
|
17
|
-
capture :rake, 'opbeat:
|
|
17
|
+
capture :rake, 'opbeat:release'
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
end
|
|
@@ -3,23 +3,19 @@ begin
|
|
|
3
3
|
rescue LoadError
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
-
# Based on the Sentry equivalent.
|
|
7
6
|
if defined?(Delayed)
|
|
8
|
-
|
|
9
7
|
module Delayed
|
|
10
8
|
module Plugins
|
|
11
|
-
class Opbeat <
|
|
9
|
+
class Opbeat < Delayed::Plugin
|
|
12
10
|
callbacks do |lifecycle|
|
|
13
11
|
lifecycle.around(:invoke_job) do |job, *args, &block|
|
|
14
12
|
begin
|
|
15
|
-
# Forward the call to the next callback in the callback chain
|
|
16
13
|
block.call(job, *args)
|
|
17
|
-
|
|
14
|
+
rescue ::Opbeat::Error
|
|
15
|
+
raise # don't report Opbeat errors
|
|
18
16
|
rescue Exception => exception
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# Make sure we propagate the failure!
|
|
22
|
-
raise exception
|
|
17
|
+
::Opbeat.report exception
|
|
18
|
+
raise
|
|
23
19
|
end
|
|
24
20
|
end
|
|
25
21
|
end
|
|
@@ -27,6 +23,5 @@ if defined?(Delayed)
|
|
|
27
23
|
end
|
|
28
24
|
end
|
|
29
25
|
|
|
30
|
-
# Register DelayedJob Opbeat plugin
|
|
31
26
|
Delayed::Worker.plugins << Delayed::Plugins::Opbeat
|
|
32
|
-
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Opbeat
|
|
2
|
+
module Integration
|
|
3
|
+
module Rails
|
|
4
|
+
module InjectExceptionsCatcher
|
|
5
|
+
def self.included(cls)
|
|
6
|
+
cls.send(:alias_method_chain, :render_exception, :opbeat)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def render_exception_with_opbeat(env, exception)
|
|
10
|
+
begin
|
|
11
|
+
Opbeat.report(exception, rack_env: env) if Opbeat.started?
|
|
12
|
+
rescue
|
|
13
|
+
::Rails::logger.error "** [Opbeat] Error capturing or sending exception #{$!}"
|
|
14
|
+
::Rails::logger.debug $!.backtrace.join("\n")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
render_exception_without_opbeat(env, exception)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'opbeat'
|
|
2
|
+
require 'rails'
|
|
3
|
+
|
|
4
|
+
module Opbeat
|
|
5
|
+
class Railtie < Rails::Railtie
|
|
6
|
+
|
|
7
|
+
config.opbeat = ActiveSupport::OrderedOptions.new
|
|
8
|
+
# bootstrap options with the defaults
|
|
9
|
+
Configuration::DEFAULTS.each { |k,v| config.opbeat[k] = v }
|
|
10
|
+
|
|
11
|
+
initializer "opbeat.configure" do |app|
|
|
12
|
+
config = Configuration.new app.config.opbeat do |conf|
|
|
13
|
+
conf.logger = Rails.logger
|
|
14
|
+
conf.view_paths = app.config.paths['app/views'].existent
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if config.enabled_environments.include?(Rails.env)
|
|
18
|
+
if Opbeat.start!(config)
|
|
19
|
+
app.config.middleware.insert 0, Middleware
|
|
20
|
+
Rails.logger.info "** [Opbeat] Client running"
|
|
21
|
+
else
|
|
22
|
+
# :nocov:
|
|
23
|
+
Rails.logger.info "** [Opbeat] Failed to start"
|
|
24
|
+
# :nocov:
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
# :nocov:
|
|
28
|
+
Rails.logger.info "** [Opbeat] Disabled in #{Rails.env} environment"
|
|
29
|
+
# :nocov:
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
config.after_initialize do
|
|
34
|
+
# :nocov:
|
|
35
|
+
require 'opbeat/integration/rails/inject_exceptions_catcher'
|
|
36
|
+
if defined?(ActionDispatch::DebugExceptions)
|
|
37
|
+
ActionDispatch::DebugExceptions.send(
|
|
38
|
+
:include, Opbeat::Integration::Rails::InjectExceptionsCatcher)
|
|
39
|
+
elsif defined?(::ActionDispatch::ShowExceptions)
|
|
40
|
+
::ActionDispatch::ShowExceptions.send(
|
|
41
|
+
:include, Opbeat::Integration::Rails::InjectExceptionsCatcher)
|
|
42
|
+
end
|
|
43
|
+
# :nocov:
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
rake_tasks do
|
|
47
|
+
# :nocov:
|
|
48
|
+
require 'opbeat/tasks'
|
|
49
|
+
# :nocov:
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'sidekiq'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
if defined? Sidekiq
|
|
7
|
+
module Opbeat
|
|
8
|
+
module Integration
|
|
9
|
+
class Sidekiq
|
|
10
|
+
def call worker, msg, queue
|
|
11
|
+
begin
|
|
12
|
+
yield
|
|
13
|
+
rescue Exception => exception
|
|
14
|
+
if [Interrupt, SystemExit, SignalException].include? exception.class
|
|
15
|
+
raise exception
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Opbeat.report exception
|
|
19
|
+
|
|
20
|
+
raise
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Sidekiq.configure_server do |config|
|
|
28
|
+
if Sidekiq::VERSION.to_i < 3
|
|
29
|
+
config.server_middleware do |chain|
|
|
30
|
+
chain.add Opbeat::Integration::Sidekiq
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
config.error_handlers << lambda do |exception|
|
|
34
|
+
Opbeat.report exception
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Opbeat
|
|
2
|
+
# @api private
|
|
3
|
+
class LineCache
|
|
4
|
+
|
|
5
|
+
CACHE = {}
|
|
6
|
+
|
|
7
|
+
def self.all path
|
|
8
|
+
CACHE[path] ||= begin
|
|
9
|
+
File.readlines(path)
|
|
10
|
+
rescue
|
|
11
|
+
[]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.find path, line
|
|
16
|
+
return nil if line < 1
|
|
17
|
+
all(path)[line - 1]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Opbeat
|
|
2
|
+
# @api private
|
|
3
|
+
module Logging
|
|
4
|
+
PREFIX = "** [Opbeat] ".freeze
|
|
5
|
+
|
|
6
|
+
def debug *args, &block
|
|
7
|
+
config.logger.debug(log_message(*args, &block)) if has_logger?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def info *args, &block
|
|
11
|
+
config.logger.info(log_message(*args, &block)) if has_logger?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def warn *args, &block
|
|
15
|
+
config.logger.warn(log_message(*args, &block)) if has_logger?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def error *args, &block
|
|
19
|
+
config.logger.error(log_message(*args, &block)) if has_logger?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def fatal *args, &block
|
|
23
|
+
config.logger.fatal(log_message(*args, &block)) if has_logger?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def has_logger?
|
|
29
|
+
respond_to?(:config) && config && config.logger
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def log_message *args, &block
|
|
33
|
+
msg = block_given? && block.call || args.first
|
|
34
|
+
"#{PREFIX}#{msg}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Opbeat
|
|
2
|
+
class Middleware
|
|
3
|
+
def initialize app
|
|
4
|
+
@app = app
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def call env
|
|
8
|
+
begin
|
|
9
|
+
transaction = Opbeat.transaction "Rack", "app.rack.request"
|
|
10
|
+
resp = @app.call env
|
|
11
|
+
resp[2] = BodyProxy.new(resp[2]) { transaction.submit(resp[0]) } if transaction
|
|
12
|
+
rescue Error
|
|
13
|
+
raise # Don't report Opbeat errors
|
|
14
|
+
rescue Exception => e
|
|
15
|
+
Opbeat.report e, rack_env: env
|
|
16
|
+
transaction.submit(500) if transaction
|
|
17
|
+
raise
|
|
18
|
+
ensure
|
|
19
|
+
transaction.release if transaction
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if error = env['rack.exception'] || env['sinatra.error']
|
|
23
|
+
Opbeat.report error, rack_env: env
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
resp
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class BodyProxy
|
|
31
|
+
def initialize body, &block
|
|
32
|
+
@body, @block, @closed = body, block, false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def respond_to? *args
|
|
36
|
+
super || @body.respond_to?(*args)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def close
|
|
40
|
+
return if closed?
|
|
41
|
+
|
|
42
|
+
@closed = true
|
|
43
|
+
|
|
44
|
+
begin
|
|
45
|
+
@body.close if @body.respond_to?(:close)
|
|
46
|
+
ensure
|
|
47
|
+
@block.call
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def closed?
|
|
52
|
+
@closed
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def method_missing *args, &block
|
|
56
|
+
@body.__send__(*args, &block)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|