Class: Raygun::Apm::Rails::Middleware
- Inherits:
-
Object
- Object
- Raygun::Apm::Rails::Middleware
- Defined in:
- lib/raygun/apm/rails/middleware.rb
Class Method Summary collapse
Instance Method Summary collapse
- #call(env) ⇒ Object
- #http_in_handler(args) ⇒ Object
-
#initialize(app) ⇒ Middleware
constructor
A new instance of Middleware.
- #instrument(env) ⇒ Object
- #raygun_shutdown_handler(exception) ⇒ Object
- #sql_handler(args) ⇒ Object
Constructor Details
#initialize(app) ⇒ Middleware
Returns a new instance of Middleware.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/raygun/apm/rails/middleware.rb', line 5 def initialize(app) @app = app @tracer = Raygun::Apm::Tracer.new @tracer.udp_sink! @tracer.process_started ObjectSpace.define_finalizer(self, self.class.finalize(@tracer)) @http_in_subscriber = ActiveSupport::Notifications.subscribe('process_action.action_controller') do |*args| http_in_handler(args) end @sql_subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |*args| sql_handler(args) end # If any fatal errors on init, shutdown the tracer rescue Raygun::Apm::FatalError => e raygun_shutdown_handler(e) end |
Class Method Details
.finalize(tracer) ⇒ Object
100 101 102 |
# File 'lib/raygun/apm/rails/middleware.rb', line 100 def self.finalize(tracer) proc {tracer.process_ended} end |
Instance Method Details
#call(env) ⇒ Object
24 25 26 27 |
# File 'lib/raygun/apm/rails/middleware.rb', line 24 def call(env) @status, @headers, @response = instrument(env) [@status, @headers, @response] end |
#http_in_handler(args) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/raygun/apm/rails/middleware.rb', line 52 def http_in_handler(args) notification = ActiveSupport::Notifications::Event.new *args if notification.payload[:exception] # XXX notify? return end req = Rack::Request.new notification.payload[:headers].env event = Raygun::Apm::Event::HttpIn.new event[:url] = req.url event[:verb] = req.request_method event[:status] = notification.payload[:status] # XXX constant milliseconds to microseconds event[:duration] = notification.duration * 1000 event[:timestamp] = Time.now.to_f*1000000 event[:pid] = Process.pid event[:tid] = @tracer.get_thread_id(Thread.current) @tracer.emit(event) rescue => e # XXX report end |
#instrument(env) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/raygun/apm/rails/middleware.rb', line 29 def instrument(env) res = nil # Can be nil if we had a fatal error @tracer.start_trace if @tracer res = @app.call(env) # Can be nil if we had a fatal error @tracer.end_trace if @tracer res rescue Raygun::APM::FatalError => e raygun_shutdown_handler(e) end |
#raygun_shutdown_handler(exception) ⇒ Object
41 42 43 44 45 46 47 48 49 50 |
# File 'lib/raygun/apm/rails/middleware.rb', line 41 def raygun_shutdown_handler(exception) warn "Raygun APM shutting down due to error - %s", e. # Kill extended event subcriptions ActiveSupport::Notifications.unsubscribe(@http_in_subscriber) ActiveSupport::Notifications.unsubscribe(@sql_subscriber) # Shutdown the tracepoint if enabled to reduce any overhead and stall emission @tracer.tracepoint.stop if @tracer.tracepoint.enabled? # Let the GC clean up the sink thread through the finalizer below @tracer = nil end |
#sql_handler(args) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/raygun/apm/rails/middleware.rb', line 73 def sql_handler(args) notification = ActiveSupport::Notifications::Event.new *args connection = if notification.payload[:connection] notification.payload[:connection] else ObjectSpace._id2ref(notification.payload[:connection_id]) end event = Raygun::Apm::Event::Sql.new event[:query] = notification.payload[:sql] # XXX this is hacky if config = connection.instance_variable_get('@config') event[:provider] = config[:adapter] event[:host] = config[:host] event[:database] = config[:database] end # XXX constant milliseconds to microseconds event[:duration] = notification.duration * 1000 event[:timestamp] = Time.now.to_f*1000000 event[:pid] = Process.pid event[:tid] = @tracer.get_thread_id(Thread.current) @tracer.emit(event) rescue => e # XXX report end |