From d4564c7afc4dfc1372891a5fed1b7bdffd23f4a3 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Wed, 31 Jan 2024 14:34:10 +0100 Subject: [PATCH 1/6] Add Datadog::Core::Utils::Url module to filter sensitive info from urls Add Datadog::Core::Environment::Git module that provides git_repository_url and git_commit_sha from environment variables --- lib/datadog/core/environment/git.rb | 27 +++++++++ lib/datadog/core/git/ext.rb | 25 +------- lib/datadog/core/utils/url.rb | 17 ++++++ sig/datadog/core/environment/git.rbs | 15 +++++ sig/datadog/core/git/ext.rbs | 42 +------------- sig/datadog/core/utils/url.rbs | 9 +++ spec/datadog/core/environment/git_spec.rb | 29 ++++++++++ spec/datadog/core/utils/url_spec.rb | 69 +++++++++++++++++++++++ 8 files changed, 170 insertions(+), 63 deletions(-) create mode 100644 lib/datadog/core/environment/git.rb create mode 100644 lib/datadog/core/utils/url.rb create mode 100644 sig/datadog/core/environment/git.rbs create mode 100644 sig/datadog/core/utils/url.rbs create mode 100644 spec/datadog/core/environment/git_spec.rb create mode 100644 spec/datadog/core/utils/url_spec.rb diff --git a/lib/datadog/core/environment/git.rb b/lib/datadog/core/environment/git.rb new file mode 100644 index 0000000000..52cecaa0af --- /dev/null +++ b/lib/datadog/core/environment/git.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require_relative '../git/ext' +require_relative '../utils/url' + +module Datadog + module Core + module Environment + # Retrieves garbage collection statistics + module Git + module_function + + def git_repository_url + return @git_repository_url if defined?(@git_repository_url) + + @git_repository_url = Utils::Url.filter_sensitive_info(ENV[Datadog::Core::Git::Ext::ENV_REPOSITORY_URL]) + end + + def git_commit_sha + return @git_commit_sha if defined?(@git_commit_sha) + + @git_commit_sha = ENV[Datadog::Core::Git::Ext::ENV_COMMIT_SHA] + end + end + end + end +end diff --git a/lib/datadog/core/git/ext.rb b/lib/datadog/core/git/ext.rb index 636f4edb93..e2014841ee 100644 --- a/lib/datadog/core/git/ext.rb +++ b/lib/datadog/core/git/ext.rb @@ -5,32 +5,11 @@ module Core module Git # Defines constants for Git tags module Ext - GIT_SHA_LENGTH = 40 - - TAG_BRANCH = 'git.branch' - TAG_REPOSITORY_URL = 'git.repository_url' - TAG_TAG = 'git.tag' - - TAG_COMMIT_AUTHOR_DATE = 'git.commit.author.date' - TAG_COMMIT_AUTHOR_EMAIL = 'git.commit.author.email' - TAG_COMMIT_AUTHOR_NAME = 'git.commit.author.name' - TAG_COMMIT_COMMITTER_DATE = 'git.commit.committer.date' - TAG_COMMIT_COMMITTER_EMAIL = 'git.commit.committer.email' - TAG_COMMIT_COMMITTER_NAME = 'git.commit.committer.name' - TAG_COMMIT_MESSAGE = 'git.commit.message' - TAG_COMMIT_SHA = 'git.commit.sha' + TAG_REPOSITORY_URL = '_dd.git.repository_url' + TAG_COMMIT_SHA = '_dd.git.commit.sha' ENV_REPOSITORY_URL = 'DD_GIT_REPOSITORY_URL' ENV_COMMIT_SHA = 'DD_GIT_COMMIT_SHA' - ENV_BRANCH = 'DD_GIT_BRANCH' - ENV_TAG = 'DD_GIT_TAG' - ENV_COMMIT_MESSAGE = 'DD_GIT_COMMIT_MESSAGE' - ENV_COMMIT_AUTHOR_NAME = 'DD_GIT_COMMIT_AUTHOR_NAME' - ENV_COMMIT_AUTHOR_EMAIL = 'DD_GIT_COMMIT_AUTHOR_EMAIL' - ENV_COMMIT_AUTHOR_DATE = 'DD_GIT_COMMIT_AUTHOR_DATE' - ENV_COMMIT_COMMITTER_NAME = 'DD_GIT_COMMIT_COMMITTER_NAME' - ENV_COMMIT_COMMITTER_EMAIL = 'DD_GIT_COMMIT_COMMITTER_EMAIL' - ENV_COMMIT_COMMITTER_DATE = 'DD_GIT_COMMIT_COMMITTER_DATE' end end end diff --git a/lib/datadog/core/utils/url.rb b/lib/datadog/core/utils/url.rb new file mode 100644 index 0000000000..18a069ecc3 --- /dev/null +++ b/lib/datadog/core/utils/url.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Datadog + module Core + module Utils + # Helpers class that provides methods to proces URLs + # such as filtering sensitive information. + module Url + def self.filter_sensitive_info(url) + return nil if url.nil? + + url.gsub(%r{((https?|ssh)://)[^/]*@}, '\1') + end + end + end + end +end diff --git a/sig/datadog/core/environment/git.rbs b/sig/datadog/core/environment/git.rbs new file mode 100644 index 0000000000..e8ad16a915 --- /dev/null +++ b/sig/datadog/core/environment/git.rbs @@ -0,0 +1,15 @@ +module Datadog + module Core + module Environment + module Git + @git_repository_url: String? + + @git_commit_sha: String? + + def self?.git_repository_url: () -> String? + + def self?.git_commit_sha: () -> String? + end + end + end +end diff --git a/sig/datadog/core/git/ext.rbs b/sig/datadog/core/git/ext.rbs index 3d000c7f0c..239e669369 100644 --- a/sig/datadog/core/git/ext.rbs +++ b/sig/datadog/core/git/ext.rbs @@ -2,51 +2,13 @@ module Datadog module Core module Git module Ext - GIT_SHA_LENGTH: ::Regexp + TAG_REPOSITORY_URL: "_dd.git.repository_url" - TAG_BRANCH: "git.branch" - - TAG_REPOSITORY_URL: "git.repository_url" - - TAG_TAG: "git.tag" - - TAG_COMMIT_AUTHOR_DATE: "git.commit.author.date" - - TAG_COMMIT_AUTHOR_EMAIL: "git.commit.author.email" - - TAG_COMMIT_AUTHOR_NAME: "git.commit.author.name" - - TAG_COMMIT_COMMITTER_DATE: "git.commit.committer.date" - - TAG_COMMIT_COMMITTER_EMAIL: "git.commit.committer.email" - - TAG_COMMIT_COMMITTER_NAME: "git.commit.committer.name" - - TAG_COMMIT_MESSAGE: "git.commit.message" - - TAG_COMMIT_SHA: "git.commit.sha" + TAG_COMMIT_SHA: "_dd.git.commit.sha" ENV_REPOSITORY_URL: "DD_GIT_REPOSITORY_URL" ENV_COMMIT_SHA: "DD_GIT_COMMIT_SHA" - - ENV_BRANCH: "DD_GIT_BRANCH" - - ENV_TAG: "DD_GIT_TAG" - - ENV_COMMIT_MESSAGE: "DD_GIT_COMMIT_MESSAGE" - - ENV_COMMIT_AUTHOR_NAME: "DD_GIT_COMMIT_AUTHOR_NAME" - - ENV_COMMIT_AUTHOR_EMAIL: "DD_GIT_COMMIT_AUTHOR_EMAIL" - - ENV_COMMIT_AUTHOR_DATE: "DD_GIT_COMMIT_AUTHOR_DATE" - - ENV_COMMIT_COMMITTER_NAME: "DD_GIT_COMMIT_COMMITTER_NAME" - - ENV_COMMIT_COMMITTER_EMAIL: "DD_GIT_COMMIT_COMMITTER_EMAIL" - - ENV_COMMIT_COMMITTER_DATE: "DD_GIT_COMMIT_COMMITTER_DATE" end end end diff --git a/sig/datadog/core/utils/url.rbs b/sig/datadog/core/utils/url.rbs new file mode 100644 index 0000000000..e0d46970d2 --- /dev/null +++ b/sig/datadog/core/utils/url.rbs @@ -0,0 +1,9 @@ +module Datadog + module Core + module Utils + module Url + def self?.filter_sensitive_info: (::String? url) -> ::String? + end + end + end +end diff --git a/spec/datadog/core/environment/git_spec.rb b/spec/datadog/core/environment/git_spec.rb new file mode 100644 index 0000000000..5b8975f4fd --- /dev/null +++ b/spec/datadog/core/environment/git_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +require 'datadog/core/environment/git' + +RSpec.describe Datadog::Core::Environment::Git do + around do |example| + ClimateControl.modify(env_key => env_value) do + example.run + end + end + + describe '.git_repository_url' do + subject { described_class.git_repository_url } + + let(:env_key) { Datadog::Core::Git::Ext::ENV_REPOSITORY_URL } + let(:env_value) { 'https://gitlab-ci-token:AAA_bbb@gitlab.com/DataDog/systems-test.git' } + + it { is_expected.to eq('https://gitlab.com/DataDog/systems-test.git') } + end + + describe '.git_commit_sha' do + subject { described_class.git_commit_sha } + + let(:env_key) { Datadog::Core::Git::Ext::ENV_COMMIT_SHA } + let(:env_value) { '1234567890abcdef' } + + it { is_expected.to eq('1234567890abcdef') } + end +end diff --git a/spec/datadog/core/utils/url_spec.rb b/spec/datadog/core/utils/url_spec.rb new file mode 100644 index 0000000000..867e587c72 --- /dev/null +++ b/spec/datadog/core/utils/url_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +require 'datadog/core/utils/url' + +RSpec.describe Datadog::Core::Utils::Url do + describe '.filter_sensitive_info' do + subject(:filtered_url) { described_class.filter_sensitive_info(url) } + + context 'with https' do + context 'with username and password' do + let(:url) { 'https://gitlab-ci-token:AAA_bbb@gitlab.com/DataDog/systems-test.git' } + + it { is_expected.to eq('https://gitlab.com/DataDog/systems-test.git') } + end + + context 'with username' do + let(:url) { 'https://token@gitlab.com/user/project.git' } + + it { is_expected.to eq('https://gitlab.com/user/project.git') } + end + + context 'without credentials' do + let(:url) { 'https://gitlab.com/DataDog/systems-test.git' } + + it { is_expected.to eq('https://gitlab.com/DataDog/systems-test.git') } + end + end + + context 'with ssh' do + context 'with username and password' do + let(:url) { 'ssh://gitlab-ci-token:AAA_bbb@gitlab.com/DataDog/systems-test.git' } + + it { is_expected.to eq('ssh://gitlab.com/DataDog/systems-test.git') } + end + + context 'with username' do + let(:url) { 'ssh://token@gitlab.com/user/project.git' } + + it { is_expected.to eq('ssh://gitlab.com/user/project.git') } + end + + context 'without credentials' do + let(:url) { 'ssh://gitlab.com/DataDog/systems-test.git' } + + it { is_expected.to eq('ssh://gitlab.com/DataDog/systems-test.git') } + end + end + + context 'without protocol' do + context 'without credentials' do + let(:url) { 'gitlab.com/DataDog/systems-test.git' } + + it { is_expected.to eq('gitlab.com/DataDog/systems-test.git') } + end + + context 'with credentials' do + let(:url) { 'git@github.com:user/project.git' } + + it { is_expected.to eq('git@github.com:user/project.git') } + end + end + + context 'with nil' do + let(:url) { nil } + + it { is_expected.to be_nil } + end + end +end From 3c7eaf9641632e5e34e5f3ea19d34f1150d3c2e2 Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Wed, 31 Jan 2024 16:34:50 +0100 Subject: [PATCH 2/6] [tracing] send source code integration tags in the first span of trace chunk --- lib/datadog/core/environment/git.rb | 4 +- lib/datadog/core/utils/url.rb | 14 +++- .../tracing/transport/trace_formatter.rb | 31 ++++++++ sig/datadog/core/utils/url.rbs | 2 +- .../tracing/transport/trace_formatter.rbs | 10 +++ spec/datadog/core/environment/git_spec.rb | 18 +++++ spec/datadog/core/utils/url_spec.rb | 4 +- .../tracing/transport/trace_formatter_spec.rb | 76 ++++++++++++++++++- 8 files changed, 150 insertions(+), 9 deletions(-) diff --git a/lib/datadog/core/environment/git.rb b/lib/datadog/core/environment/git.rb index 52cecaa0af..382633a201 100644 --- a/lib/datadog/core/environment/git.rb +++ b/lib/datadog/core/environment/git.rb @@ -6,14 +6,14 @@ module Datadog module Core module Environment - # Retrieves garbage collection statistics + # Retrieves git repository information from environment variables module Git module_function def git_repository_url return @git_repository_url if defined?(@git_repository_url) - @git_repository_url = Utils::Url.filter_sensitive_info(ENV[Datadog::Core::Git::Ext::ENV_REPOSITORY_URL]) + @git_repository_url = Utils::Url.filter_basic_auth(ENV[Datadog::Core::Git::Ext::ENV_REPOSITORY_URL]) end def git_commit_sha diff --git a/lib/datadog/core/utils/url.rb b/lib/datadog/core/utils/url.rb index 18a069ecc3..d11c0c9688 100644 --- a/lib/datadog/core/utils/url.rb +++ b/lib/datadog/core/utils/url.rb @@ -1,15 +1,23 @@ # frozen_string_literal: true +require 'uri' + module Datadog module Core module Utils - # Helpers class that provides methods to proces URLs + # Helpers class that provides methods to process URLs # such as filtering sensitive information. module Url - def self.filter_sensitive_info(url) + def self.filter_basic_auth(url) return nil if url.nil? - url.gsub(%r{((https?|ssh)://)[^/]*@}, '\1') + URI(url).tap do |u| + u.user = nil + u.password = nil + end.to_s + # Git scheme: git@github.com:DataDog/dd-trace-rb.git + rescue URI::InvalidURIError + url end end end diff --git a/lib/datadog/tracing/transport/trace_formatter.rb b/lib/datadog/tracing/transport/trace_formatter.rb index e03c66f78b..41a5e2a4c4 100644 --- a/lib/datadog/tracing/transport/trace_formatter.rb +++ b/lib/datadog/tracing/transport/trace_formatter.rb @@ -2,6 +2,8 @@ require_relative '../../core/environment/identity' require_relative '../../core/environment/socket' +require_relative '../../core/environment/git' +require_relative '../../core/git/ext' require_relative '../../core/runtime/ext' require_relative '../metadata/ext' require_relative '../trace_segment' @@ -13,6 +15,7 @@ module Transport class TraceFormatter attr_reader \ :root_span, + :first_span, :trace def self.format!(trace) @@ -22,6 +25,9 @@ def self.format!(trace) def initialize(trace) @trace = trace @root_span = find_root_span(trace) + # source code integration uses the "first span in trace chunk" concept instead of root span + # see: https://github.com/DataDog/dd-trace-rb/pull/3424 + @first_span = trace.spans.first end # Modifies a trace so suitable for transport @@ -54,6 +60,11 @@ def format! tag_sampling_priority! tag_profiling_enabled! + return trace unless first_span + + tag_git_repository_url! + tag_git_commit_sha! + trace end @@ -185,6 +196,18 @@ def tag_profiling_enabled! ) end + def tag_git_repository_url! + return if git_repository_url.nil? + + first_span.set_tag(Core::Git::Ext::TAG_REPOSITORY_URL, git_repository_url) + end + + def tag_git_commit_sha! + return if git_commit_sha.nil? + + first_span.set_tag(Core::Git::Ext::TAG_COMMIT_SHA, git_commit_sha) + end + private def partial? @@ -203,6 +226,14 @@ def find_root_span(trace) # when root span is not found, fall back to last span (partial flush) root_span || trace.spans.last end + + def git_repository_url + Core::Environment::Git.git_repository_url + end + + def git_commit_sha + Core::Environment::Git.git_commit_sha + end end end end diff --git a/sig/datadog/core/utils/url.rbs b/sig/datadog/core/utils/url.rbs index e0d46970d2..51b651c6c8 100644 --- a/sig/datadog/core/utils/url.rbs +++ b/sig/datadog/core/utils/url.rbs @@ -2,7 +2,7 @@ module Datadog module Core module Utils module Url - def self?.filter_sensitive_info: (::String? url) -> ::String? + def self?.filter_basic_auth: (::String? url) -> ::String? end end end diff --git a/sig/datadog/tracing/transport/trace_formatter.rbs b/sig/datadog/tracing/transport/trace_formatter.rbs index 7f3604db7f..cb8e14c698 100644 --- a/sig/datadog/tracing/transport/trace_formatter.rbs +++ b/sig/datadog/tracing/transport/trace_formatter.rbs @@ -4,6 +4,8 @@ module Datadog class TraceFormatter attr_reader root_span: untyped + attr_reader first_span: untyped + attr_reader trace: untyped def self.format!: (untyped trace) -> untyped @@ -40,11 +42,19 @@ module Datadog def tag_high_order_trace_id!: () -> (nil | untyped) + def tag_git_repository_url!: () -> (nil | untyped) + + def tag_git_commit_sha!: () -> (nil | untyped) + private def partial?: () -> untyped def find_root_span: (untyped trace) -> untyped + + def git_repository_url: () -> (nil | untyped) + + def git_commit_sha: () -> (nil | untyped) end end end diff --git a/spec/datadog/core/environment/git_spec.rb b/spec/datadog/core/environment/git_spec.rb index 5b8975f4fd..ad5b7e2149 100644 --- a/spec/datadog/core/environment/git_spec.rb +++ b/spec/datadog/core/environment/git_spec.rb @@ -3,12 +3,30 @@ require 'datadog/core/environment/git' RSpec.describe Datadog::Core::Environment::Git do + def remove_cached_variables + if described_class.instance_variable_defined?(:@git_repository_url) + described_class.remove_instance_variable(:@git_repository_url) + end + + if described_class.instance_variable_defined?(:@git_commit_sha) + described_class.remove_instance_variable(:@git_commit_sha) + end + end + around do |example| ClimateControl.modify(env_key => env_value) do example.run end end + before do + remove_cached_variables + end + + after do + remove_cached_variables + end + describe '.git_repository_url' do subject { described_class.git_repository_url } diff --git a/spec/datadog/core/utils/url_spec.rb b/spec/datadog/core/utils/url_spec.rb index 867e587c72..e09c667b20 100644 --- a/spec/datadog/core/utils/url_spec.rb +++ b/spec/datadog/core/utils/url_spec.rb @@ -3,8 +3,8 @@ require 'datadog/core/utils/url' RSpec.describe Datadog::Core::Utils::Url do - describe '.filter_sensitive_info' do - subject(:filtered_url) { described_class.filter_sensitive_info(url) } + describe '.filter_basic_auth' do + subject(:filtered_url) { described_class.filter_basic_auth(url) } context 'with https' do context 'with username and password' do diff --git a/spec/datadog/tracing/transport/trace_formatter_spec.rb b/spec/datadog/tracing/transport/trace_formatter_spec.rb index 2a560d73d0..59eb2e51c9 100644 --- a/spec/datadog/tracing/transport/trace_formatter_spec.rb +++ b/spec/datadog/tracing/transport/trace_formatter_spec.rb @@ -66,10 +66,32 @@ end end + shared_context 'git environment stub' do + before do + allow(Datadog::Core::Environment::Git).to receive(:git_repository_url).and_return(git_repository_url) + allow(Datadog::Core::Environment::Git).to receive(:git_commit_sha).and_return(git_commit_sha) + end + end + + shared_context 'git metadata' do + let(:git_repository_url) { 'git_repository_url' } + let(:git_commit_sha) { 'git_commit_sha' } + + include_context 'git environment stub' + end + + shared_context 'no git metadata' do + let(:git_repository_url) { nil } + let(:git_commit_sha) { nil } + + include_context 'git environment stub' + end + shared_context 'no root span' do let(:trace) { Datadog::Tracing::TraceSegment.new(spans, **trace_options) } let(:spans) { Array.new(3) { Datadog::Tracing::Span.new('my.job') } } let(:root_span) { spans.last } + let(:first_span) { spans.first } end shared_context 'missing root span' do @@ -82,12 +104,14 @@ end let(:spans) { Array.new(3) { Datadog::Tracing::Span.new('my.job') } } let(:root_span) { spans.last } + let(:first_span) { spans.first } end shared_context 'available root span' do let(:trace) { Datadog::Tracing::TraceSegment.new(spans, root_span_id: root_span.id, **trace_options) } let(:spans) { Array.new(3) { Datadog::Tracing::Span.new('my.job') } } let(:root_span) { spans[1] } + let(:first_span) { spans.first } end describe '::new' do @@ -96,7 +120,8 @@ it do is_expected.to have_attributes( trace: trace, - root_span: root_span + root_span: root_span, + first_span: first_span ) end end @@ -194,6 +219,25 @@ end end + shared_examples 'first span with no git metadata' do + it do + format! + expect(first_span.meta).to_not include('_dd.git.repository_url', '_dd.git.commit.sha') + end + end + + shared_examples 'first span with git metadata' do + it do + format! + expect(first_span.meta).to include( + { + '_dd.git.repository_url' => git_repository_url, + '_dd.git.commit.sha' => git_commit_sha + } + ) + end + end + context 'with no root span' do include_context 'no root span' @@ -231,6 +275,16 @@ it_behaves_like 'root span with tags' it_behaves_like 'root span without generic tags' end + + context 'with git metadata' do + include_context 'git metadata' + it_behaves_like 'first span with git metadata' + end + + context 'without git metadata' do + include_context 'no git metadata' + it_behaves_like 'first span with no git metadata' + end end context 'with missing root span' do @@ -270,6 +324,16 @@ it_behaves_like 'root span with tags' it_behaves_like 'root span without generic tags' end + + context 'with git metadata' do + include_context 'git metadata' + it_behaves_like 'first span with git metadata' + end + + context 'without git metadata' do + include_context 'no git metadata' + it_behaves_like 'first span with no git metadata' + end end context 'with a root span' do @@ -311,6 +375,16 @@ it_behaves_like 'root span with tags' it_behaves_like 'root span with generic tags' end + + context 'with git metadata' do + include_context 'git metadata' + it_behaves_like 'first span with git metadata' + end + + context 'without git metadata' do + include_context 'no git metadata' + it_behaves_like 'first span with no git metadata' + end end end end From d292844fc59fd705363acdb6616da21109f3fc7f Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Thu, 15 Feb 2024 13:59:10 +0100 Subject: [PATCH 3/6] [profiling] add source code integration tags to TagBuilder --- lib/datadog/core/environment/git.rb | 6 ++--- lib/datadog/profiling/tag_builder.rb | 7 ++++++ spec/datadog/profiling/tag_builder_spec.rb | 28 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/lib/datadog/core/environment/git.rb b/lib/datadog/core/environment/git.rb index 382633a201..1b40a59983 100644 --- a/lib/datadog/core/environment/git.rb +++ b/lib/datadog/core/environment/git.rb @@ -8,15 +8,13 @@ module Core module Environment # Retrieves git repository information from environment variables module Git - module_function - - def git_repository_url + def self.git_repository_url return @git_repository_url if defined?(@git_repository_url) @git_repository_url = Utils::Url.filter_basic_auth(ENV[Datadog::Core::Git::Ext::ENV_REPOSITORY_URL]) end - def git_commit_sha + def self.git_commit_sha return @git_commit_sha if defined?(@git_commit_sha) @git_commit_sha = ENV[Datadog::Core::Git::Ext::ENV_COMMIT_SHA] diff --git a/lib/datadog/profiling/tag_builder.rb b/lib/datadog/profiling/tag_builder.rb index b90b382820..be10c2bddc 100644 --- a/lib/datadog/profiling/tag_builder.rb +++ b/lib/datadog/profiling/tag_builder.rb @@ -1,12 +1,15 @@ # frozen_string_literal: true require_relative '../core/utils' +require_relative '../core/environment/git' +require_relative '../core/git/ext' module Datadog module Profiling # Builds a hash of default plus user tags to be included in a profile module TagBuilder include Datadog::Profiling::Ext::Transport::HTTP # Tag name constants + include Datadog::Core::Git::Ext # Git tags constants def self.call( settings:, @@ -23,6 +26,8 @@ def self.call( runtime_id: Core::Environment::Identity.id, runtime_platform: Core::Environment::Identity.lang_platform, runtime_version: Core::Environment::Identity.lang_version, + git_repository_url: Core::Environment::Git.git_repository_url, + git_commit_sha: Core::Environment::Git.git_commit_sha, # User-provided tags user_tags: settings.tags ) @@ -42,6 +47,8 @@ def self.call( tags[FORM_FIELD_TAG_ENV] = env if env tags[FORM_FIELD_TAG_SERVICE] = service if service tags[FORM_FIELD_TAG_VERSION] = version if version + tags[TAG_REPOSITORY_URL] = git_repository_url if git_repository_url + tags[TAG_COMMIT_SHA] = git_commit_sha if git_commit_sha # Make sure everything is an utf-8 string, to avoid encoding issues in native code/libddprof/further downstream user_tags.merge(tags).map do |key, value| diff --git a/spec/datadog/profiling/tag_builder_spec.rb b/spec/datadog/profiling/tag_builder_spec.rb index 44dbfd491f..3b82a70d4f 100644 --- a/spec/datadog/profiling/tag_builder_spec.rb +++ b/spec/datadog/profiling/tag_builder_spec.rb @@ -78,5 +78,33 @@ expect(result).to include('ascii-key' => 'ascii-value') end end + + describe 'source code integration' do + context 'when git environment is available' do + before do + allow(Datadog::Core::Environment::Git).to receive(:git_repository_url).and_return( + 'git_repository_url' + ) + allow(Datadog::Core::Environment::Git).to receive(:git_commit_sha).and_return('git_commit_sha') + end + + it 'includes the git repository URL and commit SHA' do + expect(call).to include( + '_dd.git.repository_url' => 'git_repository_url', '_dd.git.commit.sha' => 'git_commit_sha' + ) + end + end + + context 'when git environment is not available' do + before do + allow(Datadog::Core::Environment::Git).to receive(:git_repository_url).and_return(nil) + allow(Datadog::Core::Environment::Git).to receive(:git_commit_sha).and_return(nil) + end + + it 'includes the git repository URL and commit SHA' do + expect(call).to_not include('_dd.git.repository_url', '_dd.git.commit.sha') + end + end + end end end From 45fdf4b552da2f79173ff9bc6dd92a923e63f20d Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Thu, 15 Feb 2024 17:41:37 +0100 Subject: [PATCH 4/6] [profiling] do not use _dd prefix for profiling tags --- lib/datadog/profiling/ext.rb | 2 ++ lib/datadog/profiling/tag_builder.rb | 6 ++---- sig/datadog/profiling/ext.rbs | 2 ++ spec/datadog/profiling/tag_builder_spec.rb | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/datadog/profiling/ext.rb b/lib/datadog/profiling/ext.rb index 2122ec7a95..ca8380b0e8 100644 --- a/lib/datadog/profiling/ext.rb +++ b/lib/datadog/profiling/ext.rb @@ -23,6 +23,8 @@ module HTTP FORM_FIELD_TAG_RUNTIME_VERSION = 'runtime_version' FORM_FIELD_TAG_SERVICE = 'service' FORM_FIELD_TAG_VERSION = 'version' + FORM_FIELD_TAG_GIT_REPOSITORY_URL = 'git.repository_url' + FORM_FIELD_TAG_GIT_COMMIT_SHA = 'git.commit.sha' PPROF_DEFAULT_FILENAME = 'rubyprofile.pprof' CODE_PROVENANCE_FILENAME = 'code-provenance.json' diff --git a/lib/datadog/profiling/tag_builder.rb b/lib/datadog/profiling/tag_builder.rb index be10c2bddc..65ae026084 100644 --- a/lib/datadog/profiling/tag_builder.rb +++ b/lib/datadog/profiling/tag_builder.rb @@ -2,14 +2,12 @@ require_relative '../core/utils' require_relative '../core/environment/git' -require_relative '../core/git/ext' module Datadog module Profiling # Builds a hash of default plus user tags to be included in a profile module TagBuilder include Datadog::Profiling::Ext::Transport::HTTP # Tag name constants - include Datadog::Core::Git::Ext # Git tags constants def self.call( settings:, @@ -47,8 +45,8 @@ def self.call( tags[FORM_FIELD_TAG_ENV] = env if env tags[FORM_FIELD_TAG_SERVICE] = service if service tags[FORM_FIELD_TAG_VERSION] = version if version - tags[TAG_REPOSITORY_URL] = git_repository_url if git_repository_url - tags[TAG_COMMIT_SHA] = git_commit_sha if git_commit_sha + tags[FORM_FIELD_TAG_GIT_REPOSITORY_URL] = git_repository_url if git_repository_url + tags[FORM_FIELD_TAG_GIT_COMMIT_SHA] = git_commit_sha if git_commit_sha # Make sure everything is an utf-8 string, to avoid encoding issues in native code/libddprof/further downstream user_tags.merge(tags).map do |key, value| diff --git a/sig/datadog/profiling/ext.rbs b/sig/datadog/profiling/ext.rbs index f68c2a377b..873d8e40a2 100644 --- a/sig/datadog/profiling/ext.rbs +++ b/sig/datadog/profiling/ext.rbs @@ -23,6 +23,8 @@ module Datadog FORM_FIELD_TAG_RUNTIME_VERSION: "runtime_version" FORM_FIELD_TAG_SERVICE: "service" FORM_FIELD_TAG_VERSION: "version" + FORM_FIELD_TAG_GIT_REPOSITORY_URL: 'git.repository_url' + FORM_FIELD_TAG_GIT_COMMIT_SHA: 'git.commit.sha' PPROF_DEFAULT_FILENAME: "rubyprofile.pprof" CODE_PROVENANCE_FILENAME: "code-provenance.json" end diff --git a/spec/datadog/profiling/tag_builder_spec.rb b/spec/datadog/profiling/tag_builder_spec.rb index 3b82a70d4f..148f0b26dc 100644 --- a/spec/datadog/profiling/tag_builder_spec.rb +++ b/spec/datadog/profiling/tag_builder_spec.rb @@ -90,7 +90,7 @@ it 'includes the git repository URL and commit SHA' do expect(call).to include( - '_dd.git.repository_url' => 'git_repository_url', '_dd.git.commit.sha' => 'git_commit_sha' + 'git.repository_url' => 'git_repository_url', 'git.commit.sha' => 'git_commit_sha' ) end end @@ -102,7 +102,7 @@ end it 'includes the git repository URL and commit SHA' do - expect(call).to_not include('_dd.git.repository_url', '_dd.git.commit.sha') + expect(call).to_not include('git.repository_url', 'git.commit.sha') end end end From 92a95d781fa55cbdb5fe10a307708390d99e2b7f Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 16 Feb 2024 13:12:14 +0100 Subject: [PATCH 5/6] [profiling] remove FORM_FIELD_ prefix from git tags --- lib/datadog/profiling/ext.rb | 4 ++-- lib/datadog/profiling/tag_builder.rb | 4 ++-- sig/datadog/profiling/ext.rbs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/datadog/profiling/ext.rb b/lib/datadog/profiling/ext.rb index ca8380b0e8..9dea808ddf 100644 --- a/lib/datadog/profiling/ext.rb +++ b/lib/datadog/profiling/ext.rb @@ -23,8 +23,8 @@ module HTTP FORM_FIELD_TAG_RUNTIME_VERSION = 'runtime_version' FORM_FIELD_TAG_SERVICE = 'service' FORM_FIELD_TAG_VERSION = 'version' - FORM_FIELD_TAG_GIT_REPOSITORY_URL = 'git.repository_url' - FORM_FIELD_TAG_GIT_COMMIT_SHA = 'git.commit.sha' + TAG_GIT_REPOSITORY_URL = 'git.repository_url' + TAG_GIT_COMMIT_SHA = 'git.commit.sha' PPROF_DEFAULT_FILENAME = 'rubyprofile.pprof' CODE_PROVENANCE_FILENAME = 'code-provenance.json' diff --git a/lib/datadog/profiling/tag_builder.rb b/lib/datadog/profiling/tag_builder.rb index 65ae026084..2325a7b93f 100644 --- a/lib/datadog/profiling/tag_builder.rb +++ b/lib/datadog/profiling/tag_builder.rb @@ -45,8 +45,8 @@ def self.call( tags[FORM_FIELD_TAG_ENV] = env if env tags[FORM_FIELD_TAG_SERVICE] = service if service tags[FORM_FIELD_TAG_VERSION] = version if version - tags[FORM_FIELD_TAG_GIT_REPOSITORY_URL] = git_repository_url if git_repository_url - tags[FORM_FIELD_TAG_GIT_COMMIT_SHA] = git_commit_sha if git_commit_sha + tags[TAG_GIT_REPOSITORY_URL] = git_repository_url if git_repository_url + tags[TAG_GIT_COMMIT_SHA] = git_commit_sha if git_commit_sha # Make sure everything is an utf-8 string, to avoid encoding issues in native code/libddprof/further downstream user_tags.merge(tags).map do |key, value| diff --git a/sig/datadog/profiling/ext.rbs b/sig/datadog/profiling/ext.rbs index 873d8e40a2..1ad36590f8 100644 --- a/sig/datadog/profiling/ext.rbs +++ b/sig/datadog/profiling/ext.rbs @@ -23,8 +23,8 @@ module Datadog FORM_FIELD_TAG_RUNTIME_VERSION: "runtime_version" FORM_FIELD_TAG_SERVICE: "service" FORM_FIELD_TAG_VERSION: "version" - FORM_FIELD_TAG_GIT_REPOSITORY_URL: 'git.repository_url' - FORM_FIELD_TAG_GIT_COMMIT_SHA: 'git.commit.sha' + TAG_GIT_REPOSITORY_URL: "git.repository_url" + TAG_GIT_COMMIT_SHA: "git.commit.sha" PPROF_DEFAULT_FILENAME: "rubyprofile.pprof" CODE_PROVENANCE_FILENAME: "code-provenance.json" end From 79079ec11ef086ca1846fda67e9eb8f9716ddc8e Mon Sep 17 00:00:00 2001 From: Andrey Marchenko Date: Fri, 16 Feb 2024 15:34:04 +0100 Subject: [PATCH 6/6] addressing minor code review comments --- lib/datadog/tracing/transport/trace_formatter.rb | 8 ++++---- spec/datadog/tracing/transport/trace_formatter_spec.rb | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/datadog/tracing/transport/trace_formatter.rb b/lib/datadog/tracing/transport/trace_formatter.rb index 41a5e2a4c4..2140ccebdd 100644 --- a/lib/datadog/tracing/transport/trace_formatter.rb +++ b/lib/datadog/tracing/transport/trace_formatter.rb @@ -60,10 +60,10 @@ def format! tag_sampling_priority! tag_profiling_enabled! - return trace unless first_span - - tag_git_repository_url! - tag_git_commit_sha! + if first_span + tag_git_repository_url! + tag_git_commit_sha! + end trace end diff --git a/spec/datadog/tracing/transport/trace_formatter_spec.rb b/spec/datadog/tracing/transport/trace_formatter_spec.rb index 59eb2e51c9..f2bd23d69a 100644 --- a/spec/datadog/tracing/transport/trace_formatter_spec.rb +++ b/spec/datadog/tracing/transport/trace_formatter_spec.rb @@ -120,8 +120,7 @@ it do is_expected.to have_attributes( trace: trace, - root_span: root_span, - first_span: first_span + root_span: root_span ) end end