Class: Appsignal::Rack::AbstractMiddleware Abstract Private

Inherits:
Object
  • Object
show all
Defined in:
lib/appsignal/rack/abstract_middleware.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

This class is abstract.

Base instrumentation middleware.

Do not use this middleware directly. Instead use InstrumentationMiddleware.

Constant Summary collapse

DEFAULT_ERROR_REPORTING =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

:default

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ AbstractMiddleware

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of AbstractMiddleware.



17
18
19
20
21
22
23
24
# File 'lib/appsignal/rack/abstract_middleware.rb', line 17

def initialize(app, options = {})
  Appsignal.internal_logger.debug "Initializing #{self.class}"
  @app = app
  @options = options
  @request_class = options.fetch(:request_class, ::Rack::Request)
  @instrument_event_name = options.fetch(:instrument_event_name, nil)
  @report_errors = options.fetch(:report_errors, DEFAULT_ERROR_REPORTING)
end

Instance Method Details

#call(env) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/appsignal/rack/abstract_middleware.rb', line 26

def call(env)
  if Appsignal.active?
    request = request_for(env)
    # Supported nested instrumentation middlewares by checking if there's
    # already a transaction active for this request.
    wrapped_instrumentation = env.key?(Appsignal::Rack::APPSIGNAL_TRANSACTION)
    transaction =
      if wrapped_instrumentation
        env[Appsignal::Rack::APPSIGNAL_TRANSACTION]
      else
        Appsignal::Transaction.create(Appsignal::Transaction::HTTP_REQUEST)
      end

    unless wrapped_instrumentation
      # Set transaction on the request environment so other nested
      # middleware can detect if there is parent instrumentation
      # middleware active.
      env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = transaction
    end

    begin
      (transaction, request)
      # Report errors if the :report_errors option is set to true or when
      # there is no parent instrumentation that can rescue and report the error.
      if @report_errors || !wrapped_instrumentation
        instrument_app_call_with_exception_handling(
          request.env,
          transaction,
          wrapped_instrumentation
        )
      else
        instrument_app_call(request.env, transaction)
      end
    ensure
      (transaction, request)

      # Complete transaction because this is the top instrumentation middleware.
      Appsignal::Transaction.complete_current! unless wrapped_instrumentation
    end
  else
    @app.call(env)
  end
end