- Notifications
You must be signed in to change notification settings - Fork 140
Closed
Labels
Description
Describe the bug
If a Faraday::Connection includes the RaiseError middleware, the response.status_code is not set in the span. By using this middleware, client's code is probably rescuing Faraday::Error and Faraday's run_request won't return a Faraday::Response.
Steps to reproduce
This test should fail.
# spec/elastic_apm/spies/faraday_spec.rb describe 'faraday middleware' do let(:faraday_connection) do Faraday.new do |builder| builder.use Faraday::Response::RaiseError builder.adapter :test do |stub| stub.get('/not_found') do |env| [ 404, { 'Content-Type': 'application/plain', }, 'Not Found' ] end end end end it 'should capture status_code' do with_agent do ElasticAPM.with_transaction 'Faraday test' do faraday_connection.get('/not_found') end end span, = @intercepted.spans http = span.context.http expect(http.status_code).to match('404') end endExpected behavior
response.status_code should be set.
Environment
- OS: Linux
- Ruby version: 2.6.6
- Framework and version: Rails 5.2.8.1
- APM Server version: 7.17.5
- Agent version: 3.15.1
Additional context
FaradaySpy should inject a middleware in the Faraday's Connection stack instead on relying on a Faraday::Response. It should be more reliable.
I've created one locally and it works
# elastic_apm/spies/faraday.rb ElasticAPM::Spies::FaradaySpy.without_net_http do trace_context = span&.trace_context || transaction.trace_context self.response :elastic_apm_span_middleware, span # middleware run_request_without_apm(method, url, body, headers) do |req| trace_context.apply_headers { |k, v| req[k] = v } yield req if block_given? end end ... class ApmSpanMiddleware < Faraday::Middleware attr_reader :span def initialize(app, span = nil, options = {}) super(app) @span = span end def on_complete(env) status = env[:status] http = span&.context&.http http.status_code = status.to_s if http && status span&.outcome = Span::Outcome.from_http_status(status) end end Faraday::Response.register_middleware elastic_apm_span_middleware: -> { ElasticAPM::Spies::ApmSpanMiddleware }-
Agent config options
Click to expand
replace this line with your agent config options remember to mask any sensitive fields like tokens
ebuildy, therealolivierl, g-pelletier and tdompierre