Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record status codes when middleware instrumentation is disabled #2175

Merged
merged 20 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# New Relic Ruby Agent Release Notes


## dev

Version <dev> allows the agent to record the http status code on a transaction when middleware instrumentation is disabled and fixes a bug in `NewRelic::Rack::AgentHooks.needed?`.
tannalynn marked this conversation as resolved.
Show resolved Hide resolved


- **Feature: Report transaction HTTP status codes when middleware instrumentation is disabled**
Previously, when `disable_middleware_instrumentation` was set to `true`, the agent would not record the value of the response code or content type on the transaction. This was due to the possibility that a middleware could alter the response, which would not be captured by the agent when the middleware instrumentation was disabled. However, based on customer feedback, the agent will now report the HTTP status code and content type on a transaction when middleware instrumentation is disabled. [PR#2175](https://github.com/newrelic/newrelic-ruby-agent/pull/2175)
tannalynn marked this conversation as resolved.
Show resolved Hide resolved

- **Bugfix: Resolve inverted logic of NewRelic::Rack::AgentHooks.needed?**
Previously, `NewRelic::Rack::AgentHooks.needed?` incorrectly used inverted logic. This has now been resolved, allowing AgentHooks to be installed when `disable_middleware_instrumentation` is set to true. [PR#2175](https://github.com/newrelic/newrelic-ruby-agent/pull/2175)


## v9.4.2

Version 9.4.2 of the agent re-addresses the 9.4.0 issue of `NoMethodError` seen when using the `uppy-s3_multipart` gem.
Expand Down
8 changes: 7 additions & 1 deletion lib/new_relic/agent/configuration/default_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,13 @@ def self.enforce_fallback(allowed_values: nil, fallback: nil)
:public => true,
:type => Boolean,
:allowed_from_server => false,
:description => 'If `true`, the agent won\'t wrap third-party middlewares in instrumentation (regardless of whether they are installed via `Rack::Builder` or Rails).'
:description => <<~DESCRIPTION
If `true`, the agent won't wrap third-party middlewares in instrumentation (regardless of whether they are installed via `Rack::Builder` or Rails).

<Callout variant="important">
When middleware instrumentation is disabled, if an application is using middleware that could alter the response code, the HTTP status code reported on the transaction may not reflect the altered value.
</Callout>
DESCRIPTION
},
:disable_samplers => {
:default => false,
Expand Down
2 changes: 1 addition & 1 deletion lib/new_relic/rack/agent_hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module NewRelic::Rack
#
class AgentHooks < AgentMiddleware
def self.needed?
!NewRelic::Agent.config[:disable_middleware_instrumentation]
NewRelic::Agent.config[:disable_middleware_instrumentation]
end

def traced_call(env)
Expand Down
16 changes: 0 additions & 16 deletions lib/new_relic/rack/agent_middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@ def build_transaction_name
prefix = ::NewRelic::Agent::Instrumentation::ControllerInstrumentation::TransactionNamer.prefix_for_category(nil, @category)
"#{prefix}#{self.class.name}/call"
end

# If middleware tracing is disabled, we'll still inject our agent-specific
# middlewares, and still trace those, but we don't want to capture HTTP
# response codes, since middleware that's outside of ours might change the
# response code before it goes back to the client.
def capture_http_response_code(state, result)
return if NewRelic::Agent.config[:disable_middleware_instrumentation]

super
end

def capture_response_content_type(state, result)
return if NewRelic::Agent.config[:disable_middleware_instrumentation]

super
end
end
end
end
6 changes: 3 additions & 3 deletions test/multiverse/suites/rack/http_response_code_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ def test_records_http_response_code_on_analytics_events
assert_equal(302, get_last_analytics_event[2][:'http.statusCode'])
end

def test_skips_http_response_code_if_middleware_tracing_disabled
def test_records_http_response_code_if_middleware_tracing_disabled
with_config(:disable_middleware_instrumentation => true) do
rsp = get('/', {'override-response-code' => 404})

assert_equal(404, rsp.status)
refute get_last_analytics_event[2][:'http.statusCode']
assert get_last_analytics_event[2][:'http.statusCode']

rsp = get('/', {'override-response-code' => 302})

assert_equal(302, rsp.status)
refute get_last_analytics_event[2][:'http.statusCode']
assert get_last_analytics_event[2][:'http.statusCode']
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions test/multiverse/suites/rack/response_content_type_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ def test_records_response_content_type_on_analytics_events
assert_equal('application/xml', get_last_analytics_event[2][:'response.headers.contentType'])
end

def test_skips_response_content_type_if_middleware_tracing_disabled
def test_records_response_content_type_if_middleware_tracing_disabled
with_config(:disable_middleware_instrumentation => true) do
rsp = get('/', {'override-content-type' => 'application/json'})

assert_equal('application/json', rsp.headers['Content-Type'])
refute get_last_analytics_event[2][:'response.headers.contentType']
assert get_last_analytics_event[2][:'response.headers.contentType']
tannalynn marked this conversation as resolved.
Show resolved Hide resolved

rsp = get('/', {'override-content-type' => 'application/xml'})

assert_equal('application/xml', rsp.headers['Content-Type'])
refute get_last_analytics_event[2][:'response.headers.contentType']
assert get_last_analytics_event[2][:'response.headers.contentType']
end
end
end
Expand Down