Skip to content

Commit

Permalink
Merge pull request #1008 from DataDog/fix/env_vars_from_tags
Browse files Browse the repository at this point in the history
Populate env, service, and version from tags
  • Loading branch information
delner authored Apr 15, 2020
2 parents d7aba16 + 70863c4 commit f9db8f2
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 80 deletions.
38 changes: 23 additions & 15 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -1603,9 +1603,11 @@ By default, the trace agent (not this library, but the program running in the ba
You can configure the application to automatically tag your traces and metrics, using the following environment variables:

- `DD_ENV`: Your application environment (e.g. `production`, `staging`, etc.)
- `DD_SERVICE`: Your application's default service name (e.g. `billing-api`)
- `DD_VERSION`: Your application version (e.g. `2.5`, `202003181415`, `1.3-alpha`, etc.)
- `DD_TAGS`: Custom tags in value pairs separated by `,` (e.g. `layer:api,team:intake`)
- If `DD_ENV` or `DD_VERSION`, it will override any `env` or `version` tag defined in `DD_TAGS`.
- If `DD_ENV`, `DD_SERVICE` or `DD_VERSION` are set, it will override any respective `env`/`service`/`version` tag defined in `DD_TAGS`.
- If `DD_ENV`, `DD_SERVICE` or `DD_VERSION` are NOT set, tags defined in `DD_TAGS` will be used to populate `env`/`service`/`version` respectively.

These values can also be overridden at the tracer level:

Expand All @@ -1618,9 +1620,9 @@ Datadog.configure do |c|
end
```

This enables you to set this value on a per tracer basis, so you can have for example several applications reporting for different environments on the same host.
This enables you to set this value on a per application basis, so you can have for example several applications reporting for different environments on the same host.

Ultimately, tags can be set per span, but `env` should typically be the same for all spans belonging to a given trace.
Tags can also be set directly on individual spans, which will supersede any conflicting tags defined at the application level.

### Sampling

Expand Down Expand Up @@ -1910,6 +1912,7 @@ Datadog.tracer.trace('correlation.example') do
correlation.trace_id # => 5963550561812073440
correlation.span_id # => 2232727802607726424
correlation.env # => 'production' (derived from DD_ENV)
correlation.service # => 'billing-api' (derived from DD_SERVICE)
correlation.version # => '2.5.17' (derived from DD_VERSION)
end

Expand All @@ -1919,8 +1922,9 @@ correlation = Datadog.tracer.active_correlation
correlation = Datadog.tracer.active_correlation
correlation.trace_id # => 0
correlation.span_id # => 0
correlation.trace_id # => nil
correlation.span_id # => nil
correlation.env # => 'production' (derived from DD_ENV)
correlation.service # => 'billing-api' (derived from DD_SERVICE)
correlation.version # => '2.5.17' (derived from DD_VERSION)
```

#### For logging in Rails applications using Lograge (recommended)
Expand All @@ -1939,6 +1943,7 @@ config.lograge.custom_options = lambda do |event|
:trace_id => correlation.trace_id.to_s,
:span_id => correlation.span_id.to_s,
:env => correlation.env.to_s,
:service => correlation.service.to_s,
:version => correlation.version.to_s
},
:ddsource => ["ruby"],
Expand All @@ -1960,27 +1965,29 @@ end

# Given:
# DD_ENV = 'production' (The name of the environment your application is running in.)
# DD_SERVICE = 'billing-api' (Default service name of your application.)
# DD_VERSION = '2.5.17' (The version of your application.)

