lib/ddtrace/contrib/sinatra/tracer.rb in ddtrace-0.39.0 vs lib/ddtrace/contrib/sinatra/tracer.rb in ddtrace-0.40.0

- old
+ new

@@ -34,63 +34,48 @@ super end def self.registered(app) - app.use TracerMiddleware + app.use TracerMiddleware, app_instance: app app.after do configuration = Datadog.configuration[:sinatra] next unless configuration[:tracer].enabled - # Ensures we only create a span for the top-most Sinatra middleware. - # - # If we traced all Sinatra middleware apps, we would have a chain - # of nested spans that were not responsible for handling this request, - # adding little value to users. - next if Sinatra::Env.middleware_traced?(env) + span = Sinatra::Env.datadog_span(env, app) - span = Sinatra::Env.datadog_span(env) || Sinatra::Tracer.create_middleware_span(env, configuration) - + # TODO: `route` should *only* be populated if @datadog_route is defined. + # TODO: If @datadog_route is not defined, then this Sinatra app is not responsible + # TODO: for handling this request. + # TODO: + # TODO: This change would be BREAKING for any Sinatra app (classic or modular), + # TODO: as it affects the `resource` value for requests not handled by the Sinatra app. + # TODO: Currently we use "#{method} #{path}" in such aces, but `path` is the raw, + # TODO: high-cardinality HTTP path, and can contain PII. + # TODO: + # TODO: The value we should use as the `resource` when the Sinatra app is not + # TODO: responsible for the request is a tricky subject. + # TODO: The best option is a value that clearly communicates that this app did not + # TODO: handle this request. It's important to keep in mind that an unhandled request + # TODO: by this Sinatra app might still be handled by another Rack middleware (which can + # TODO: be a Sinatra app itself) or it might just 404 if not handled at all. + # TODO: + # TODO: A possible value for `resource` could set a high level description, e.g. + # TODO: `request.request_method`, given we don't have the response object available yet. route = if defined?(@datadog_route) @datadog_route else # Fallback in case no routes have matched request.path end span.resource = "#{request.request_method} #{route}" - - span.set_tag(Datadog::Ext::HTTP::URL, request.path) - span.set_tag(Datadog::Ext::HTTP::METHOD, request.request_method) - span.set_tag(Ext::TAG_APP_NAME, app.settings.name) span.set_tag(Ext::TAG_ROUTE_PATH, route) - if request.script_name && !request.script_name.empty? - span.set_tag(Ext::TAG_SCRIPT_NAME, request.script_name) - end - - span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, response.status) - span.set_error(env['sinatra.error']) if response.server_error? - - Sinatra::Env.set_middleware_traced(env, true) end end - # Initializes a span for the top-most Sinatra middleware. - def self.create_middleware_span(env, configuration) - tracer = configuration[:tracer] - span = tracer.trace( - Ext::SPAN_REQUEST, - service: configuration[:service_name], - span_type: Datadog::Ext::HTTP::TYPE_INBOUND, - start_time: Sinatra::Env.middleware_start_time(env) - ) - - Sinatra::Env.set_datadog_span(env, span) - span - end - # Method overrides for Sinatra::Base module Base def render(engine, data, *) tracer = Datadog.configuration[:sinatra][:tracer] return super unless tracer.enabled @@ -112,16 +97,10 @@ # Invoked when a matching route is found. # This method yields directly to user code. def route_eval configuration = Datadog.configuration[:sinatra] tracer = configuration[:tracer] - return super unless tracer.enabled - - # For initialization of Sinatra middleware span in order - # guarantee that the Ext::SPAN_ROUTE span being created below - # has the middleware span as its parent. - Sinatra::Tracer.create_middleware_span(env, configuration) unless Sinatra::Env.datadog_span(env) tracer.trace( Ext::SPAN_ROUTE, service: configuration[:service_name], span_type: Datadog::Ext::HTTP::TYPE_INBOUND