Skip to content

Commit 1d5f17c

Browse files
committed
Added: URL quantization to Rack.
1 parent 3204d8a commit 1d5f17c

File tree

4 files changed

+67
-1
lines changed

4 files changed

+67
-1
lines changed

docs/GettingStarted.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,44 @@ Where `options` is an optional `Hash` that accepts the following parameters:
142142
| ``service_name`` | Service name used when tracing application requests | rack |
143143
| ``distributed_tracing`` | Enables [distributed tracing](#Distributed_Tracing) so that this service trace is connected with a trace of another service if tracing headers are received | `false` |
144144
| ``middleware_names`` | Enable this if you want to use the middleware classes as the resource names for `rack` spans. Must provide the ``application`` option with it. | ``false`` |
145+
| ``quantize`` | Hash containing options for quantization. May include `:query` or `:fragment`. | {} |
146+
| ``quantize.query`` | Hash containing options for query portion of URL quantization. May include `:show` or `:exclude`. See options below. Option must be nested inside the `quantize` option. | {} |
147+
| ``quantize.query.show`` | Defines which values should always be shown. Shows no values by default. May be an Array of strings, or `:all` to show all values. Option must be nested inside the `query` option. | ``nil`` |
148+
| ``quantize.query.exclude`` | Defines which values should be removed entirely. Excludes nothing by default. May be an Array of strings, or `:all` to remove the query string entirely. Option must be nested inside the `query` option. | ``nil`` |
149+
| ``quantize.fragment`` | Defines behavior for URL fragments. Removes fragments by default. May be `:show` to show URL fragments. Option must be nested inside the `quantize` option. | ``nil`` |
145150
| ``application`` | Your Rack application. Necessary for enabling middleware resource names. | ``nil`` |
146151
| ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
147152

153+
Configuring URL quantization behavior:
154+
155+
```
156+
Datadog.configure do |c|
157+
# Default behavior: all values are quantized, fragment is removed.
158+
# http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id&sort_by
159+
# http://example.com/path?categories[]=1&categories[]=2 --> http://example.com/path?categories[]
160+
161+
# Show values for any query string parameter matching 'category_id' exactly
162+
# http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id=1&sort_by
163+
c.use :rack, quantize: { query: { show: ['category_id'] } }
164+
165+
# Show all values for all query string parameters
166+
# http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id=1&sort_by=asc
167+
c.use :rack, quantize: { query: { show: :all } }
168+
169+
# Totally exclude any query string parameter matching 'sort_by' exactly
170+
# http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id
171+
c.use :rack, quantize: { query: { exclude: ['sort_by'] } }
172+
173+
# Remove the query string entirely
174+
# http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path
175+
c.use :rack, quantize: { query: { exclude: :all } }
176+
177+
# Show URL fragments
178+
# http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id&sort_by#featured
179+
c.use :rack, quantize: { fragment: :show }
180+
end
181+
```
182+
148183
## Other libraries
149184

150185
### GraphQL

lib/ddtrace/contrib/rack/middlewares.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ def set_request_tags!(request_span, env, status, headers, response, original_env
104104
request_span.set_tag(Datadog::Ext::HTTP::METHOD, env['REQUEST_METHOD'])
105105
end
106106
if request_span.get_tag(Datadog::Ext::HTTP::URL).nil?
107-
request_span.set_tag(Datadog::Ext::HTTP::URL, url)
107+
options = Datadog.configuration[:rack][:quantize]
108+
request_span.set_tag(Datadog::Ext::HTTP::URL, Datadog::Quantization::HTTP.url(url, options))
108109
end
109110
if request_span.get_tag(Datadog::Ext::HTTP::BASE_URL).nil?
110111
request_obj = ::Rack::Request.new(env)

lib/ddtrace/contrib/rack/patcher.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Patcher
88
option :tracer, default: Datadog.tracer
99
option :distributed_tracing, default: false
1010
option :middleware_names, default: false
11+
option :quantize, default: {}
1112
option :application
1213
option :service_name, default: 'rack', depends_on: [:tracer] do |value|
1314
get_option(:tracer).set_service_info(value, 'rack', Ext::AppTypes::WEB)

test/contrib/rack/middleware_test.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,35 @@ def test_request_middleware_get_with_request_uri
6464
assert_equal('200', span.get_tag('http.status_code'))
6565
# Since REQUEST_URI is set (usually provided by WEBrick/Puma)
6666
# it uses REQUEST_URI, which has query string parameters.
67+
# However, that query string will be quantized.
68+
assert_equal('/success?foo', span.get_tag('http.url'))
69+
assert_equal('http://example.org', span.get_tag('http.base_url'))
70+
assert_equal(0, span.status)
71+
assert_nil(span.parent)
72+
end
73+
74+
def test_request_middleware_get_with_request_uri_and_quantize_option
75+
Datadog.configure do |c|
76+
c.use :rack, quantize: { query: { show: ['foo'] } }
77+
end
78+
79+
# ensure the Rack request is properly traced
80+
get '/success?foo=bar', {}, 'REQUEST_URI' => '/success?foo=bar'
81+
assert last_response.ok?
82+
83+
spans = @tracer.writer.spans
84+
assert_equal(1, spans.length)
85+
86+
span = spans[0]
87+
assert_equal('rack.request', span.name)
88+
assert_equal('http', span.span_type)
89+
assert_equal('rack', span.service)
90+
assert_equal('GET 200', span.resource)
91+
assert_equal('GET', span.get_tag('http.method'))
92+
assert_equal('200', span.get_tag('http.status_code'))
93+
# Since REQUEST_URI is set (usually provided by WEBrick/Puma)
94+
# it uses REQUEST_URI, which has query string parameters.
95+
# However, that query string will be quantized.
6796
assert_equal('/success?foo=bar', span.get_tag('http.url'))
6897
assert_equal('http://example.org', span.get_tag('http.base_url'))
6998
assert_equal(0, span.status)

0 commit comments

Comments
 (0)