Skip to content

Instantly share code, notes, and snippets.

@bjeanes
Created July 18, 2022 07:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjeanes/520d02943be2afdc1f3230a4145921f7 to your computer and use it in GitHub Desktop.
Save bjeanes/520d02943be2afdc1f3230a4145921f7 to your computer and use it in GitHub Desktop.
Excon Sentry tracing and sentry-trace header

Not yet sure if this is working, but roughly ports built-in Net::HTTP tracing from Sentry to an Excon middleware.

# https://github.com/getsentry/sentry-ruby/blob/07084c5b959d146066af44fb1467af614b9da262/sentry-ruby/lib/sentry/net/http.rb
# https://github.com/excon/excon/blob/master/lib/excon/middlewares/base.rb
require 'excon'
class Excon::Middleware::SentryTrace < Excon::Middleware::Base
def request_call(datum)
@span = start_sentry_span
@stack.request_call(set_entry_trace_header(datum))
end
def response_call(datum)
debugger
if datum.has_key?(:response)
record_sentry_breadcrumb(datum)
record_sentry_span(datum)
end
@stack.response_call(datum)
end
private def start_sentry_span
return unless Sentry.initialized?
return unless span = Sentry.get_current_scope&.get_span
return if span.sampled == false
span.start_child(op: Sentry::Net::HTTP::OP_NAME, start_timestamp: Sentry.utc_now.to_f)
end
private def set_entry_trace_header(datum)
headers = datum[:headers] || {}
if (@span && trace = Sentry.get_current_client.generate_sentry_trace(@span))
headers[Sentry::SENTRY_TRACE_HEADER_NAME] = trace
end
datum.merge(headers: headers)
end
private def record_sentry_breadcrumb(datum)
return unless Sentry.initialized? && Sentry.configuration.breadcrumbs_logger.include?(:http_logger)
crumb = Sentry::Breadcrumb.new(
level: :info,
category: Sentry::Net::HTTP::BREADCRUMB_CATEGORY,
type: :info,
data: extract_request_info(datum)
)
Sentry.add_breadcrumb(crumb)
end
private def record_sentry_span(datum)
return unless Sentry.initialized? && @span
request_info = extract_request_info(datum)
@span.set_description("#{request_info[:method]} #{request_info[:url]}")
@span.set_data(request_info[:status])
@span.set_timestamp(Sentry.utc_now.to_f)
end
private def extract_request_info(datum)
{
url: "#{datum[:scheme]}://#{datum[:host]}:#{datum[:port]}#{datum[:path]}",
status: datum[:response][:status],
method: datum[:method].to_s.upcase,
}
end
end
Excon.defaults[:middlewares].unshift Excon::Middleware::SentryTrace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment