Skip to content

Commit

Permalink
Merge pull request #3657 from DataDog/munir/remap-otel-configs
Browse files Browse the repository at this point in the history
  • Loading branch information
marcotc authored Jun 7, 2024
2 parents c88f117 + a05f047 commit eab4b6e
Show file tree
Hide file tree
Showing 8 changed files with 307 additions and 18 deletions.
1 change: 1 addition & 0 deletions lib/datadog/core/configuration/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Ext
# @public_api
module Diagnostics
ENV_DEBUG_ENABLED = 'DD_TRACE_DEBUG'
ENV_OTEL_LOG_LEVEL = 'OTEL_LOG_LEVEL'
ENV_HEALTH_METRICS_ENABLED = 'DD_HEALTH_METRICS_ENABLED'
ENV_STARTUP_LOGS_ENABLED = 'DD_TRACE_STARTUP_LOGS'
end
Expand Down
34 changes: 29 additions & 5 deletions lib/datadog/core/configuration/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,18 @@ def initialize(*_)
# @default `DD_TRACE_DEBUG` environment variable, otherwise `false`
# @return [Boolean]
option :debug do |o|
o.env Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED
o.env [Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED,
Datadog::Core::Configuration::Ext::Diagnostics::ENV_OTEL_LOG_LEVEL]
o.default false
o.type :bool
o.env_parser do |value|
if value
value = value.strip.downcase
# Debug is enabled when DD_TRACE_DEBUG is true or 1 OR
# when OTEL_LOG_LEVEL is set to debug
['true', '1', 'debug'].include?(value)
end
end
o.after_set do |enabled|
# Enable rich debug print statements.
# We do not need to unnecessarily load 'pp' unless in debugging mode.
Expand Down Expand Up @@ -465,7 +474,7 @@ def initialize(*_)
o.type :string, nilable: true

# NOTE: service also gets set as a side effect of tags. See the WORKAROUND note in #initialize for details.
o.env Core::Environment::Ext::ENV_SERVICE
o.env [Core::Environment::Ext::ENV_SERVICE, Core::Environment::Ext::ENV_OTEL_SERVICE]
o.default Core::Environment::Ext::FALLBACK_SERVICE_NAME

# There's a few cases where we don't want to use the fallback service name, so this helper allows us to get a
Expand Down Expand Up @@ -500,14 +509,13 @@ def initialize(*_)
# @return [Hash<String,String>]
option :tags do |o|
o.type :hash, nilable: true
o.env Core::Environment::Ext::ENV_TAGS
o.env [Core::Environment::Ext::ENV_TAGS, Core::Environment::Ext::ENV_OTEL_RESOURCE_ATTRIBUTES]
o.env_parser do |env_value|
values = if env_value.include?(',')
env_value.split(',')
else
env_value.split(' ') # rubocop:disable Style/RedundantArgument
end

values.map! do |v|
v.gsub!(/\A[\s,]*|[\s,]*\Z/, '')

Expand All @@ -517,7 +525,23 @@ def initialize(*_)
values.compact!
values.each_with_object({}) do |tag, tags|
key, value = tag.split(':', 2)
tags[key] = value if value && !value.empty?
if value.nil?
# support tags/attributes delimited by the OpenTelemetry separator (`=`)
key, value = tag.split('=', 2)
end
next if value.nil? || value.empty?

# maps OpenTelemetry semantic attributes to Datadog tags
case key.downcase
when 'deployment.environment'
tags['env'] = value
when 'service.version'
tags['version'] = value
when 'service.name'
tags['service'] = value
else
tags[key] = value
end
end
end
o.setter do |new_value, old_value|
Expand Down
2 changes: 2 additions & 0 deletions lib/datadog/core/environment/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ module Ext
ENV_API_KEY = 'DD_API_KEY'
ENV_ENVIRONMENT = 'DD_ENV'
ENV_SERVICE = 'DD_SERVICE'
ENV_OTEL_SERVICE = 'OTEL_SERVICE_NAME'
ENV_SITE = 'DD_SITE'
ENV_TAGS = 'DD_TAGS'
ENV_OTEL_RESOURCE_ATTRIBUTES = 'OTEL_RESOURCE_ATTRIBUTES'
ENV_VERSION = 'DD_VERSION'
FALLBACK_SERVICE_NAME =
begin
Expand Down
1 change: 1 addition & 0 deletions lib/datadog/core/runtime/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Ext
# @public_api
module Metrics
ENV_ENABLED = 'DD_RUNTIME_METRICS_ENABLED'
ENV_OTEL_METRICS_EXPORTER = 'OTEL_METRICS_EXPORTER'

METRIC_CLASS_COUNT = 'runtime.ruby.class_count'
METRIC_GC_PREFIX = 'runtime.ruby.gc'
Expand Down
7 changes: 7 additions & 0 deletions lib/datadog/tracing/configuration/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Configuration
# e.g. Env vars, default values, enums, etc...
module Ext
ENV_ENABLED = 'DD_TRACE_ENABLED'
ENV_OTEL_TRACES_EXPORTER = 'OTEL_TRACES_EXPORTER'
ENV_HEADER_TAGS = 'DD_TRACE_HEADER_TAGS'
ENV_TRACE_ID_128_BIT_GENERATION_ENABLED = 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED'

Expand Down Expand Up @@ -39,10 +40,14 @@ module Distributed
# W3C Trace Context
PROPAGATION_STYLE_TRACE_CONTEXT = 'tracecontext'

PROPAGATION_STYLE_SUPPORTED = [PROPAGATION_STYLE_DATADOG, PROPAGATION_STYLE_B3_MULTI_HEADER,
PROPAGATION_STYLE_B3_SINGLE_HEADER, PROPAGATION_STYLE_TRACE_CONTEXT].freeze

# Sets both extract and inject propagation style tho the provided value.
# Has lower precedence than `DD_TRACE_PROPAGATION_STYLE_INJECT` or
# `DD_TRACE_PROPAGATION_STYLE_EXTRACT`.
ENV_PROPAGATION_STYLE = 'DD_TRACE_PROPAGATION_STYLE'
ENV_OTEL_PROPAGATION_STYLE = 'OTEL_PROPAGATORS'

ENV_PROPAGATION_STYLE_INJECT = 'DD_TRACE_PROPAGATION_STYLE_INJECT'

Expand All @@ -68,6 +73,8 @@ module Sampling
ENV_SAMPLE_RATE = 'DD_TRACE_SAMPLE_RATE'
ENV_RATE_LIMIT = 'DD_TRACE_RATE_LIMIT'
ENV_RULES = 'DD_TRACE_SAMPLING_RULES'
ENV_OTEL_TRACES_SAMPLER = 'OTEL_TRACES_SAMPLER'
OTEL_TRACES_SAMPLER_ARG = 'OTEL_TRACES_SAMPLER_ARG'

# @public_api
module Span
Expand Down
55 changes: 52 additions & 3 deletions lib/datadog/tracing/configuration/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ module Configuration
# rubocop:disable Metrics/BlockLength
# rubocop:disable Metrics/MethodLength
# rubocop:disable Layout/LineLength
# rubocop:disable Metrics/CyclomaticComplexity
# rubocop:disable Metrics/PerceivedComplexity
module Settings
def self.extended(base)
base.class_eval do
Expand Down Expand Up @@ -89,14 +91,22 @@ def self.extended(base)
# @return [Array<String>]
option :propagation_style do |o|
o.type :array
o.env Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE
o.env [Configuration::Ext::Distributed::ENV_PROPAGATION_STYLE, Configuration::Ext::Distributed::ENV_OTEL_PROPAGATION_STYLE]
o.default []
o.after_set do |styles|
next if styles.empty?

# Make values case-insensitive
styles.map!(&:downcase)

styles.select! do |s|
if Configuration::Ext::Distributed::PROPAGATION_STYLE_SUPPORTED.include?(s)
true
else
Datadog.logger.warn("Unsupported propagation style: #{s}")
false
end
end
set_option(:propagation_style_extract, styles)
set_option(:propagation_style_inject, styles)
end
Expand All @@ -121,9 +131,23 @@ def self.extended(base)
# @default `DD_TRACE_ENABLED` environment variable, otherwise `true`
# @return [Boolean]
option :enabled do |o|
o.env Tracing::Configuration::Ext::ENV_ENABLED
o.env [Tracing::Configuration::Ext::ENV_ENABLED, Tracing::Configuration::Ext::ENV_OTEL_TRACES_EXPORTER]
o.default true
o.type :bool
o.env_parser do |value|
value = value&.downcase
# Tracing is disabled when OTEL_TRACES_EXPORTER is none or
# DD_TRACE_ENABLED is 0 or false.
if ['none', 'false', '0'].include?(value)
false
# Tracing is enabled when DD_TRACE_ENABLED is true or 1
elsif ['true', '1'].include?(value)
true
else
Datadog.logger.warn("Unsupported value for exporting datadog traces: #{value}. Traces will be sent to Datadog.")
nil
end
end
end

# Comma-separated, case-insensitive list of header names that are reported in incoming and outgoing HTTP requests.
Expand Down Expand Up @@ -245,7 +269,30 @@ def self.extended(base)
# @return [Float, nil]
option :default_rate do |o|
o.type :float, nilable: true
o.env Tracing::Configuration::Ext::Sampling::ENV_SAMPLE_RATE
o.env [Tracing::Configuration::Ext::Sampling::ENV_SAMPLE_RATE, Tracing::Configuration::Ext::Sampling::ENV_OTEL_TRACES_SAMPLER]
o.env_parser do |value|
# Parse the value as a float
next if value.nil?

value = value&.downcase
if ['always_on', 'always_off', 'traceidratio'].include?(value)
Datadog.logger.warn("The value '#{value}' is not yet supported. 'parentbased_#{value}' will be used instead.")
value = "parentbased_#{value}"
end
# OTEL_TRACES_SAMPLER can be set to always_on, always_off, traceidratio, and/or parentbased value.
# These values are mapped to a sample rate.
# DD_TRACE_SAMPLE_RATE sets the sample rate to float.
case value
when 'parentbased_always_on'
1.0
when 'parentbased_always_off'
0.0
when 'parentbased_traceidratio'
ENV.fetch(Tracing::Configuration::Ext::Sampling::OTEL_TRACES_SAMPLER_ARG, 1.0).to_f
else
value.to_f
end
end
end

# Rate limit for number of spans per second.
Expand Down Expand Up @@ -417,6 +464,8 @@ def self.extended(base)
# rubocop:enable Metrics/BlockLength
# rubocop:enable Metrics/MethodLength
# rubocop:enable Layout/LineLength
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/PerceivedComplexity
end
end
end
82 changes: 80 additions & 2 deletions spec/datadog/core/configuration/settings_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,40 @@
it { is_expected.to be false }
end
end

context "when #{Datadog::Core::Configuration::Ext::Diagnostics::ENV_OTEL_LOG_LEVEL}" do
around do |example|
ClimateControl.modify(
{
Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED => dd_debug_env,
Datadog::Core::Configuration::Ext::Diagnostics::ENV_OTEL_LOG_LEVEL => otel_level_env
}
) do
example.run
end
end

context 'is set to debug' do
let(:dd_debug_env) { nil }
let(:otel_level_env) { 'DEBUG' }

it { is_expected.to be true }
end

context 'is not set to debug' do
let(:dd_debug_env) { nil }
let(:otel_level_env) { 'INFO' }

it { is_expected.to be false }
end

context 'and DD_TRACE_DEBUG is defined' do
let(:dd_debug_env) { 'true' }
let(:otel_level_env) { 'info' }

it { is_expected.to be true }
end
end
end

describe '#debug=' do
Expand Down Expand Up @@ -943,9 +977,12 @@
is_expected.to eq('service-name-from-tag')
end

context 'and defined via DD_SERVICE' do
context 'and defined via DD_SERVICE and OTEL_SERVICE_NAME' do
around do |example|
ClimateControl.modify(Datadog::Core::Environment::Ext::ENV_SERVICE => 'service-name-from-dd-service') do
ClimateControl.modify(
Datadog::Core::Environment::Ext::ENV_SERVICE => 'service-name-from-dd-service',
Datadog::Core::Environment::Ext::ENV_OTEL_SERVICE => 'otel-service-name'
) do
example.run
end
end
Expand All @@ -954,6 +991,18 @@
is_expected.to eq('service-name-from-dd-service')
end
end

context 'and defined via OTEL_SERVICE_NAME' do
around do |example|
ClimateControl.modify(Datadog::Core::Environment::Ext::ENV_OTEL_SERVICE => 'otel-service-name') do
example.run
end
end

it 'uses the service name from OTEL_SERVICE_NAME' do
is_expected.to eq('otel-service-name')
end
end
end
end

Expand Down Expand Up @@ -1131,6 +1180,35 @@
it { is_expected.to include('version' => version_value) }
end
end

context "when #{Datadog::Core::Environment::Ext::ENV_OTEL_RESOURCE_ATTRIBUTES}" do
around do |example|
ClimateControl.modify(
Datadog::Core::Environment::Ext::ENV_OTEL_RESOURCE_ATTRIBUTES => otel_tags,
Datadog::Core::Environment::Ext::ENV_TAGS => dd_tags
) do
example.run
end
end

context 'is defined and DD_TAGS is set' do
let(:otel_tags) { 'deployment.environment=prod,service.name=bleh,service.version=1.0,mkey=val1' }
let(:dd_tags) { 'service:moon-test,version:v42069,env:prod,token:gg' }
it { is_expected.to include('service' => 'moon-test', 'version' => 'v42069', 'env' => 'prod', 'token' => 'gg') }
end

context 'is defined and DD_TAGS is not set' do
let(:otel_tags) { 'deployment.environment=prod,service.name=bleh,service.version=1.0,mkey=val1' }
let(:dd_tags) { nil }
it { is_expected.to include('env' => 'prod', 'service' => 'bleh', 'version' => '1.0', 'mkey' => 'val1') }
end

context 'is not defined and DD_TAGS is not set' do
let(:otel_tags) { nil }
let(:dd_tags) { nil }
it { is_expected.to eq({}) }
end
end
end

describe '#tags=' do
Expand Down
Loading

0 comments on commit eab4b6e

Please sign in to comment.