Skip to content

Commit

Permalink
Merge pull request #714 from DataDog/feature/datadog_global_config_se…
Browse files Browse the repository at this point in the history
…ttings

Implement global configuration using configuration API
  • Loading branch information
delner authored Mar 14, 2019
2 parents c11e390 + c28ce31 commit b70c87b
Show file tree
Hide file tree
Showing 43 changed files with 419 additions and 762 deletions.
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace :spec do

RSpec::Core::RakeTask.new(:contrib) do |t|
# rubocop:disable Metrics/LineLength
t.pattern = 'spec/**/contrib/{analytics,configurable,integration,patchable,patcher,registerable,sampling,configuration/*}_spec.rb'
t.pattern = 'spec/**/contrib/{analytics,configurable,integration,patchable,patcher,registerable,registry,configuration/*}_spec.rb'
end

[
Expand Down
35 changes: 4 additions & 31 deletions lib/ddtrace.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
require 'thread'

require 'ddtrace/registry'
require 'ddtrace/pin'
require 'ddtrace/tracer'
require 'ddtrace/error'
Expand All @@ -14,39 +13,13 @@
# \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
module Datadog
extend Augmentation
extend Configuration

@tracer = Tracer.new
@registry = Registry.new
@configuration = Configuration.new(registry: @registry)

# Default tracer that can be used as soon as +ddtrace+ is required:
#
# require 'ddtrace'
#
# span = Datadog.tracer.trace('web.request')
# span.finish()
#
# If you want to override the default tracer, the recommended way
# is to "pin" your own tracer onto your traced component:
#
# tracer = Datadog::Tracer.new
# pin = Datadog::Pin.get_from(mypatchcomponent)
# pin.tracer = tracer
class << self
attr_reader :tracer, :registry
attr_accessor :configuration

def configure(target = configuration, opts = {})
if target.is_a?(Configuration)
yield(target)
else
Configuration::PinSetup.new(target, opts).call
end
end
end
# Load and extend Contrib by default
require 'ddtrace/contrib/extensions'
extend Contrib::Extensions
end

require 'ddtrace/contrib/base'
require 'ddtrace/contrib/active_model_serializers/integration'
require 'ddtrace/contrib/active_record/integration'
require 'ddtrace/contrib/aws/integration'
Expand Down
83 changes: 0 additions & 83 deletions lib/ddtrace/configurable.rb

This file was deleted.

72 changes: 13 additions & 59 deletions lib/ddtrace/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,72 +1,26 @@
require_relative 'configuration/proxy'
require_relative 'configuration/resolver'
require_relative 'configuration/pin_setup'
require 'ddtrace/configuration/pin_setup'
require 'ddtrace/configuration/settings'

module Datadog
# Configuration provides a unique access point for configurations
class Configuration
ENV_TRACE_ANALYTICS_ENABLED = 'DD_TRACE_ANALYTICS_ENABLED'.freeze
InvalidIntegrationError = Class.new(StandardError)
module Configuration
attr_writer :configuration

attr_writer :analytics_enabled

def initialize(options = {})
@registry = options.fetch(:registry) { Datadog.registry }
@wrapped_registry = {}
@analytics_enabled = nil
end

def analytics_enabled
@analytics_enabled || begin
if ENV.key?(ENV_TRACE_ANALYTICS_ENABLED)
value = ENV[ENV_TRACE_ANALYTICS_ENABLED]
value.to_s.downcase == 'true'
end
end
def configuration
@configuration ||= Settings.new
end

def [](integration_name, configuration_name = :default)
integration = fetch_integration(integration_name)

if integration.class <= Datadog::Contrib::Integration
integration.configuration(configuration_name)
def configure(target = configuration, opts = {})
if target.is_a?(Settings)
yield(target)
else
@wrapped_registry[integration_name] ||= Proxy.new(integration)
PinSetup.new(target, opts).call
end
end

def use(integration_name, options = {}, &block)
integration = fetch_integration(integration_name)

if integration.class <= Datadog::Contrib::Integration
configuration_name = options[:describes] || :default
filtered_options = options.reject { |k, _v| k == :describes }
integration.configure(configuration_name, filtered_options, &block)
else
settings = Proxy.new(integration)
integration.sorted_options.each do |name|
settings[name] = options.fetch(name, settings[name])
end
end

integration.patch if integration.respond_to?(:patch)
end

def tracer(options = {})
instance = options.fetch(:instance, Datadog.tracer)

instance.configure(options)
instance.class.log = options[:log] if options[:log]
instance.set_tags(options[:tags]) if options[:tags]
instance.set_tags(env: options[:env]) if options[:env]
instance.class.debug_logging = options.fetch(:debug, false)
end

private

def fetch_integration(name)
@registry[name] ||
raise(InvalidIntegrationError, "'#{name}' is not a valid integration.")
# Helper methods
def tracer
configuration.tracer
end
end
end
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
require 'tsort'

module Datadog
class Configuration
module Configuration
# Resolver performs a topological sort over the dependency graph
class Resolver
class DependencyResolver
include TSort

def initialize(dependency_graph = {})
Expand Down
32 changes: 32 additions & 0 deletions lib/ddtrace/configuration/option.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Datadog
module Configuration
# Represents an instance of an integration configuration option
class Option
attr_reader \
:definition

def initialize(definition, context)
@definition = definition
@context = context
@value = nil
@is_set = false
end

def set(value)
@value = @context.instance_exec(value, &definition.setter).tap do
@is_set = true
end
end

def get
return definition.default_value unless @is_set
@value
end

def reset
@is_set = false
@value = nil
end
end
end
end
27 changes: 27 additions & 0 deletions lib/ddtrace/configuration/option_definition.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Datadog
module Configuration
# Represents a definition for an integration configuration option
class OptionDefinition
IDENTITY = ->(x) { x }

attr_reader \
:default,
:depends_on,
:lazy,
:name,
:setter

def initialize(name, meta = {}, &block)
@default = meta[:default]
@depends_on = meta[:depends_on] || []
@lazy = meta[:lazy] || false
@name = name.to_sym
@setter = meta[:setter] || block || IDENTITY
end

def default_value
lazy ? @default.call : @default
end
end
end
end
18 changes: 18 additions & 0 deletions lib/ddtrace/configuration/option_definition_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
require 'ddtrace/configuration/dependency_resolver'

module Datadog
module Configuration
# Represents a set of configuration option definitions for an integration
class OptionDefinitionSet < Hash
def dependency_order
DependencyResolver.new(dependency_graph).call
end

def dependency_graph
each_with_object({}) do |(name, option), graph|
graph[name] = option.depends_on
end
end
end
end
end
6 changes: 6 additions & 0 deletions lib/ddtrace/configuration/option_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Datadog
module Configuration
class OptionSet < Hash
end
end
end
Loading

0 comments on commit b70c87b

Please sign in to comment.