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 global configuration using configuration API #714

Merged
merged 4 commits into from
Mar 14, 2019
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 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