# Web requests will produce:
# [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206 dd.env=production dd.version=2.5.17] Started GET "/articles" for 172.22.0.1 at 2019-01-16 18:50:57 +0000
# [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206 dd.env=production dd.version=2.5.17] Processing by ArticlesController#index as */*
# [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206 dd.env=production dd.version=2.5.17] Article Load (0.5ms) SELECT "articles".* FROM "articles"
# [dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206 dd.env=production dd.version=2.5.17] Completed 200 OK in 7ms (Views: 5.5ms | ActiveRecord: 0.5ms)
# [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Started GET "/articles" for 172.22.0.1 at 2019-01-16 18:50:57 +0000
# [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Processing by ArticlesController#index as */*
# [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Article Load (0.5ms) SELECT "articles".* FROM "articles"
# [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Completed 200 OK in 7ms (Views: 5.5ms | ActiveRecord: 0.5ms)
```

#### For logging in Ruby applications

To add correlation IDs to your logger, add a log formatter which retrieves the correlation IDs with `Datadog.tracer.active_correlation`, then add them to the message.

To properly correlate with Datadog logging, be sure the following is present in the log message:
To properly correlate with Datadog logging, be sure the following is present in the log message, in order as they appear:

- `dd.env=<ENV>`: Where `<ENV>` is equal to `Datadog.tracer.active_correlation.env`. Omit if no environment is configured.
- `dd.service=<SERVICE>`: Where `<SERVICE>` is equal to `Datadog.tracer.active_correlation.service`. Omit if no default service name is configured.
- `dd.version=<VERSION>`: Where `<VERSION>` is equal to `Datadog.tracer.active_correlation.version`. Omit if no application version is configured.
- `dd.trace_id=<TRACE_ID>`: Where `<TRACE_ID>` is equal to `Datadog.tracer.active_correlation.trace_id` or `0` if no trace is active during logging.
- `dd.span_id=<SPAN_ID>`: Where `<SPAN_ID>` is equal to `Datadog.tracer.active_correlation.span_id` or `0` if no trace is active during logging.
- `dd.env=<ENV>`: Where `<ENV>` is equal to `Datadog.tracer.active_correlation.env` or empty string (no quotes) if no environment name is configured.
- `dd.version=<SPAN_ID>`: Where `<SPAN_ID>` is equal to `Datadog.tracer.active_correlation.version` or empty string (no quotes) if no application version is configured.

By default, `Datadog::Correlation::Identifier#to_s` will return `dd.trace_id=<TRACE_ID> dd.span_id=<SPAN_ID> dd.env=<ENV> dd.version=<VERSION>`.
By default, `Datadog::Correlation::Identifier#to_s` will return `dd.env=<ENV> dd.service=<SERVICE> dd.version=<VERSION> dd.trace_id=<TRACE_ID> dd.span_id=<SPAN_ID>`.

If a trace is not active and the application environment & version is not configured, it will return `dd.trace_id=0 dd.span_id=0 dd.env= dd.version=`.

Expand All @@ -1991,6 +1998,7 @@ require 'ddtrace'
require 'logger'

ENV['DD_ENV'] = 'production'
ENV['DD_SERVICE'] = 'billing-api'
ENV['DD_VERSION'] = '2.5.17'

logger = Logger.new(STDOUT)
Expand All @@ -2001,11 +2009,11 @@ end

# When no trace is active
logger.warn('This is an untraced operation.')
# [2019-01-16 18:38:41 +0000][my_app][WARN][dd.trace_id=0 dd.span_id=0 dd.env=production dd.version=2.5.17] This is an untraced operation.
# [2019-01-16 18:38:41 +0000][my_app][WARN][dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=0 dd.span_id=0] This is an untraced operation.

