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

Implement Rack integration configuration #541

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
2 changes: 1 addition & 1 deletion lib/ddtrace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def configure(target = configuration, opts = {})
require 'ddtrace/contrib/mongodb/patcher'
require 'ddtrace/contrib/mysql2/patcher'
require 'ddtrace/contrib/racecar/patcher'
require 'ddtrace/contrib/rack/patcher'
require 'ddtrace/contrib/rack/integration'
require 'ddtrace/contrib/rails/integration'
require 'ddtrace/contrib/rake/patcher'
require 'ddtrace/contrib/redis/patcher'
Expand Down
36 changes: 36 additions & 0 deletions lib/ddtrace/contrib/rack/configuration/settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'ddtrace/contrib/configuration/settings'

module Datadog
module Contrib
module Rack
module Configuration
# Custom settings for the Rack integration
class Settings < Contrib::Configuration::Settings
DEFAULT_HEADERS = {
response: [
'Content-Type',
'X-Request-ID'
]
}.freeze

option :distributed_tracing, default: false
option :middleware_names, default: false
option :quantize, default: {}
option :application
option :service_name, default: 'rack', depends_on: [:tracer] do |value|
get_option(:tracer).set_service_info(value, Integration::APP, Ext::AppTypes::WEB)
value
end
option :request_queuing, default: false
option :web_service_name, default: 'web-server', depends_on: [:tracer, :request_queuing] do |value|
if get_option(:request_queuing)
get_option(:tracer).set_service_info(value, 'webserver', Ext::AppTypes::WEB)
end
value
end
option :headers, default: DEFAULT_HEADERS
end
end
end
end
end
34 changes: 34 additions & 0 deletions lib/ddtrace/contrib/rack/integration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'ddtrace/contrib/integration'
require 'ddtrace/contrib/rack/configuration/settings'
require 'ddtrace/contrib/rack/patcher'

module Datadog
module Contrib
module Rack
# Description of Rack integration
class Integration
include Contrib::Integration

APP = 'rack'.freeze

register_as :rack, auto_patch: false

def self.version
Gem.loaded_specs['rack'] && Gem.loaded_specs['rack'].version
end

def self.present?
super && defined?(::Rack)
end

def default_configuration
Configuration::Settings.new
end

def patcher
Patcher
end
end
end
end
end
59 changes: 20 additions & 39 deletions lib/ddtrace/contrib/rack/patcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,36 @@ module Contrib
module Rack
# Provides instrumentation for `rack`
module Patcher
include Base
include Contrib::Patcher

DEFAULT_HEADERS = {
response: [
'Content-Type',
'X-Request-ID'
]
}.freeze
module_function

register_as :rack
option :tracer, default: Datadog.tracer
option :distributed_tracing, default: false
option :middleware_names, default: false
option :quantize, default: {}
option :application
option :service_name, default: 'rack', depends_on: [:tracer] do |value|
get_option(:tracer).set_service_info(value, 'rack', Ext::AppTypes::WEB)
value
end
option :request_queuing, default: false
option :web_service_name, default: 'web-server', depends_on: [:tracer, :request_queuing] do |value|
if get_option(:request_queuing)
get_option(:tracer).set_service_info(value, 'webserver', Ext::AppTypes::WEB)
end
value
def patched?
done?(:rack)
end
option :headers, default: DEFAULT_HEADERS

module_function

def patch
unless patched?
# Patch middleware
do_once(:rack) do
require_relative 'middlewares'
@patched = true
end

if !@middleware_patched && get_option(:middleware_names)
# Patch middleware names
if !done?(:rack_middleware_names) && get_option(:middleware_names)
if get_option(:application)
enable_middleware_names
@middleware_patched = true
do_once(:rack_middleware_names) do
patch_middleware_names
end
else
Datadog::Tracer.log.warn(%(
Rack :middleware_names requires you to also pass :application.
Middleware names have NOT been patched; please provide :application.
e.g. use: :rack, middleware_names: true, application: my_rack_app).freeze)
end
end

@patched || @middleware_patched
end

def patched?
@patched ||= false
end

def enable_middleware_names
def patch_middleware_names
retain_middleware_name(get_option(:application))
rescue => e
# We can safely ignore these exceptions since they happen only in the
Expand All @@ -80,9 +54,16 @@ def call(env)
end
end

following = middleware.instance_variable_get('@app')
following = if middleware.instance_variable_defined?('@app')
middleware.instance_variable_get('@app')
end

retain_middleware_name(following)
end

def get_option(option)
Datadog.configuration[:rack].get_option(option)
end
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions test/contrib/grape/rack_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def setup
def teardown
super
# reset the configuration
Datadog.registry[:rack].reset_options!
Datadog.registry[:grape].reset_options!
Datadog.configuration[:rack].reset_options!
Datadog.configuration[:grape].reset_options!
end
end
2 changes: 1 addition & 1 deletion test/contrib/rack/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,6 @@ def setup
def teardown
super
# reset the configuration
Datadog.registry[:rack].reset_options!
Datadog.configuration[:rack].reset_options!
end
end
9 changes: 7 additions & 2 deletions test/contrib/rack/resource_name_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ def setup
run BottomMiddleware.new
end.to_app

remove_patch!(:rack)
Datadog.registry[:rack].instance_variable_set('@middleware_patched', false)
Datadog.registry[:rack].patcher.tap do |patcher|
if patcher.instance_variable_defined?(:@done_once)
patcher.instance_variable_get(:@done_once).delete(:rack)
patcher.instance_variable_get(:@done_once).delete(:rack_middleware_names)
end
end

Datadog.configuration.use(
:rack,
middleware_names: true,
Expand Down