Class: ScoutApm::Instant::DevTraceResponseManipulator
- Inherits:
-
Object
- Object
- ScoutApm::Instant::DevTraceResponseManipulator
- Defined in:
- lib/scout_apm/instant/middleware.rb
Instance Attribute Summary collapse
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#rack_body ⇒ Object
readonly
Returns the value of attribute rack_body.
-
#rack_headers ⇒ Object
readonly
Returns the value of attribute rack_headers.
-
#rack_response ⇒ Object
readonly
Returns the value of attribute rack_response.
-
#rack_status ⇒ Object
readonly
Returns the value of attribute rack_status.
Instance Method Summary collapse
- #adjust_ajax_header ⇒ Object
- #adjust_html_response ⇒ Object
-
#adjust_newer_rails_response ⇒ Object
Preserve the ActionDispatch::Response object we’re working with.
- #adjust_older_rails_response ⇒ Object
- #adjust_rack_proxy_response ⇒ Object
- #ajax_request? ⇒ Boolean
- #apm_host ⇒ Object
- #call ⇒ Object
- #content_type ⇒ Object
- #dev_trace_disabled? ⇒ Boolean
- #development_asset? ⇒ Boolean
- #html_manipulator ⇒ Object
-
#initialize(env, rack_response) ⇒ DevTraceResponseManipulator
constructor
A new instance of DevTraceResponseManipulator.
-
#logger ⇒ Object
APM Helpers & Shorthands #.
- #newer_rails_response? ⇒ Boolean
- #older_rails_response? ⇒ Boolean
- #path ⇒ Object
- #payload ⇒ Object
-
#preconditions_met? ⇒ Boolean
Precondition checking #.
- #rack_proxy_response? ⇒ Boolean
-
#rebuild_rack_response ⇒ Object
Response Injection #.
- #trace ⇒ Object
- #tracked_request ⇒ Object
Constructor Details
#initialize(env, rack_response) ⇒ DevTraceResponseManipulator
Returns a new instance of DevTraceResponseManipulator.
69 70 71 72 73 74 75 76 |
# File 'lib/scout_apm/instant/middleware.rb', line 69 def initialize(env, rack_response) @env = env @rack_response = rack_response @rack_status = rack_response[0] @rack_headers = rack_response[1] @rack_body = rack_response[2] end |
Instance Attribute Details
#env ⇒ Object (readonly)
Returns the value of attribute env.
67 68 69 |
# File 'lib/scout_apm/instant/middleware.rb', line 67 def env @env end |
#rack_body ⇒ Object (readonly)
Returns the value of attribute rack_body.
66 67 68 |
# File 'lib/scout_apm/instant/middleware.rb', line 66 def rack_body @rack_body end |
#rack_headers ⇒ Object (readonly)
Returns the value of attribute rack_headers.
66 67 68 |
# File 'lib/scout_apm/instant/middleware.rb', line 66 def rack_headers @rack_headers end |
#rack_response ⇒ Object (readonly)
Returns the value of attribute rack_response.
65 66 67 |
# File 'lib/scout_apm/instant/middleware.rb', line 65 def rack_response @rack_response end |
#rack_status ⇒ Object (readonly)
Returns the value of attribute rack_status.
66 67 68 |
# File 'lib/scout_apm/instant/middleware.rb', line 66 def rack_status @rack_status end |
Instance Method Details
#adjust_ajax_header ⇒ Object
130 131 132 |
# File 'lib/scout_apm/instant/middleware.rb', line 130 def adjust_ajax_header rack_headers['X-scoutapminstant'] = payload end |
#adjust_html_response ⇒ Object
134 135 136 137 138 139 140 141 142 |
# File 'lib/scout_apm/instant/middleware.rb', line 134 def adjust_html_response case true when older_rails_response? then adjust_older_rails_response when newer_rails_response? then adjust_newer_rails_response when rack_proxy_response? then adjust_rack_proxy_response else # No action taken, we only adjust if we know exactly what we have. end end |
#adjust_newer_rails_response ⇒ Object
Preserve the ActionDispatch::Response object we’re working with
166 167 168 169 |
# File 'lib/scout_apm/instant/middleware.rb', line 166 def adjust_newer_rails_response logger.debug("DevTrace: in middleware, dev_trace is active, and response has a (newer) body. This appears to be an HTML page and an ActionDispatch::Response. Path=#{path}; ContentType=#{content_type}") @rack_body = [ html_manipulator.res ] end |
#adjust_older_rails_response ⇒ Object
160 161 162 163 |
# File 'lib/scout_apm/instant/middleware.rb', line 160 def adjust_older_rails_response logger.debug("DevTrace: in middleware, dev_trace is active, and response has a (older) body. This appears to be an HTML page and an ActionDispatch::Response. Path=#{path}; ContentType=#{content_type}") rack_body.body = [ html_manipulator.res ] end |
#adjust_rack_proxy_response ⇒ Object
171 172 173 174 175 |
# File 'lib/scout_apm/instant/middleware.rb', line 171 def adjust_rack_proxy_response logger.debug("DevTrace: in middleware, dev_trace is active, and response has a body. This appears to be an HTML page and an Rack::BodyProxy. Path=#{path}; ContentType=#{content_type}") @rack_body = [ html_manipulator.res ] @rack_headers.delete("Content-Length") end |
#ajax_request? ⇒ Boolean
194 195 196 |
# File 'lib/scout_apm/instant/middleware.rb', line 194 def ajax_request? env['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' || content_type.include?("application/json") end |
#apm_host ⇒ Object
222 223 224 |
# File 'lib/scout_apm/instant/middleware.rb', line 222 def apm_host ScoutApm::Agent.instance.context.config.value("direct_host") end |
#call ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/scout_apm/instant/middleware.rb', line 78 def call return rack_response unless preconditions_met? if ajax_request? ScoutApm::Agent.instance.context.logger.debug("DevTrace: in middleware, dev_trace is active, and response has a body. This is either AJAX or JSON. Path=#{path}; ContentType=#{content_type}") adjust_ajax_header else adjust_html_response end rebuild_rack_response end |
#content_type ⇒ Object
206 207 208 |
# File 'lib/scout_apm/instant/middleware.rb', line 206 def content_type rack_headers['Content-Type'] end |
#dev_trace_disabled? ⇒ Boolean
118 119 120 |
# File 'lib/scout_apm/instant/middleware.rb', line 118 def dev_trace_disabled? ! ScoutApm::Agent.instance.context.config.value('dev_trace') end |
#development_asset? ⇒ Boolean
198 199 200 |
# File 'lib/scout_apm/instant/middleware.rb', line 198 def development_asset? !rack_body.respond_to?(:body) end |
#html_manipulator ⇒ Object
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/scout_apm/instant/middleware.rb', line 177 def html_manipulator @html_manipulator ||= begin page = ScoutApm::Instant::Page.new(rack_body.body) # This monkey-patches XMLHttpRequest. It could possibly be part of the main scout_instant.js too. Putting it here so it runs as soon as possible. page.add_to_head(ScoutApm::Instant::Util.read_asset("xmlhttp_instrumentation.html")) # Add a link to CSS, then JS page.add_to_head("<link href='#{apm_host}/instant/scout_instant.css?cachebust=#{Time.now.to_i}' media='all' rel='stylesheet' />") page.add_to_body("<script src='#{apm_host}/instant/scout_instant.js?cachebust=#{Time.now.to_i}'></script>") page.add_to_body("<script>var scoutInstantPageTrace=#{payload};window.scoutInstant=window.scoutInstant('#{apm_host}', scoutInstantPageTrace)</script>") page end end |
#logger ⇒ Object
APM Helpers & Shorthands #
214 215 216 |
# File 'lib/scout_apm/instant/middleware.rb', line 214 def logger ScoutApm::Agent.instance.context.logger end |
#newer_rails_response? ⇒ Boolean
150 151 152 153 154 |
# File 'lib/scout_apm/instant/middleware.rb', line 150 def newer_rails_response? if defined?(ActionDispatch::Response::RackBody) return true if rack_body.is_a?(ActionDispatch::Response::RackBody) end end |
#older_rails_response? ⇒ Boolean
144 145 146 147 148 |
# File 'lib/scout_apm/instant/middleware.rb', line 144 def older_rails_response? if defined?(ActionDispatch::Response) return true if rack_body.is_a?(ActionDispatch::Response) end end |
#path ⇒ Object
202 203 204 |
# File 'lib/scout_apm/instant/middleware.rb', line 202 def path env['PATH_INFO'] end |
#payload ⇒ Object
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/scout_apm/instant/middleware.rb', line 235 def payload @payload ||= begin = { :app_root => ScoutApm::Agent.instance.context.environment.root.to_s, :unique_id => env['action_dispatch.request_id'], # note, this is a different unique_id than what "normal" payloads use :agent_version => ScoutApm::VERSION, :platform => "ruby", } hash = ScoutApm::Serializers::PayloadSerializerToJson. rearrange_slow_transaction(trace). merge!(:metadata => ) ScoutApm::Serializers::PayloadSerializerToJson.jsonify_hash(hash) end end |
#preconditions_met? ⇒ Boolean
Precondition checking #
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/scout_apm/instant/middleware.rb', line 95 def preconditions_met? if dev_trace_disabled? logger.debug("DevTrace: isn't activated via config. Try: SCOUT_DEV_TRACE=true rails server") return false end # Don't attempt to instrument assets. # Don't log this case, since it would be very noisy logger.debug("DevTrace: dev asset ignored") and return false if development_asset? # If we didn't have a tracked_request object, or we explicitly ignored # this request, don't do any work. logger.debug("DevTrace: no tracked request") and return false if tracked_request.nil? || tracked_request.ignoring_request? # If we didn't get a trace, we can't show a trace... if trace.nil? logger.debug("DevTrace: in middleware, dev_trace is active, and response has a body, but no trace was found. Path=#{path}; ContentType=#{content_type}") return false end true end |
#rack_proxy_response? ⇒ Boolean
156 157 158 |
# File 'lib/scout_apm/instant/middleware.rb', line 156 def rack_proxy_response? rack_body.is_a?(::Rack::BodyProxy) end |
#rebuild_rack_response ⇒ Object
Response Injection #
126 127 128 |
# File 'lib/scout_apm/instant/middleware.rb', line 126 def rebuild_rack_response [rack_status, rack_headers, rack_body] end |
#trace ⇒ Object
226 227 228 229 230 231 232 233 |
# File 'lib/scout_apm/instant/middleware.rb', line 226 def trace @trace ||= begin layer_finder = LayerConverters::FindLayerByType.new(tracked_request) converter = LayerConverters::SlowRequestConverter.new(ScoutApm::Agent.instance.context, tracked_request, layer_finder, ScoutApm::FakeStore.new) converter.call end end |
#tracked_request ⇒ Object
218 219 220 |
# File 'lib/scout_apm/instant/middleware.rb', line 218 def tracked_request @tracked_request ||= ScoutApm::RequestManager.lookup end |