Skip to content

Commit

Permalink
Add http.useragent tag
Browse files Browse the repository at this point in the history
While User-Agent is a header and can be included in the
http.request_headers tag, it is not by default, and even if it were it
oculd be removed from the list by the user.

This unconditionally obtains the request header value and stores it in a
dedicated tag.
  • Loading branch information
lloeki committed Sep 9, 2022
1 parent d2ba9c9 commit 1875ffd
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/datadog/tracing/contrib/rack/middlewares.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ def set_request_tags!(trace, request_span, env, status, headers, response, origi
request_headers_tags = parse_request_headers(request_header_collection)
response_headers_tags = parse_response_headers(headers || {})

# request_headers is subject to filtering and configuration so we
# get the user agent separately
user_agent = parse_user_agent_header(request_header_collection)

# The priority
# 1. User overrides span.resource
# 2. Configuration
Expand Down Expand Up @@ -205,6 +209,10 @@ def set_request_tags!(trace, request_span, env, status, headers, response, origi
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, status)
end

if request_span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT).nil? && user_agent
request_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_USER_AGENT, user_agent)
end

# Request headers
request_headers_tags.each do |name, value|
request_span.set_tag(name, value) if request_span.get_tag(name).nil?
Expand All @@ -230,6 +238,10 @@ def configuration
Datadog.configuration.tracing[:rack]
end

def parse_user_agent_header(headers)
headers.get(Tracing::Metadata::Ext::HTTP::HEADER_USER_AGENT)
end

def parse_request_headers(headers)
whitelist = configuration[:headers][:request] || []
whitelist.each_with_object({}) do |header, result|
Expand Down
2 changes: 2 additions & 0 deletions lib/datadog/tracing/metadata/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ module HTTP
TAG_BASE_URL = 'http.base_url'
TAG_METHOD = 'http.method'
TAG_STATUS_CODE = 'http.status_code'
TAG_USER_AGENT = 'http.useragent'
TAG_URL = 'http.url'
TYPE_INBOUND = AppTypes::TYPE_WEB.freeze
TYPE_OUTBOUND = 'http'
TYPE_PROXY = 'proxy'
TYPE_TEMPLATE = 'template'
TAG_CLIENT_IP = 'http.client_ip'
HEADER_USER_AGENT = 'User-Agent'

# General header functionality
module Headers
Expand Down
42 changes: 42 additions & 0 deletions spec/datadog/tracing/contrib/rack/integration_test_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,48 @@
end

describe 'GET request' do
context 'that does not sent user agent' do
subject(:response) { get '/headers/', {}, headers }

let(:headers) do
{}
end

before do
is_expected.to be_ok
expect(spans).to have(1).items
end

it_behaves_like 'a rack GET 200 span'

it do
expect(span.get_tag('http.useragent')).to be nil
expect(span.get_tag('http.request.headers.user-agent')).to be nil
end
end

context 'that sends user agent' do
subject(:response) { get '/headers/', {}, headers }

let(:headers) do
{
'HTTP_USER_AGENT' => 'SuperUserAgent',
}
end

before do
is_expected.to be_ok
expect(spans).to have(1).items
end

it_behaves_like 'a rack GET 200 span'

it do
expect(span.get_tag('http.useragent')).to eq('SuperUserAgent')
expect(span.get_tag('http.request.headers.user-agent')).to be nil
end
end

context 'that sends headers' do
subject(:response) { get '/headers/', {}, headers }

Expand Down

0 comments on commit 1875ffd

Please sign in to comment.