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

Add http.request_id tag to Rack spans #335

Merged
merged 1 commit into from
Feb 1, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 12 additions & 0 deletions lib/ddtrace/contrib/rack/middlewares.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def set_request_tags!(request_span, env, status, headers, response)
# we prefer using the `REQUEST_URI` if this is available.
# NOTE: `REQUEST_URI` is Rails specific and may not apply for other frameworks
url = env['REQUEST_URI'] || env['PATH_INFO']
request_id = get_request_id(headers, env)

request_span.resource ||= resource_name_for(env, status)
if request_span.get_tag(Datadog::Ext::HTTP::METHOD).nil?
Expand All @@ -110,13 +111,24 @@ def set_request_tags!(request_span, env, status, headers, response)
if request_span.get_tag(Datadog::Ext::HTTP::STATUS_CODE).nil? && status
request_span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, status)
end
if request_span.get_tag(Datadog::Ext::HTTP::REQUEST_ID).nil? && request_id
request_span.set_tag(Datadog::Ext::HTTP::REQUEST_ID, request_id)
end

# detect if the status code is a 5xx and flag the request span as an error
# unless it has been already set by the underlying framework
if status.to_s.start_with?('5') && request_span.status.zero?
request_span.status = 1
end
end

# If Rails is present, it will sanitize & use the Request ID header,
# or generate a UUID if no request ID header is present, then set that as headers['X-Request-Id'].
# Othewise use whatever Rack variables are present (they should all be the same.)
def get_request_id(headers, env)
headers ||= {}
headers['X-Request-Id'] || headers['X-Request-ID'] || env['HTTP_X_REQUEST_ID']
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/ddtrace/ext/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module HTTP
URL = 'http.url'.freeze
BASE_URL = 'http.base_url'.freeze
METHOD = 'http.method'.freeze
REQUEST_ID = 'http.request_id'.freeze
STATUS_CODE = 'http.status_code'.freeze
ERROR_RANGE = 500...600
end
Expand Down
23 changes: 23 additions & 0 deletions test/contrib/rack/middleware_test.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'securerandom'
require 'contrib/rack/helpers'

# rubocop:disable Metrics/ClassLength
Expand Down Expand Up @@ -283,4 +284,26 @@ def test_request_middleware_custom_service
assert_equal(0, span.status)
assert_nil(span.parent)
end

def test_request_middleware_request_id
request_id = SecureRandom.uuid
get '/success/', {}, 'HTTP_X_REQUEST_ID' => request_id
assert last_response.ok?

spans = @tracer.writer.spans
assert_equal(1, spans.length)

span = spans.first
assert_equal('rack.request', span.name)
assert_equal('http', span.span_type)
assert_equal('rack', span.service)
assert_equal('GET 200', span.resource)
assert_equal('GET', span.get_tag('http.method'))
assert_equal('200', span.get_tag('http.status_code'))
assert_equal('/success/', span.get_tag('http.url'))
assert_equal('http://example.org', span.get_tag('http.base_url'))
assert_equal(request_id, span.get_tag('http.request_id'))
assert_equal(0, span.status)
assert_nil(span.parent)
end
end