|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +module Sentry |
| 4 | + module Excon |
| 5 | + OP_NAME = "http.client" |
| 6 | + |
| 7 | + class Middleware < ::Excon::Middleware::Base |
| 8 | + def initialize(stack) |
| 9 | + super |
| 10 | + @instrumenter = Instrumenter.new |
| 11 | + end |
| 12 | + |
| 13 | + def request_call(datum) |
| 14 | + @instrumenter.start_transaction(datum) |
| 15 | + @stack.request_call(datum) |
| 16 | + end |
| 17 | + |
| 18 | + def response_call(datum) |
| 19 | + @instrumenter.finish_transaction(datum) |
| 20 | + @stack.response_call(datum) |
| 21 | + end |
| 22 | + end |
| 23 | + |
| 24 | + class Instrumenter |
| 25 | + SPAN_ORIGIN = "auto.http.excon" |
| 26 | + BREADCRUMB_CATEGORY = "http" |
| 27 | + |
| 28 | + include Utils::HttpTracing |
| 29 | + |
| 30 | + def start_transaction(env) |
| 31 | + return unless Sentry.initialized? |
| 32 | + |
| 33 | + current_span = Sentry.get_current_scope&.span |
| 34 | + @span = current_span&.start_child(op: OP_NAME, start_timestamp: Sentry.utc_now.to_f, origin: SPAN_ORIGIN) |
| 35 | + |
| 36 | + request_info = extract_request_info(env) |
| 37 | + |
| 38 | + if propagate_trace?(request_info[:url]) |
| 39 | + set_propagation_headers(env[:headers]) |
| 40 | + end |
| 41 | + end |
| 42 | + |
| 43 | + def finish_transaction(response) |
| 44 | + return unless @span |
| 45 | + |
| 46 | + response_status = response[:response][:status] |
| 47 | + request_info = extract_request_info(response) |
| 48 | + |
| 49 | + if record_sentry_breadcrumb? |
| 50 | + record_sentry_breadcrumb(request_info, response_status) |
| 51 | + end |
| 52 | + |
| 53 | + set_span_info(@span, request_info, response_status) |
| 54 | + ensure |
| 55 | + @span&.finish |
| 56 | + end |
| 57 | + |
| 58 | + private |
| 59 | + |
| 60 | + def extract_request_info(env) |
| 61 | + url = env[:scheme] + "://" + env[:hostname] + env[:path] |
| 62 | + result = { method: env[:method].to_s.upcase, url: url } |
| 63 | + |
| 64 | + if Sentry.configuration.send_default_pii |
| 65 | + result[:query] = env[:query] |
| 66 | + |
| 67 | + # Handle excon 1.0.0+ |
| 68 | + result[:query] = build_nested_query(result[:query]) unless result[:query].is_a?(String) |
| 69 | + |
| 70 | + result[:body] = env[:body] |
| 71 | + end |
| 72 | + |
| 73 | + result |
| 74 | + end |
| 75 | + end |
| 76 | + end |
| 77 | +end |
0 commit comments