Class: Contrast::Agent::Middleware

Inherits:
Object
  • Object
show all
Includes:
Components::Logger::InstanceMethods, Components::Scope::InstanceMethods, Utils::MiddlewareUtils, Utils::Reporting::ApplicationActivityBatchUtils
Defined in:
lib/contrast/agent/middleware/middleware.rb

Overview

This class allows the Agent to plug into the Rack middleware stack. When the application is first started, we initialize ourselves as a rack middleware inside of #initialize. Afterwards, we process each http request and response as it goes through the middleware stack inside of #call.

Constant Summary

Constants included from Utils::Reporting::ApplicationActivityBatchUtils

Utils::Reporting::ApplicationActivityBatchUtils::DEFAULT_REPORTING_INTERVAL_MS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils::Reporting::ApplicationActivityBatchUtils

#activity_batch, #add_activity_to_batch, #batch_age, #report_batch

Methods included from Components::Scope::InstanceMethods

#contrast_enter_method_scopes!, #contrast_exit_method_scopes!, #with_app_scope, #with_contrast_scope, #with_deserialization_scope, #with_split_scope

Methods included from Components::Logger::InstanceMethods

#cef_logger, #logger

Constructor Details

#initialize(app, _legacy_param = nil) ⇒ Middleware

Allows the Agent to function as a middleware. We perform all our one-time whole-app routines in here since we’re only going to be initialized a single time. Our initialization order is:

  • capture the application

  • setup the Agent

  • startup the Agent

Parameters:

  • app (Rack::Application)

    the application to be instrumented

  • _legacy_param (nil) (defaults to: nil)

    was a flag we no longer need, but Sinatra may call it



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/contrast/agent/middleware/middleware.rb', line 43

def initialize app, _legacy_param = nil
  @app = app  # THIS MUST BE FIRST AND ALWAYS SET!
  setup_agent # THIS MUST BE SECOND AND ALWAYS CALLED!
  unless ::Contrast::AGENT.enabled?
    logger.error('The Agent was unable to initialize before the application middleware was initialized. ' \
                 'Disabling permanently.')
    ::Contrast::AGENT.disable! # ensure the agent is disabled (probably redundant)
    return
  end
  agent_startup_routine
rescue StandardError => e
  logger.error('Unable to initialize the agent. Disabling permanently.', e)
  ::Contrast::AGENT.disable! # ensure the agent is disabled (probably redundant)
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



33
34
35
# File 'lib/contrast/agent/middleware/middleware.rb', line 33

def app
  @app
end

Instance Method Details

#call(env) ⇒ Array, Rack::Response

This is where we’re hooked into the middleware stack. If the agent is enabled, we’re ready to do some processing on a per request basis. If not, we just pass the request along to the next middleware in the stack. If Application Scope feature is enabled we execute the env call with that scope, enabling only analysis for the current application, and nothing outside that.

Parameters:

  • env (Hash)

    the various variables stored by this and other Middlewares to know the state and values of this Request

Returns:

  • (Array, Rack::Response)

    the Response of this and subsequent Middlewares to be passed back to the user up the Rack framework.



67
68
69
70
71
# File 'lib/contrast/agent/middleware/middleware.rb', line 67

def call env
  return with_app_scope { call_routine(env) } if Contrast::RUBY_INTERFACE.start_with_application_scope?

  call_routine(env)
end