# When a trace is active
Datadog.tracer.trace('my.operation') { logger.warn('This is a traced operation.') }
# [2019-01-16 18:38:41 +0000][my_app][WARN][dd.trace_id=8545847825299552251 dd.span_id=3711755234730770098 dd.env=production dd.version=2.5.17] This is a traced operation.
# [2019-01-16 18:38:41 +0000][my_app][WARN][dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=8545847825299552251 dd.span_id=3711755234730770098] This is a traced operation.
```

### Configuring the transport layer
Expand Down
13 changes: 13 additions & 0 deletions lib/ddtrace/configuration/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,19 @@ def runtime_metrics(options = nil)
# Coerce keys to strings
string_tags = Hash[new_value.collect { |k, v| [k.to_s, v] }]

# Cross-populate tag values with other settings
if env.nil? && string_tags.key?(Ext::Environment::TAG_ENV)
self.env = string_tags[Ext::Environment::TAG_ENV]
end

if version.nil? && string_tags.key?(Ext::Environment::TAG_VERSION)
self.version = string_tags[Ext::Environment::TAG_VERSION]
end

if service.nil? && string_tags.key?(Ext::Environment::TAG_SERVICE)
self.service = string_tags[Ext::Environment::TAG_SERVICE]
end

# Merge with previous tags
(old_value || {}).merge(string_tags)
end
Expand Down
15 changes: 9 additions & 6 deletions lib/ddtrace/correlation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,24 @@ module Datadog
# e.g. Retrieve a correlation to the current trace for logging, etc.
module Correlation
# Struct representing correlation
Identifier = Struct.new(:trace_id, :span_id, :env, :version) do
Identifier = Struct.new(:trace_id, :span_id, :env, :service, :version) do
def initialize(*args)
super
self.trace_id = trace_id || 0
self.span_id = span_id || 0
self.env = env || Datadog.configuration.env
self.service = service || Datadog.configuration.service
self.version = version || Datadog.configuration.version
end

def to_s
str = "#{Ext::Correlation::ATTR_TRACE_ID}=#{trace_id}"
str += " #{Ext::Correlation::ATTR_SPAN_ID}=#{span_id}"
str += " #{Ext::Correlation::ATTR_ENV}=#{env}"
str += " #{Ext::Correlation::ATTR_VERSION}=#{version}"
str
attributes = []
attributes << "#{Ext::Correlation::ATTR_ENV}=#{env}" unless env.nil?
attributes << "#{Ext::Correlation::ATTR_SERVICE}=#{service}" unless service.nil?
attributes << "#{Ext::Correlation::ATTR_VERSION}=#{version}" unless version.nil?
attributes << "#{Ext::Correlation::ATTR_TRACE_ID}=#{trace_id}"
attributes << "#{Ext::Correlation::ATTR_SPAN_ID}=#{span_id}"
attributes.join(' ')
end
end.freeze

Expand Down
1 change: 1 addition & 0 deletions lib/ddtrace/ext/correlation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Datadog
module Ext
module Correlation
ATTR_ENV = 'dd.env'.freeze
ATTR_SERVICE = 'dd.service'.freeze
ATTR_SPAN_ID = 'dd.span_id'.freeze
ATTR_TRACE_ID = 'dd.trace_id'.freeze
ATTR_VERSION = 'dd.version'.freeze
Expand Down
1 change: 1 addition & 0 deletions lib/ddtrace/ext/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module Environment
ENV_VERSION = 'DD_VERSION'.freeze

TAG_ENV = 'env'.freeze
TAG_SERVICE = 'service'.freeze
TAG_VERSION = 'version'.freeze
end
end
Expand Down
36 changes: 36 additions & 0 deletions spec/ddtrace/configuration/settings_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,18 @@
end
end

context 'defines :env with missing #env' do
let(:env_tags) { "env:#{tag_env_value}" }
let(:tag_env_value) { 'tag-env-value' }

it 'populates #env from the tag' do
expect { tags }
.to change { settings.env }
.from(nil)
.to(tag_env_value)
end
end

context 'conflicts with #env' do
let(:env_tags) { "env:#{tag_env_value}" }
let(:tag_env_value) { 'tag-env-value' }
Expand All @@ -554,6 +566,18 @@
it { is_expected.to include('env' => env_value) }
end

context 'defines :service with missing #service' do
let(:env_tags) { "service:#{tag_service_value}" }
let(:tag_service_value) { 'tag-service-value' }

it 'populates #service from the tag' do
expect { tags }
.to change { settings.service }
.from(nil)
.to(tag_service_value)
end
end

context 'conflicts with #version' do
let(:env_tags) { "env:#{tag_version_value}" }
let(:tag_version_value) { 'tag-version-value' }
Expand All @@ -563,6 +587,18 @@

it { is_expected.to include('version' => version_value) }
end

context 'defines :version with missing #version' do
let(:env_tags) { "version:#{tag_version_value}" }
let(:tag_version_value) { 'tag-version-value' }

it 'populates #version from the tag' do
expect { tags }
.to change { settings.version }
.from(nil)
.to(tag_version_value)
end
end
end
end

Expand Down
Loading

0 comments on commit f9db8f2

Please sign in to comment.