From e8a86246d66f14287e4fa49be94d822e8335ad04 Mon Sep 17 00:00:00 2001 From: Sarah Chen Date: Thu, 20 Jul 2023 11:15:56 -0400 Subject: [PATCH 1/7] first round of changes. --- lib/datadog/tracing/component.rb | 2 +- .../tracing/diagnostics/environment_logger.rb | 286 +++++++++++++++ lib/datadog/tracing/diagnostics/ext.rb | 2 + lib/datadog/tracing/workers/trace_writer.rb | 2 +- .../core/configuration/components_spec.rb | 2 +- .../diagnostics/environment_logger_spec.rb | 331 ++++++++++++++++++ spec/datadog/tracing/writer_spec.rb | 2 +- 7 files changed, 623 insertions(+), 4 deletions(-) create mode 100644 lib/datadog/tracing/diagnostics/environment_logger.rb create mode 100644 spec/datadog/tracing/diagnostics/environment_logger_spec.rb diff --git a/lib/datadog/tracing/component.rb b/lib/datadog/tracing/component.rb index 0cb993ab1d2..1667659b3a6 100644 --- a/lib/datadog/tracing/component.rb +++ b/lib/datadog/tracing/component.rb @@ -140,7 +140,7 @@ def subscribe_to_writer_events!(writer, sampler, test_mode) end WRITER_RECORD_ENVIRONMENT_INFORMATION_CALLBACK = lambda do |_, responses| - Core::Diagnostics::EnvironmentLogger.log!(responses) + Tracing::Diagnostics::EnvironmentLogger.log!(responses) end # Create new lambda for writer callback, diff --git a/lib/datadog/tracing/diagnostics/environment_logger.rb b/lib/datadog/tracing/diagnostics/environment_logger.rb new file mode 100644 index 00000000000..df9e9a8c10f --- /dev/null +++ b/lib/datadog/tracing/diagnostics/environment_logger.rb @@ -0,0 +1,286 @@ +require 'date' +require 'json' +require 'rbconfig' + +module Datadog + module Tracing + module Diagnostics + # A holistic collection of the environment in which ddtrace is running. + # This logger should allow for easy reporting by users to Datadog support. + # + module EnvironmentLogger + class << self + # Outputs environment information to {Datadog.logger}. + # Executes only once for the lifetime of the program. + def log!(transport_responses) + return if (defined?(@executed) && @executed) || !log? + + @executed = true + + data = EnvironmentCollector.new.collect!(transport_responses) + data.reject! { |_, v| v.nil? } # Remove empty values from hash output + + log_environment!(data.to_json) + log_error!('Agent Error'.freeze, data[:agent_error]) if data[:agent_error] + rescue => e + Datadog.logger.warn("Failed to collect environment information: #{e} Location: #{Array(e.backtrace).first}") + end + + private + + def log_environment!(line) + Datadog.logger.info("DATADOG CONFIGURATION - #{line}") + end + + def log_error!(type, error) + Datadog.logger.warn("DATADOG DIAGNOSTIC - #{type}: #{error}") + end + + # Are we logging the environment data? + def log? + startup_logs_enabled = Datadog.configuration.diagnostics.startup_logs.enabled + if startup_logs_enabled.nil? + !repl? # Suppress logs if we running in a REPL + else + startup_logs_enabled + end + end + + REPL_PROGRAM_NAMES = %w[irb pry].freeze + + def repl? + REPL_PROGRAM_NAMES.include?($PROGRAM_NAME) + end + end + end + + # Collects environment information for diagnostic logging + class EnvironmentCollector + # @return [String] current time in ISO8601 format + def date + DateTime.now.iso8601 + end + + # Best portable guess of OS information. + # @return [String] platform string + def os_name + RbConfig::CONFIG['host'.freeze] + end + + # @return [String] ddtrace version + def version + DDTrace::VERSION::STRING + end + + # @return [String] "ruby" + def lang + Diagnostics::Ext::LANG + end + + # Supported Ruby language version. + # Will be distinct from VM version for non-MRI environments. + # @return [String] + def lang_version + Diagnostics::Ext::LANG_VERSION + end + + # @return [String] configured application environment + def env + Datadog.configuration.env + end + + # @return [Boolean, nil] + def enabled + Datadog.configuration.tracing.enabled + end + + # @return [String] configured application service name + def service + Datadog.configuration.service + end + + # @return [String] configured application version + def dd_version + Datadog.configuration.version + end + + # @return [String, nil] target agent URL for trace flushing + def agent_url + # Retrieve the effect agent URL, regardless of how it was configured + transport = Tracing.send(:tracer).writer.transport + + # return `nil` with IO transport + return unless transport.respond_to?(:client) + + adapter = transport.client.api.adapter + adapter.url + end + + # Error returned by Datadog agent during a tracer flush attempt + # @return [String] concatenated list of transport errors + def agent_error(transport_responses) + error_responses = transport_responses.reject(&:ok?) + + return nil if error_responses.empty? + + error_responses.map(&:inspect).join(','.freeze) + end + + # @return [Boolean, nil] debug mode enabled in configuration + def debug + !!Datadog.configuration.diagnostics.debug + end + + # @return [Boolean, nil] analytics enabled in configuration + def analytics_enabled + !!Datadog.configuration.tracing.analytics.enabled + end + + # @return [Numeric, nil] tracer sample rate configured + def sample_rate + sampler = Datadog.configuration.tracing.sampler + return nil unless sampler + + sampler.sample_rate(nil) rescue nil + end + + # DEV: We currently only support SimpleRule instances. + # DEV: These are the most commonly used rules. + # DEV: We should expand support for other rules in the future, + # DEV: although it is tricky to serialize arbitrary rules. + # + # @return [Hash, nil] sample rules configured + def sampling_rules + sampler = Datadog.configuration.tracing.sampler + return nil unless sampler.is_a?(Tracing::Sampling::PrioritySampler) && + sampler.priority_sampler.is_a?(Tracing::Sampling::RuleSampler) + + sampler.priority_sampler.rules.map do |rule| + next unless rule.is_a?(Tracing::Sampling::SimpleRule) + + { + name: rule.matcher.name, + service: rule.matcher.service, + sample_rate: rule.sampler.sample_rate(nil) + } + end.compact + end + + # @return [Hash, nil] concatenated list of global tracer tags configured + def tags + tags = Datadog.configuration.tags + return nil if tags.empty? + + hash_serializer(tags) + end + + # @return [Boolean, nil] runtime metrics enabled in configuration + def runtime_metrics_enabled + Datadog.configuration.runtime_metrics.enabled + end + + # Concatenated list of integrations activated, with their gem version. + # Example: "rails@6.0.3,rack@2.2.3" + # + # @return [String, nil] + def integrations_loaded + integrations = instrumented_integrations + return if integrations.empty? + + integrations.map { |name, integration| "#{name}@#{integration.class.version}" }.join(','.freeze) + end + + # Ruby VM name and version. + # Examples: "ruby-2.7.1", "jruby-9.2.11.1", "truffleruby-20.1.0" + # @return [String, nil] + def vm + # RUBY_ENGINE_VERSION returns the VM version, which + # will differ from RUBY_VERSION for non-mri VMs. + if defined?(RUBY_ENGINE_VERSION) + "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" + else + # Ruby < 2.3 doesn't support RUBY_ENGINE_VERSION + "#{RUBY_ENGINE}-#{RUBY_VERSION}" + end + end + + # @return [Boolean, nil] partial flushing enabled in configuration + def partial_flushing_enabled + !!Datadog.configuration.tracing.partial_flush.enabled + end + + # @return [Boolean, nil] priority sampling enabled in configuration + def priority_sampling_enabled + !!Datadog.configuration.tracing.priority_sampling + end + + # @return [Boolean, nil] health metrics enabled in configuration + def health_metrics_enabled + !!Datadog.configuration.diagnostics.health_metrics.enabled + end + + def profiling_enabled + !!Datadog.configuration.profiling.enabled + end + + # TODO: Populate when automatic log correlation is implemented + # def logs_correlation_enabled + # end + + # @return [Hash] environment information available at call time + def collect!(transport_responses) + { + date: date, + os_name: os_name, + version: version, + lang: lang, + lang_version: lang_version, + env: env, + enabled: enabled, + service: service, + dd_version: dd_version, + agent_url: agent_url, + agent_error: agent_error(transport_responses), + debug: debug, + analytics_enabled: analytics_enabled, + sample_rate: sample_rate, + sampling_rules: sampling_rules, + tags: tags, + runtime_metrics_enabled: runtime_metrics_enabled, + integrations_loaded: integrations_loaded, + vm: vm, + partial_flushing_enabled: partial_flushing_enabled, + priority_sampling_enabled: priority_sampling_enabled, + health_metrics_enabled: health_metrics_enabled, + profiling_enabled: profiling_enabled, + **instrumented_integrations_settings + } + end + + private + + def instrumented_integrations + Datadog.configuration.tracing.instrumented_integrations + end + + # Capture all active integration settings into "integrationName_settingName: value" entries. + def instrumented_integrations_settings + instrumented_integrations.flat_map do |name, integration| + integration.configuration.to_h.flat_map do |setting, value| + next [] if setting == :tracer # Skip internal Ruby objects + + # Convert value to a string to avoid custom #to_json + # handlers possibly causing errors. + [[:"integration_#{name}_#{setting}", value.to_s]] + end + end.to_h + end + + # Outputs "k1:v1,k2:v2,..." + def hash_serializer(h) + h.map { |k, v| "#{k}:#{v}" }.join(','.freeze) + end + end + end + end +end diff --git a/lib/datadog/tracing/diagnostics/ext.rb b/lib/datadog/tracing/diagnostics/ext.rb index a0b3aa30062..32fc66d5580 100644 --- a/lib/datadog/tracing/diagnostics/ext.rb +++ b/lib/datadog/tracing/diagnostics/ext.rb @@ -5,6 +5,8 @@ module Tracing module Diagnostics # @public_api module Ext + LANG = 'ruby' + LANG_VERSION = RUBY_VERSION # Health module Health # Metrics diff --git a/lib/datadog/tracing/workers/trace_writer.rb b/lib/datadog/tracing/workers/trace_writer.rb index fdd6c11d926..97e86e98b5d 100644 --- a/lib/datadog/tracing/workers/trace_writer.rb +++ b/lib/datadog/tracing/workers/trace_writer.rb @@ -57,7 +57,7 @@ def flush_traces(traces) end end - # TODO: Register `Datadog::Core::Diagnostics::EnvironmentLogger.log!` + # TODO: Register `Datadog::Tracing::Diagnostics::EnvironmentLogger.log!` # TODO: as a flush_completed subscriber when the `TraceWriter` # TODO: instantiation code is implemented. def flush_completed diff --git a/spec/datadog/core/configuration/components_spec.rb b/spec/datadog/core/configuration/components_spec.rb index 2c4c297c71a..764a885267e 100644 --- a/spec/datadog/core/configuration/components_spec.rb +++ b/spec/datadog/core/configuration/components_spec.rb @@ -917,7 +917,7 @@ let(:responses) { [double('response')] } it 'invokes the environment logger with responses' do - expect(Datadog::Core::Diagnostics::EnvironmentLogger).to receive(:log!).with(responses) + expect(Datadog::Tracing::Diagnostics::EnvironmentLogger).to receive(:log!).with(responses) call end end diff --git a/spec/datadog/tracing/diagnostics/environment_logger_spec.rb b/spec/datadog/tracing/diagnostics/environment_logger_spec.rb new file mode 100644 index 00000000000..53966fb7658 --- /dev/null +++ b/spec/datadog/tracing/diagnostics/environment_logger_spec.rb @@ -0,0 +1,331 @@ +require 'spec_helper' + +require 'datadog/tracing/diagnostics/environment_logger' +require 'ddtrace/transport/io' + +RSpec.describe Datadog::Tracing::Diagnostics::EnvironmentLogger do + subject(:env_logger) { described_class } + + # Reading DD_AGENT_HOST allows this to work in CI + let(:agent_hostname) { ENV['DD_AGENT_HOST'] || '127.0.0.1' } + let(:agent_port) { ENV['DD_TRACE_AGENT_PORT'] || 8126 } + + before do + allow(DateTime).to receive(:now).and_return(DateTime.new(2020)) + + # Resets "only-once" execution pattern of `log!` + env_logger.instance_variable_set(:@executed, nil) + + Datadog.configuration.reset! + end + + describe '#log!' do + subject(:log!) { env_logger.log!([response]) } + + let(:logger) do + log! + tracer_logger + end + + let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } + let(:tracer_logger) { instance_double(Datadog::Tracing::Logger) } + + before do + allow(Datadog).to receive(:logger).and_return(tracer_logger) + allow(tracer_logger).to receive(:debug?).and_return true + allow(tracer_logger).to receive(:debug) + allow(tracer_logger).to receive(:info) + allow(tracer_logger).to receive(:warn) + allow(tracer_logger).to receive(:error) + end + + it 'with a default tracer settings' do + expect(logger).to have_received(:info).with start_with('DATADOG CONFIGURATION') do |msg| + json = JSON.parse(msg.partition('-')[2].strip) + expect(json).to match( + 'agent_url' => start_with("http://#{agent_hostname}:#{agent_port}?timeout="), + 'analytics_enabled' => false, + 'date' => '2020-01-01T00:00:00+00:00', + 'debug' => false, + 'enabled' => true, + 'health_metrics_enabled' => false, + 'lang' => 'ruby', + 'lang_version' => match(/[23]\./), + 'os_name' => (include('x86_64').or include('i686').or include('aarch64').or include('arm')), + 'partial_flushing_enabled' => false, + 'priority_sampling_enabled' => false, + 'runtime_metrics_enabled' => false, + 'version' => DDTrace::VERSION::STRING, + 'vm' => be_a(String), + 'service' => be_a(String), + 'profiling_enabled' => false, + ) + end + end + + context 'with multiple invocations' do + it 'executes only once' do + env_logger.log!([response]) + env_logger.log!([response]) + + expect(logger).to have_received(:info).once + end + end + + context 'with agent error' do + before { allow(tracer_logger).to receive(:warn) } + + let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } + + it do + expect(logger).to have_received(:warn).with start_with('DATADOG DIAGNOSTIC') do |msg| + error_line = msg.partition('-')[2].strip + error = error_line.partition(':')[2].strip + + expect(error_line).to start_with('Agent Error') + expect(error).to include('ZeroDivisionError') + expect(error).to include('msg') + end + end + end + + context 'under a REPL' do + around do |example| + begin + original = $PROGRAM_NAME + $0 = 'irb' + example.run + ensure + $0 = original + end + end + + context 'with default settings' do + it { expect(logger).to_not have_received(:info) } + end + + context 'with explicit setting' do + before do + Datadog.configure { |c| c.diagnostics.startup_logs.enabled = true } + end + + it { expect(logger).to have_received(:info) } + end + end + + context 'with error collecting information' do + before do + allow(tracer_logger).to receive(:warn) + expect_any_instance_of(Datadog::Tracing::Diagnostics::EnvironmentCollector).to receive(:collect!).and_raise + end + + it 'rescues error and logs exception' do + expect(logger).to have_received(:warn).with start_with('Failed to collect environment information') + end + end + end + + describe Datadog::Tracing::Diagnostics::EnvironmentCollector do + describe '#collect!' do + subject(:collect!) { collector.collect!([response]) } + + let(:collector) { described_class.new } + let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } + + it 'with a default tracer' do + is_expected.to match( + agent_error: nil, + agent_url: start_with("http://#{agent_hostname}:#{agent_port}?timeout="), + analytics_enabled: false, + date: '2020-01-01T00:00:00+00:00', + dd_version: nil, + debug: false, + enabled: true, + env: nil, + health_metrics_enabled: false, + integrations_loaded: nil, + lang: 'ruby', + lang_version: match(/[23]\./), + os_name: (include('x86_64').or include('i686').or include('aarch64').or include('arm')), + partial_flushing_enabled: false, + priority_sampling_enabled: false, + runtime_metrics_enabled: false, + sample_rate: nil, + sampling_rules: nil, + service: be_a(String), + tags: nil, + version: DDTrace::VERSION::STRING, + vm: be_a(String), + profiling_enabled: false, + ) + end + + context 'with tracer disabled' do + before { Datadog.configure { |c| c.tracing.enabled = false } } + + after { Datadog.configure { |c| c.tracing.enabled = true } } + + it { is_expected.to include enabled: false } + end + + context 'with env configured' do + before { Datadog.configure { |c| c.env = 'env' } } + + it { is_expected.to include env: 'env' } + end + + context 'with tags configured' do + before { Datadog.configure { |c| c.tags = { 'k1' => 'v1', 'k2' => 'v2' } } } + + it { is_expected.to include tags: 'k1:v1,k2:v2' } + end + + context 'with service configured' do + before { Datadog.configure { |c| c.service = 'svc' } } + + it { is_expected.to include service: 'svc' } + end + + context 'with version configured' do + before { Datadog.configure { |c| c.version = '1.2' } } + + it { is_expected.to include dd_version: '1.2' } + end + + context 'with debug enabled' do + before do + Datadog.configure do |c| + c.diagnostics.debug = true + c.logger.instance = Datadog::Tracing::Logger.new(StringIO.new) + end + end + + it { is_expected.to include debug: true } + end + + context 'with analytics enabled' do + before { Datadog.configure { |c| c.tracing.analytics.enabled = true } } + + it { is_expected.to include analytics_enabled: true } + end + + context 'with runtime metrics enabled' do + before { Datadog.configure { |c| c.runtime_metrics.enabled = true } } + + after { Datadog.configuration.runtime_metrics.reset! } + + it { is_expected.to include runtime_metrics_enabled: true } + end + + context 'with partial flushing enabled' do + before { Datadog.configure { |c| c.tracing.partial_flush.enabled = true } } + + it { is_expected.to include partial_flushing_enabled: true } + end + + context 'with priority sampling enabled' do + before { Datadog.configure { |c| c.tracing.priority_sampling = true } } + + it { is_expected.to include priority_sampling_enabled: true } + end + + context 'with health metrics enabled' do + before { Datadog.configure { |c| c.diagnostics.health_metrics.enabled = true } } + + it { is_expected.to include health_metrics_enabled: true } + end + + context 'with agent connectivity issues' do + let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } + + it { is_expected.to include agent_error: include('ZeroDivisionError') } + it { is_expected.to include agent_error: include('msg') } + end + + context 'with IO transport' do + before do + Datadog.configure do |c| + c.tracing.writer = Datadog::Tracing::SyncWriter.new( + transport: Datadog::Transport::IO.default + ) + end + end + + after { Datadog.configure { |c| c.tracing.writer = nil } } + + it { is_expected.to include agent_url: nil } + end + + context 'with unix socket transport' do + before do + Datadog.configure do |c| + c.tracing.transport_options = ->(t) { t.adapter :unix, '/tmp/trace.sock' } + end + end + + after { Datadog.configure { |c| c.tracing.transport_options = {} } } + + it { is_expected.to include agent_url: include('unix') } + it { is_expected.to include agent_url: include('/tmp/trace.sock') } + end + + context 'with integrations loaded' do + before { Datadog.configure { |c| c.tracing.instrument :http, options } } + + let(:options) { {} } + + it { is_expected.to include integrations_loaded: start_with('http') } + + it do + # Because net/http is default gem, we use the Ruby version as the library version. + is_expected.to include integrations_loaded: end_with("@#{RUBY_VERSION}") + end + + context 'with integration-specific settings' do + let(:options) { { service_name: 'my-http' } } + + it { is_expected.to include integration_http_analytics_enabled: 'false' } + it { is_expected.to include integration_http_analytics_sample_rate: '1.0' } + it { is_expected.to include integration_http_service_name: 'my-http' } + it { is_expected.to include integration_http_distributed_tracing: 'true' } + it { is_expected.to include integration_http_split_by_domain: 'false' } + end + + context 'with a complex setting value' do + let(:options) { { service_name: Class.new } } + + it 'converts to a string' do + is_expected.to include integration_http_service_name: start_with('# Date: Thu, 20 Jul 2023 14:48:20 -0400 Subject: [PATCH 2/7] passing environment_logger_spec.rb. --- gemfiles/ruby_3.1.2_contrib.gemfile | 1 + gemfiles/ruby_3.1.2_contrib.gemfile.lock | 6 +- gemfiles/ruby_3.1.2_contrib_old.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_core_old.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_cucumber3.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_cucumber4.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_cucumber5.gemfile.lock | 5 +- .../ruby_3.1.2_opentelemetry.gemfile.lock | 6 +- .../ruby_3.1.2_rails61_mysql2.gemfile.lock | 5 +- .../ruby_3.1.2_rails61_postgres.gemfile.lock | 5 +- ..._3.1.2_rails61_postgres_redis.gemfile.lock | 5 +- ....1.2_rails61_postgres_sidekiq.gemfile.lock | 5 +- ...3.1.2_rails61_semantic_logger.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_redis_3.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_redis_4.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_redis_5.gemfile.lock | 5 +- .../ruby_3.1.2_resque2_redis3.gemfile.lock | 5 +- .../ruby_3.1.2_resque2_redis4.gemfile.lock | 5 +- gemfiles/ruby_3.1.2_sinatra.gemfile.lock | 5 +- lib/datadog/tracing/logger.rb | 44 ++++++++++ .../diagnostics/environment_logger_spec.rb | 2 + spec/datadog/tracing/logger_spec.rb | 88 +++++++++++++++++++ 22 files changed, 172 insertions(+), 55 deletions(-) create mode 100644 lib/datadog/tracing/logger.rb create mode 100644 spec/datadog/tracing/logger_spec.rb diff --git a/gemfiles/ruby_3.1.2_contrib.gemfile b/gemfiles/ruby_3.1.2_contrib.gemfile index ee85eb9a73e..a9af819e089 100644 --- a/gemfiles/ruby_3.1.2_contrib.gemfile +++ b/gemfiles/ruby_3.1.2_contrib.gemfile @@ -58,6 +58,7 @@ gem "http" gem "httpclient" gem "lograge" gem "makara", ">= 0.6.0.pre" +gem "minitest", ">= 5.0.0" gem "mongo", ">= 2.8.0", "< 2.15.0" gem "mysql2", ">= 0.5.3", platform: :ruby gem "activerecord-jdbcmysql-adapter", platform: :jruby diff --git a/gemfiles/ruby_3.1.2_contrib.gemfile.lock b/gemfiles/ruby_3.1.2_contrib.gemfile.lock index 2329dac0240..cea38748f36 100644 --- a/gemfiles/ruby_3.1.2_contrib.gemfile.lock +++ b/gemfiles/ruby_3.1.2_contrib.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -1569,8 +1569,7 @@ GEM addressable (>= 2.4) jsonapi-renderer (0.2.2) king_konf (1.0.1) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) @@ -1842,6 +1841,7 @@ DEPENDENCIES lograge makara (>= 0.6.0.pre) memory_profiler (~> 0.9) + minitest (>= 5.0.0) mongo (>= 2.8.0, < 2.15.0) mysql2 (>= 0.5.3) net-smtp diff --git a/gemfiles/ruby_3.1.2_contrib_old.gemfile.lock b/gemfiles/ruby_3.1.2_contrib_old.gemfile.lock index a51bd280e10..06712f42547 100644 --- a/gemfiles/ruby_3.1.2_contrib_old.gemfile.lock +++ b/gemfiles/ruby_3.1.2_contrib_old.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -73,8 +73,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_core_old.gemfile.lock b/gemfiles/ruby_3.1.2_core_old.gemfile.lock index ecb8bfb1119..df5a7f3c289 100644 --- a/gemfiles/ruby_3.1.2_core_old.gemfile.lock +++ b/gemfiles/ruby_3.1.2_core_old.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -53,8 +53,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_cucumber3.gemfile.lock b/gemfiles/ruby_3.1.2_cucumber3.gemfile.lock index eceb13b797b..5938dd65807 100644 --- a/gemfiles/ruby_3.1.2_cucumber3.gemfile.lock +++ b/gemfiles/ruby_3.1.2_cucumber3.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -71,8 +71,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_cucumber4.gemfile.lock b/gemfiles/ruby_3.1.2_cucumber4.gemfile.lock index 26b1a3a82b4..5af0bfb2918 100644 --- a/gemfiles/ruby_3.1.2_cucumber4.gemfile.lock +++ b/gemfiles/ruby_3.1.2_cucumber4.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -91,8 +91,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_cucumber5.gemfile.lock b/gemfiles/ruby_3.1.2_cucumber5.gemfile.lock index edce7e9494c..9969e6b472c 100644 --- a/gemfiles/ruby_3.1.2_cucumber5.gemfile.lock +++ b/gemfiles/ruby_3.1.2_cucumber5.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -91,8 +91,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_opentelemetry.gemfile.lock b/gemfiles/ruby_3.1.2_opentelemetry.gemfile.lock index 36282e6777d..37b45796bee 100644 --- a/gemfiles/ruby_3.1.2_opentelemetry.gemfile.lock +++ b/gemfiles/ruby_3.1.2_opentelemetry.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -54,9 +54,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-darwin) diff --git a/gemfiles/ruby_3.1.2_rails61_mysql2.gemfile.lock b/gemfiles/ruby_3.1.2_rails61_mysql2.gemfile.lock index 6ed113b49a1..42150f24363 100644 --- a/gemfiles/ruby_3.1.2_rails61_mysql2.gemfile.lock +++ b/gemfiles/ruby_3.1.2_rails61_mysql2.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -119,8 +119,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_rails61_postgres.gemfile.lock b/gemfiles/ruby_3.1.2_rails61_postgres.gemfile.lock index 523fb450aff..84d73886ebe 100644 --- a/gemfiles/ruby_3.1.2_rails61_postgres.gemfile.lock +++ b/gemfiles/ruby_3.1.2_rails61_postgres.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -119,8 +119,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_rails61_postgres_redis.gemfile.lock b/gemfiles/ruby_3.1.2_rails61_postgres_redis.gemfile.lock index ac96b997836..33bd945b1c9 100644 --- a/gemfiles/ruby_3.1.2_rails61_postgres_redis.gemfile.lock +++ b/gemfiles/ruby_3.1.2_rails61_postgres_redis.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -119,8 +119,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_rails61_postgres_sidekiq.gemfile.lock b/gemfiles/ruby_3.1.2_rails61_postgres_sidekiq.gemfile.lock index 9c56293a4fd..c61175e1841 100644 --- a/gemfiles/ruby_3.1.2_rails61_postgres_sidekiq.gemfile.lock +++ b/gemfiles/ruby_3.1.2_rails61_postgres_sidekiq.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -120,8 +120,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_rails61_semantic_logger.gemfile.lock b/gemfiles/ruby_3.1.2_rails61_semantic_logger.gemfile.lock index d2ddd47207c..451b7b3ac94 100644 --- a/gemfiles/ruby_3.1.2_rails61_semantic_logger.gemfile.lock +++ b/gemfiles/ruby_3.1.2_rails61_semantic_logger.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -119,8 +119,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_redis_3.gemfile.lock b/gemfiles/ruby_3.1.2_redis_3.gemfile.lock index 70596e34dd5..06119bcb68a 100644 --- a/gemfiles/ruby_3.1.2_redis_3.gemfile.lock +++ b/gemfiles/ruby_3.1.2_redis_3.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -53,8 +53,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_redis_4.gemfile.lock b/gemfiles/ruby_3.1.2_redis_4.gemfile.lock index 2efede1c6be..f9ad4e3e4a1 100644 --- a/gemfiles/ruby_3.1.2_redis_4.gemfile.lock +++ b/gemfiles/ruby_3.1.2_redis_4.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -53,8 +53,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_redis_5.gemfile.lock b/gemfiles/ruby_3.1.2_redis_5.gemfile.lock index c3501ba66ea..0e084e7d346 100644 --- a/gemfiles/ruby_3.1.2_redis_5.gemfile.lock +++ b/gemfiles/ruby_3.1.2_redis_5.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -54,8 +54,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_resque2_redis3.gemfile.lock b/gemfiles/ruby_3.1.2_resque2_redis3.gemfile.lock index 5afaa664894..b97d75c783d 100644 --- a/gemfiles/ruby_3.1.2_resque2_redis3.gemfile.lock +++ b/gemfiles/ruby_3.1.2_resque2_redis3.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -53,8 +53,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_resque2_redis4.gemfile.lock b/gemfiles/ruby_3.1.2_resque2_redis4.gemfile.lock index 42e6305f9f7..979e8631ff8 100644 --- a/gemfiles/ruby_3.1.2_resque2_redis4.gemfile.lock +++ b/gemfiles/ruby_3.1.2_resque2_redis4.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -54,8 +54,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/gemfiles/ruby_3.1.2_sinatra.gemfile.lock b/gemfiles/ruby_3.1.2_sinatra.gemfile.lock index 1241393c6b0..16f72b30395 100644 --- a/gemfiles/ruby_3.1.2_sinatra.gemfile.lock +++ b/gemfiles/ruby_3.1.2_sinatra.gemfile.lock @@ -13,7 +13,7 @@ PATH specs: ddtrace (1.12.1) debase-ruby_core_source (= 3.2.1) - libdatadog (~> 2.0.0.1.0) + libdatadog (~> 3.0.0.1.0) libddwaf (~> 1.9.0.0.0) msgpack @@ -53,8 +53,7 @@ GEM json (2.6.3) json-schema (2.8.1) addressable (>= 2.4) - libdatadog (2.0.0.1.0-aarch64-linux) - libdatadog (2.0.0.1.0-x86_64-linux) + libdatadog (3.0.0.1.0-aarch64-linux) libddwaf (1.9.0.0.0-aarch64-linux) ffi (~> 1.0) libddwaf (1.9.0.0.0-x86_64-linux) diff --git a/lib/datadog/tracing/logger.rb b/lib/datadog/tracing/logger.rb new file mode 100644 index 00000000000..1b907327705 --- /dev/null +++ b/lib/datadog/tracing/logger.rb @@ -0,0 +1,44 @@ +require 'logger' + +module Datadog + module Tracing + # A custom logger with minor enhancements: + # - progname defaults to ddtrace to clearly identify Datadog dd-trace-rb related messages + # - adds last caller stack-trace info to know where the message comes from + # @public_api + class Logger < ::Logger + # TODO: Consider renaming this to 'datadog' + PREFIX = 'ddtrace'.freeze + + def initialize(*args, &block) + super + self.progname = PREFIX + self.level = ::Logger::INFO + end + + def add(severity, message = nil, progname = nil, &block) + where = '' + + # We are in debug mode, or this is an error, add stack trace to help debugging + if debug? || severity >= ::Logger::ERROR + c = caller + where = "(#{c[1]}) " if c.length > 1 + end + + if message.nil? + if block + super(severity, message, progname) do + "[#{self.progname}] #{where}#{yield}" + end + else + super(severity, message, "[#{self.progname}] #{where}#{progname}") + end + else + super(severity, "[#{self.progname}] #{where}#{message}") + end + end + + alias log add + end + end +end diff --git a/spec/datadog/tracing/diagnostics/environment_logger_spec.rb b/spec/datadog/tracing/diagnostics/environment_logger_spec.rb index 53966fb7658..3de885b41c9 100644 --- a/spec/datadog/tracing/diagnostics/environment_logger_spec.rb +++ b/spec/datadog/tracing/diagnostics/environment_logger_spec.rb @@ -2,6 +2,8 @@ require 'datadog/tracing/diagnostics/environment_logger' require 'ddtrace/transport/io' +require 'datadog/tracing/logger' +require 'datadog/profiling/profiler' RSpec.describe Datadog::Tracing::Diagnostics::EnvironmentLogger do subject(:env_logger) { described_class } diff --git a/spec/datadog/tracing/logger_spec.rb b/spec/datadog/tracing/logger_spec.rb new file mode 100644 index 00000000000..819748cbca1 --- /dev/null +++ b/spec/datadog/tracing/logger_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +require 'datadog/tracing/logger' + +RSpec.describe Datadog::Tracing::Logger do + describe '::new' do + subject(:logger) { described_class.new($stdout) } + + it { is_expected.to be_a_kind_of(::Logger) } + it { expect(logger.level).to be ::Logger::INFO } + it { expect(logger.progname).to eq(Datadog::Core::Logger::PREFIX) } + end + + describe 'output' do + subject(:lines) do + log_messages! # This is done to manipulate the stacktrace + buffer.string.lines + end + + let(:logger) { described_class.new(buffer) } + let(:buffer) { StringIO.new } + + def log_messages! + logger.debug('Debug message') + logger.info('Info message') + logger.warn('Warning message') + logger.error { 'Error message #1' } + logger.error('my-progname') { 'Error message #2' } + logger.add(Logger::ERROR, 'Error message #3') + end + + context 'with default settings' do + it { is_expected.to have(5).items } + + it 'produces log messages with expected format' do + expect(lines[0]).to match(/I,.*INFO -- ddtrace: \[ddtrace\] Info message/) + + expect(lines[1]).to match( + /W,.*WARN -- ddtrace: \[ddtrace\] Warning message/ + ) + + expect(lines[2]).to match( + /E,.*ERROR -- ddtrace: \[ddtrace\] \(.*logger_spec.rb.*\) Error message #1/ + ) + + expect(lines[3]).to match( + /E,.*ERROR -- my-progname: \[ddtrace\] \(.*logger_spec.rb.*\) Error message #2/ + ) + + expect(lines[4]).to match( + /E,.*ERROR -- ddtrace: \[ddtrace\] \(.*logger_spec.rb.*\) Error message #3/ + ) + end + end + + context 'with debug level set' do + before { logger.level = ::Logger::DEBUG } + + it { is_expected.to have(6).items } + + it 'produces log messages with expected format' do + expect(lines[0]).to match( + /D,.*DEBUG -- ddtrace: \[ddtrace\] \(.*logger_spec.rb.*\) Debug message/ + ) + + expect(lines[1]).to match( + /I,.*INFO -- ddtrace: \[ddtrace\] \(.*logger_spec.rb.*\) Info message/ + ) + + expect(lines[2]).to match( + /W,.*WARN -- ddtrace: \[ddtrace\] \(.*logger_spec.rb.*\) Warning message/ + ) + + expect(lines[3]).to match( + /E,.*ERROR -- ddtrace: \[ddtrace\] \(.*logger_spec.rb.*\) Error message #1/ + ) + + expect(lines[4]).to match( + /E,.*ERROR -- my-progname: \[ddtrace\] \(.*logger_spec.rb.*\) Error message #2/ + ) + + expect(lines[5]).to match( + /E,.*ERROR -- ddtrace: \[ddtrace\] \(.*logger_spec.rb.*\) Error message #3/ + ) + end + end + end +end From 19c5c95f29b8d153fd406e3ba6722da7f3cab14a Mon Sep 17 00:00:00 2001 From: Sarah Chen Date: Thu, 20 Jul 2023 15:11:06 -0400 Subject: [PATCH 3/7] changed Tracing::Logger to Core::Logger and commented out original environmentlogger files. --- .../core/diagnostics/environment_logger.rb | 572 ++++++++--------- lib/datadog/tracing/logger.rb | 44 -- .../diagnostics/environment_logger_spec.rb | 598 +++++++++--------- .../diagnostics/environment_logger_spec.rb | 6 +- spec/datadog/tracing/logger_spec.rb | 88 --- 5 files changed, 587 insertions(+), 721 deletions(-) delete mode 100644 lib/datadog/tracing/logger.rb delete mode 100644 spec/datadog/tracing/logger_spec.rb diff --git a/lib/datadog/core/diagnostics/environment_logger.rb b/lib/datadog/core/diagnostics/environment_logger.rb index 9f99c031806..308800cc0ee 100644 --- a/lib/datadog/core/diagnostics/environment_logger.rb +++ b/lib/datadog/core/diagnostics/environment_logger.rb @@ -1,286 +1,286 @@ -require 'date' -require 'json' -require 'rbconfig' - -module Datadog - module Core - module Diagnostics - # A holistic collection of the environment in which ddtrace is running. - # This logger should allow for easy reporting by users to Datadog support. - # - module EnvironmentLogger - class << self - # Outputs environment information to {Datadog.logger}. - # Executes only once for the lifetime of the program. - def log!(transport_responses) - return if (defined?(@executed) && @executed) || !log? - - @executed = true - - data = EnvironmentCollector.new.collect!(transport_responses) - data.reject! { |_, v| v.nil? } # Remove empty values from hash output - - log_environment!(data.to_json) - log_error!('Agent Error'.freeze, data[:agent_error]) if data[:agent_error] - rescue => e - Datadog.logger.warn("Failed to collect environment information: #{e} Location: #{Array(e.backtrace).first}") - end - - private - - def log_environment!(line) - Datadog.logger.info("DATADOG CONFIGURATION - #{line}") - end - - def log_error!(type, error) - Datadog.logger.warn("DATADOG DIAGNOSTIC - #{type}: #{error}") - end - - # Are we logging the environment data? - def log? - startup_logs_enabled = Datadog.configuration.diagnostics.startup_logs.enabled - if startup_logs_enabled.nil? - !repl? # Suppress logs if we running in a REPL - else - startup_logs_enabled - end - end - - REPL_PROGRAM_NAMES = %w[irb pry].freeze - - def repl? - REPL_PROGRAM_NAMES.include?($PROGRAM_NAME) - end - end - end - - # Collects environment information for diagnostic logging - class EnvironmentCollector - # @return [String] current time in ISO8601 format - def date - DateTime.now.iso8601 - end - - # Best portable guess of OS information. - # @return [String] platform string - def os_name - RbConfig::CONFIG['host'.freeze] - end - - # @return [String] ddtrace version - def version - DDTrace::VERSION::STRING - end - - # @return [String] "ruby" - def lang - Core::Environment::Ext::LANG - end - - # Supported Ruby language version. - # Will be distinct from VM version for non-MRI environments. - # @return [String] - def lang_version - Core::Environment::Ext::LANG_VERSION - end - - # @return [String] configured application environment - def env - Datadog.configuration.env - end - - # @return [Boolean, nil] - def enabled - Datadog.configuration.tracing.enabled - end - - # @return [String] configured application service name - def service - Datadog.configuration.service - end - - # @return [String] configured application version - def dd_version - Datadog.configuration.version - end - - # @return [String, nil] target agent URL for trace flushing - def agent_url - # Retrieve the effect agent URL, regardless of how it was configured - transport = Tracing.send(:tracer).writer.transport - - # return `nil` with IO transport - return unless transport.respond_to?(:client) - - adapter = transport.client.api.adapter - adapter.url - end - - # Error returned by Datadog agent during a tracer flush attempt - # @return [String] concatenated list of transport errors - def agent_error(transport_responses) - error_responses = transport_responses.reject(&:ok?) - - return nil if error_responses.empty? - - error_responses.map(&:inspect).join(','.freeze) - end - - # @return [Boolean, nil] debug mode enabled in configuration - def debug - !!Datadog.configuration.diagnostics.debug - end - - # @return [Boolean, nil] analytics enabled in configuration - def analytics_enabled - !!Datadog.configuration.tracing.analytics.enabled - end - - # @return [Numeric, nil] tracer sample rate configured - def sample_rate - sampler = Datadog.configuration.tracing.sampler - return nil unless sampler - - sampler.sample_rate(nil) rescue nil - end - - # DEV: We currently only support SimpleRule instances. - # DEV: These are the most commonly used rules. - # DEV: We should expand support for other rules in the future, - # DEV: although it is tricky to serialize arbitrary rules. - # - # @return [Hash, nil] sample rules configured - def sampling_rules - sampler = Datadog.configuration.tracing.sampler - return nil unless sampler.is_a?(Tracing::Sampling::PrioritySampler) && - sampler.priority_sampler.is_a?(Tracing::Sampling::RuleSampler) - - sampler.priority_sampler.rules.map do |rule| - next unless rule.is_a?(Tracing::Sampling::SimpleRule) - - { - name: rule.matcher.name, - service: rule.matcher.service, - sample_rate: rule.sampler.sample_rate(nil) - } - end.compact - end - - # @return [Hash, nil] concatenated list of global tracer tags configured - def tags - tags = Datadog.configuration.tags - return nil if tags.empty? - - hash_serializer(tags) - end - - # @return [Boolean, nil] runtime metrics enabled in configuration - def runtime_metrics_enabled - Datadog.configuration.runtime_metrics.enabled - end - - # Concatenated list of integrations activated, with their gem version. - # Example: "rails@6.0.3,rack@2.2.3" - # - # @return [String, nil] - def integrations_loaded - integrations = instrumented_integrations - return if integrations.empty? - - integrations.map { |name, integration| "#{name}@#{integration.class.version}" }.join(','.freeze) - end - - # Ruby VM name and version. - # Examples: "ruby-2.7.1", "jruby-9.2.11.1", "truffleruby-20.1.0" - # @return [String, nil] - def vm - # RUBY_ENGINE_VERSION returns the VM version, which - # will differ from RUBY_VERSION for non-mri VMs. - if defined?(RUBY_ENGINE_VERSION) - "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" - else - # Ruby < 2.3 doesn't support RUBY_ENGINE_VERSION - "#{RUBY_ENGINE}-#{RUBY_VERSION}" - end - end - - # @return [Boolean, nil] partial flushing enabled in configuration - def partial_flushing_enabled - !!Datadog.configuration.tracing.partial_flush.enabled - end - - # @return [Boolean, nil] priority sampling enabled in configuration - def priority_sampling_enabled - !!Datadog.configuration.tracing.priority_sampling - end - - # @return [Boolean, nil] health metrics enabled in configuration - def health_metrics_enabled - !!Datadog.configuration.diagnostics.health_metrics.enabled - end - - def profiling_enabled - !!Datadog.configuration.profiling.enabled - end - - # TODO: Populate when automatic log correlation is implemented - # def logs_correlation_enabled - # end - - # @return [Hash] environment information available at call time - def collect!(transport_responses) - { - date: date, - os_name: os_name, - version: version, - lang: lang, - lang_version: lang_version, - env: env, - enabled: enabled, - service: service, - dd_version: dd_version, - agent_url: agent_url, - agent_error: agent_error(transport_responses), - debug: debug, - analytics_enabled: analytics_enabled, - sample_rate: sample_rate, - sampling_rules: sampling_rules, - tags: tags, - runtime_metrics_enabled: runtime_metrics_enabled, - integrations_loaded: integrations_loaded, - vm: vm, - partial_flushing_enabled: partial_flushing_enabled, - priority_sampling_enabled: priority_sampling_enabled, - health_metrics_enabled: health_metrics_enabled, - profiling_enabled: profiling_enabled, - **instrumented_integrations_settings - } - end - - private - - def instrumented_integrations - Datadog.configuration.tracing.instrumented_integrations - end - - # Capture all active integration settings into "integrationName_settingName: value" entries. - def instrumented_integrations_settings - instrumented_integrations.flat_map do |name, integration| - integration.configuration.to_h.flat_map do |setting, value| - next [] if setting == :tracer # Skip internal Ruby objects - - # Convert value to a string to avoid custom #to_json - # handlers possibly causing errors. - [[:"integration_#{name}_#{setting}", value.to_s]] - end - end.to_h - end - - # Outputs "k1:v1,k2:v2,..." - def hash_serializer(h) - h.map { |k, v| "#{k}:#{v}" }.join(','.freeze) - end - end - end - end -end +# require 'date' +# require 'json' +# require 'rbconfig' + +# module Datadog +# module Core +# module Diagnostics +# # A holistic collection of the environment in which ddtrace is running. +# # This logger should allow for easy reporting by users to Datadog support. +# # +# module EnvironmentLogger +# class << self +# # Outputs environment information to {Datadog.logger}. +# # Executes only once for the lifetime of the program. +# def log!(transport_responses) +# return if (defined?(@executed) && @executed) || !log? + +# @executed = true + +# data = EnvironmentCollector.new.collect!(transport_responses) +# data.reject! { |_, v| v.nil? } # Remove empty values from hash output + +# log_environment!(data.to_json) +# log_error!('Agent Error'.freeze, data[:agent_error]) if data[:agent_error] +# rescue => e +# Datadog.logger.warn("Failed to collect environment information: #{e} Location: #{Array(e.backtrace).first}") +# end + +# private + +# def log_environment!(line) +# Datadog.logger.info("DATADOG CONFIGURATION - #{line}") +# end + +# def log_error!(type, error) +# Datadog.logger.warn("DATADOG DIAGNOSTIC - #{type}: #{error}") +# end + +# # Are we logging the environment data? +# def log? +# startup_logs_enabled = Datadog.configuration.diagnostics.startup_logs.enabled +# if startup_logs_enabled.nil? +# !repl? # Suppress logs if we running in a REPL +# else +# startup_logs_enabled +# end +# end + +# REPL_PROGRAM_NAMES = %w[irb pry].freeze + +# def repl? +# REPL_PROGRAM_NAMES.include?($PROGRAM_NAME) +# end +# end +# end + +# # Collects environment information for diagnostic logging +# class EnvironmentCollector +# # @return [String] current time in ISO8601 format +# def date +# DateTime.now.iso8601 +# end + +# # Best portable guess of OS information. +# # @return [String] platform string +# def os_name +# RbConfig::CONFIG['host'.freeze] +# end + +# # @return [String] ddtrace version +# def version +# DDTrace::VERSION::STRING +# end + +# # @return [String] "ruby" +# def lang +# Core::Environment::Ext::LANG +# end + +# # Supported Ruby language version. +# # Will be distinct from VM version for non-MRI environments. +# # @return [String] +# def lang_version +# Core::Environment::Ext::LANG_VERSION +# end + +# # @return [String] configured application environment +# def env +# Datadog.configuration.env +# end + +# # @return [Boolean, nil] +# def enabled +# Datadog.configuration.tracing.enabled +# end + +# # @return [String] configured application service name +# def service +# Datadog.configuration.service +# end + +# # @return [String] configured application version +# def dd_version +# Datadog.configuration.version +# end + +# # @return [String, nil] target agent URL for trace flushing +# def agent_url +# # Retrieve the effect agent URL, regardless of how it was configured +# transport = Tracing.send(:tracer).writer.transport + +# # return `nil` with IO transport +# return unless transport.respond_to?(:client) + +# adapter = transport.client.api.adapter +# adapter.url +# end + +# # Error returned by Datadog agent during a tracer flush attempt +# # @return [String] concatenated list of transport errors +# def agent_error(transport_responses) +# error_responses = transport_responses.reject(&:ok?) + +# return nil if error_responses.empty? + +# error_responses.map(&:inspect).join(','.freeze) +# end + +# # @return [Boolean, nil] debug mode enabled in configuration +# def debug +# !!Datadog.configuration.diagnostics.debug +# end + +# # @return [Boolean, nil] analytics enabled in configuration +# def analytics_enabled +# !!Datadog.configuration.tracing.analytics.enabled +# end + +# # @return [Numeric, nil] tracer sample rate configured +# def sample_rate +# sampler = Datadog.configuration.tracing.sampler +# return nil unless sampler + +# sampler.sample_rate(nil) rescue nil +# end + +# # DEV: We currently only support SimpleRule instances. +# # DEV: These are the most commonly used rules. +# # DEV: We should expand support for other rules in the future, +# # DEV: although it is tricky to serialize arbitrary rules. +# # +# # @return [Hash, nil] sample rules configured +# def sampling_rules +# sampler = Datadog.configuration.tracing.sampler +# return nil unless sampler.is_a?(Tracing::Sampling::PrioritySampler) && +# sampler.priority_sampler.is_a?(Tracing::Sampling::RuleSampler) + +# sampler.priority_sampler.rules.map do |rule| +# next unless rule.is_a?(Tracing::Sampling::SimpleRule) + +# { +# name: rule.matcher.name, +# service: rule.matcher.service, +# sample_rate: rule.sampler.sample_rate(nil) +# } +# end.compact +# end + +# # @return [Hash, nil] concatenated list of global tracer tags configured +# def tags +# tags = Datadog.configuration.tags +# return nil if tags.empty? + +# hash_serializer(tags) +# end + +# # @return [Boolean, nil] runtime metrics enabled in configuration +# def runtime_metrics_enabled +# Datadog.configuration.runtime_metrics.enabled +# end + +# # Concatenated list of integrations activated, with their gem version. +# # Example: "rails@6.0.3,rack@2.2.3" +# # +# # @return [String, nil] +# def integrations_loaded +# integrations = instrumented_integrations +# return if integrations.empty? + +# integrations.map { |name, integration| "#{name}@#{integration.class.version}" }.join(','.freeze) +# end + +# # Ruby VM name and version. +# # Examples: "ruby-2.7.1", "jruby-9.2.11.1", "truffleruby-20.1.0" +# # @return [String, nil] +# def vm +# # RUBY_ENGINE_VERSION returns the VM version, which +# # will differ from RUBY_VERSION for non-mri VMs. +# if defined?(RUBY_ENGINE_VERSION) +# "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" +# else +# # Ruby < 2.3 doesn't support RUBY_ENGINE_VERSION +# "#{RUBY_ENGINE}-#{RUBY_VERSION}" +# end +# end + +# # @return [Boolean, nil] partial flushing enabled in configuration +# def partial_flushing_enabled +# !!Datadog.configuration.tracing.partial_flush.enabled +# end + +# # @return [Boolean, nil] priority sampling enabled in configuration +# def priority_sampling_enabled +# !!Datadog.configuration.tracing.priority_sampling +# end + +# # @return [Boolean, nil] health metrics enabled in configuration +# def health_metrics_enabled +# !!Datadog.configuration.diagnostics.health_metrics.enabled +# end + +# def profiling_enabled +# !!Datadog.configuration.profiling.enabled +# end + +# # TODO: Populate when automatic log correlation is implemented +# # def logs_correlation_enabled +# # end + +# # @return [Hash] environment information available at call time +# def collect!(transport_responses) +# { +# date: date, +# os_name: os_name, +# version: version, +# lang: lang, +# lang_version: lang_version, +# env: env, +# enabled: enabled, +# service: service, +# dd_version: dd_version, +# agent_url: agent_url, +# agent_error: agent_error(transport_responses), +# debug: debug, +# analytics_enabled: analytics_enabled, +# sample_rate: sample_rate, +# sampling_rules: sampling_rules, +# tags: tags, +# runtime_metrics_enabled: runtime_metrics_enabled, +# integrations_loaded: integrations_loaded, +# vm: vm, +# partial_flushing_enabled: partial_flushing_enabled, +# priority_sampling_enabled: priority_sampling_enabled, +# health_metrics_enabled: health_metrics_enabled, +# profiling_enabled: profiling_enabled, +# **instrumented_integrations_settings +# } +# end + +# private + +# def instrumented_integrations +# Datadog.configuration.tracing.instrumented_integrations +# end + +# # Capture all active integration settings into "integrationName_settingName: value" entries. +# def instrumented_integrations_settings +# instrumented_integrations.flat_map do |name, integration| +# integration.configuration.to_h.flat_map do |setting, value| +# next [] if setting == :tracer # Skip internal Ruby objects + +# # Convert value to a string to avoid custom #to_json +# # handlers possibly causing errors. +# [[:"integration_#{name}_#{setting}", value.to_s]] +# end +# end.to_h +# end + +# # Outputs "k1:v1,k2:v2,..." +# def hash_serializer(h) +# h.map { |k, v| "#{k}:#{v}" }.join(','.freeze) +# end +# end +# end +# end +# end diff --git a/lib/datadog/tracing/logger.rb b/lib/datadog/tracing/logger.rb deleted file mode 100644 index 1b907327705..00000000000 --- a/lib/datadog/tracing/logger.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'logger' - -module Datadog - module Tracing - # A custom logger with minor enhancements: - # - progname defaults to ddtrace to clearly identify Datadog dd-trace-rb related messages - # - adds last caller stack-trace info to know where the message comes from - # @public_api - class Logger < ::Logger - # TODO: Consider renaming this to 'datadog' - PREFIX = 'ddtrace'.freeze - - def initialize(*args, &block) - super - self.progname = PREFIX - self.level = ::Logger::INFO - end - - def add(severity, message = nil, progname = nil, &block) - where = '' - - # We are in debug mode, or this is an error, add stack trace to help debugging - if debug? || severity >= ::Logger::ERROR - c = caller - where = "(#{c[1]}) " if c.length > 1 - end - - if message.nil? - if block - super(severity, message, progname) do - "[#{self.progname}] #{where}#{yield}" - end - else - super(severity, message, "[#{self.progname}] #{where}#{progname}") - end - else - super(severity, "[#{self.progname}] #{where}#{message}") - end - end - - alias log add - end - end -end diff --git a/spec/datadog/core/diagnostics/environment_logger_spec.rb b/spec/datadog/core/diagnostics/environment_logger_spec.rb index eb2eefa3982..bb1652b6339 100644 --- a/spec/datadog/core/diagnostics/environment_logger_spec.rb +++ b/spec/datadog/core/diagnostics/environment_logger_spec.rb @@ -1,331 +1,331 @@ -require 'spec_helper' - -require 'datadog/core/diagnostics/environment_logger' -require 'ddtrace/transport/io' - -RSpec.describe Datadog::Core::Diagnostics::EnvironmentLogger do - subject(:env_logger) { described_class } - - # Reading DD_AGENT_HOST allows this to work in CI - let(:agent_hostname) { ENV['DD_AGENT_HOST'] || '127.0.0.1' } - let(:agent_port) { ENV['DD_TRACE_AGENT_PORT'] || 8126 } - - before do - allow(DateTime).to receive(:now).and_return(DateTime.new(2020)) - - # Resets "only-once" execution pattern of `log!` - env_logger.instance_variable_set(:@executed, nil) - - Datadog.configuration.reset! - end - - describe '#log!' do - subject(:log!) { env_logger.log!([response]) } - - let(:logger) do - log! - tracer_logger - end - - let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } - let(:tracer_logger) { instance_double(Datadog::Core::Logger) } - - before do - allow(Datadog).to receive(:logger).and_return(tracer_logger) - allow(tracer_logger).to receive(:debug?).and_return true - allow(tracer_logger).to receive(:debug) - allow(tracer_logger).to receive(:info) - allow(tracer_logger).to receive(:warn) - allow(tracer_logger).to receive(:error) - end - - it 'with a default tracer settings' do - expect(logger).to have_received(:info).with start_with('DATADOG CONFIGURATION') do |msg| - json = JSON.parse(msg.partition('-')[2].strip) - expect(json).to match( - 'agent_url' => start_with("http://#{agent_hostname}:#{agent_port}?timeout="), - 'analytics_enabled' => false, - 'date' => '2020-01-01T00:00:00+00:00', - 'debug' => false, - 'enabled' => true, - 'health_metrics_enabled' => false, - 'lang' => 'ruby', - 'lang_version' => match(/[23]\./), - 'os_name' => (include('x86_64').or include('i686').or include('aarch64').or include('arm')), - 'partial_flushing_enabled' => false, - 'priority_sampling_enabled' => false, - 'runtime_metrics_enabled' => false, - 'version' => DDTrace::VERSION::STRING, - 'vm' => be_a(String), - 'service' => be_a(String), - 'profiling_enabled' => false, - ) - end - end - - context 'with multiple invocations' do - it 'executes only once' do - env_logger.log!([response]) - env_logger.log!([response]) - - expect(logger).to have_received(:info).once - end - end - - context 'with agent error' do - before { allow(tracer_logger).to receive(:warn) } - - let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } - - it do - expect(logger).to have_received(:warn).with start_with('DATADOG DIAGNOSTIC') do |msg| - error_line = msg.partition('-')[2].strip - error = error_line.partition(':')[2].strip - - expect(error_line).to start_with('Agent Error') - expect(error).to include('ZeroDivisionError') - expect(error).to include('msg') - end - end - end - - context 'under a REPL' do - around do |example| - begin - original = $PROGRAM_NAME - $0 = 'irb' - example.run - ensure - $0 = original - end - end - - context 'with default settings' do - it { expect(logger).to_not have_received(:info) } - end - - context 'with explicit setting' do - before do - Datadog.configure { |c| c.diagnostics.startup_logs.enabled = true } - end - - it { expect(logger).to have_received(:info) } - end - end - - context 'with error collecting information' do - before do - allow(tracer_logger).to receive(:warn) - expect_any_instance_of(Datadog::Core::Diagnostics::EnvironmentCollector).to receive(:collect!).and_raise - end - - it 'rescues error and logs exception' do - expect(logger).to have_received(:warn).with start_with('Failed to collect environment information') - end - end - end - - describe Datadog::Core::Diagnostics::EnvironmentCollector do - describe '#collect!' do - subject(:collect!) { collector.collect!([response]) } - - let(:collector) { described_class.new } - let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } - - it 'with a default tracer' do - is_expected.to match( - agent_error: nil, - agent_url: start_with("http://#{agent_hostname}:#{agent_port}?timeout="), - analytics_enabled: false, - date: '2020-01-01T00:00:00+00:00', - dd_version: nil, - debug: false, - enabled: true, - env: nil, - health_metrics_enabled: false, - integrations_loaded: nil, - lang: 'ruby', - lang_version: match(/[23]\./), - os_name: (include('x86_64').or include('i686').or include('aarch64').or include('arm')), - partial_flushing_enabled: false, - priority_sampling_enabled: false, - runtime_metrics_enabled: false, - sample_rate: nil, - sampling_rules: nil, - service: be_a(String), - tags: nil, - version: DDTrace::VERSION::STRING, - vm: be_a(String), - profiling_enabled: false, - ) - end - - context 'with tracer disabled' do - before { Datadog.configure { |c| c.tracing.enabled = false } } - - after { Datadog.configure { |c| c.tracing.enabled = true } } - - it { is_expected.to include enabled: false } - end - - context 'with env configured' do - before { Datadog.configure { |c| c.env = 'env' } } - - it { is_expected.to include env: 'env' } - end - - context 'with tags configured' do - before { Datadog.configure { |c| c.tags = { 'k1' => 'v1', 'k2' => 'v2' } } } - - it { is_expected.to include tags: 'k1:v1,k2:v2' } - end - - context 'with service configured' do - before { Datadog.configure { |c| c.service = 'svc' } } - - it { is_expected.to include service: 'svc' } - end - - context 'with version configured' do - before { Datadog.configure { |c| c.version = '1.2' } } - - it { is_expected.to include dd_version: '1.2' } - end - - context 'with debug enabled' do - before do - Datadog.configure do |c| - c.diagnostics.debug = true - c.logger.instance = Datadog::Core::Logger.new(StringIO.new) - end - end - - it { is_expected.to include debug: true } - end - - context 'with analytics enabled' do - before { Datadog.configure { |c| c.tracing.analytics.enabled = true } } - - it { is_expected.to include analytics_enabled: true } - end +# require 'spec_helper' + +# require 'datadog/core/diagnostics/environment_logger' +# require 'ddtrace/transport/io' + +# RSpec.describe Datadog::Core::Diagnostics::EnvironmentLogger do +# subject(:env_logger) { described_class } + +# # Reading DD_AGENT_HOST allows this to work in CI +# let(:agent_hostname) { ENV['DD_AGENT_HOST'] || '127.0.0.1' } +# let(:agent_port) { ENV['DD_TRACE_AGENT_PORT'] || 8126 } + +# before do +# allow(DateTime).to receive(:now).and_return(DateTime.new(2020)) + +# # Resets "only-once" execution pattern of `log!` +# env_logger.instance_variable_set(:@executed, nil) + +# Datadog.configuration.reset! +# end + +# describe '#log!' do +# subject(:log!) { env_logger.log!([response]) } + +# let(:logger) do +# log! +# tracer_logger +# end + +# let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } +# let(:tracer_logger) { instance_double(Datadog::Core::Logger) } + +# before do +# allow(Datadog).to receive(:logger).and_return(tracer_logger) +# allow(tracer_logger).to receive(:debug?).and_return true +# allow(tracer_logger).to receive(:debug) +# allow(tracer_logger).to receive(:info) +# allow(tracer_logger).to receive(:warn) +# allow(tracer_logger).to receive(:error) +# end + +# it 'with a default tracer settings' do +# expect(logger).to have_received(:info).with start_with('DATADOG CONFIGURATION') do |msg| +# json = JSON.parse(msg.partition('-')[2].strip) +# expect(json).to match( +# 'agent_url' => start_with("http://#{agent_hostname}:#{agent_port}?timeout="), +# 'analytics_enabled' => false, +# 'date' => '2020-01-01T00:00:00+00:00', +# 'debug' => false, +# 'enabled' => true, +# 'health_metrics_enabled' => false, +# 'lang' => 'ruby', +# 'lang_version' => match(/[23]\./), +# 'os_name' => (include('x86_64').or include('i686').or include('aarch64').or include('arm')), +# 'partial_flushing_enabled' => false, +# 'priority_sampling_enabled' => false, +# 'runtime_metrics_enabled' => false, +# 'version' => DDTrace::VERSION::STRING, +# 'vm' => be_a(String), +# 'service' => be_a(String), +# 'profiling_enabled' => false, +# ) +# end +# end + +# context 'with multiple invocations' do +# it 'executes only once' do +# env_logger.log!([response]) +# env_logger.log!([response]) + +# expect(logger).to have_received(:info).once +# end +# end + +# context 'with agent error' do +# before { allow(tracer_logger).to receive(:warn) } + +# let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } + +# it do +# expect(logger).to have_received(:warn).with start_with('DATADOG DIAGNOSTIC') do |msg| +# error_line = msg.partition('-')[2].strip +# error = error_line.partition(':')[2].strip + +# expect(error_line).to start_with('Agent Error') +# expect(error).to include('ZeroDivisionError') +# expect(error).to include('msg') +# end +# end +# end + +# context 'under a REPL' do +# around do |example| +# begin +# original = $PROGRAM_NAME +# $0 = 'irb' +# example.run +# ensure +# $0 = original +# end +# end + +# context 'with default settings' do +# it { expect(logger).to_not have_received(:info) } +# end + +# context 'with explicit setting' do +# before do +# Datadog.configure { |c| c.diagnostics.startup_logs.enabled = true } +# end + +# it { expect(logger).to have_received(:info) } +# end +# end + +# context 'with error collecting information' do +# before do +# allow(tracer_logger).to receive(:warn) +# expect_any_instance_of(Datadog::Core::Diagnostics::EnvironmentCollector).to receive(:collect!).and_raise +# end + +# it 'rescues error and logs exception' do +# expect(logger).to have_received(:warn).with start_with('Failed to collect environment information') +# end +# end +# end + +# describe Datadog::Core::Diagnostics::EnvironmentCollector do +# describe '#collect!' do +# subject(:collect!) { collector.collect!([response]) } + +# let(:collector) { described_class.new } +# let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } + +# it 'with a default tracer' do +# is_expected.to match( +# agent_error: nil, +# agent_url: start_with("http://#{agent_hostname}:#{agent_port}?timeout="), +# analytics_enabled: false, +# date: '2020-01-01T00:00:00+00:00', +# dd_version: nil, +# debug: false, +# enabled: true, +# env: nil, +# health_metrics_enabled: false, +# integrations_loaded: nil, +# lang: 'ruby', +# lang_version: match(/[23]\./), +# os_name: (include('x86_64').or include('i686').or include('aarch64').or include('arm')), +# partial_flushing_enabled: false, +# priority_sampling_enabled: false, +# runtime_metrics_enabled: false, +# sample_rate: nil, +# sampling_rules: nil, +# service: be_a(String), +# tags: nil, +# version: DDTrace::VERSION::STRING, +# vm: be_a(String), +# profiling_enabled: false, +# ) +# end + +# context 'with tracer disabled' do +# before { Datadog.configure { |c| c.tracing.enabled = false } } + +# after { Datadog.configure { |c| c.tracing.enabled = true } } + +# it { is_expected.to include enabled: false } +# end + +# context 'with env configured' do +# before { Datadog.configure { |c| c.env = 'env' } } + +# it { is_expected.to include env: 'env' } +# end + +# context 'with tags configured' do +# before { Datadog.configure { |c| c.tags = { 'k1' => 'v1', 'k2' => 'v2' } } } + +# it { is_expected.to include tags: 'k1:v1,k2:v2' } +# end + +# context 'with service configured' do +# before { Datadog.configure { |c| c.service = 'svc' } } + +# it { is_expected.to include service: 'svc' } +# end + +# context 'with version configured' do +# before { Datadog.configure { |c| c.version = '1.2' } } + +# it { is_expected.to include dd_version: '1.2' } +# end + +# context 'with debug enabled' do +# before do +# Datadog.configure do |c| +# c.diagnostics.debug = true +# c.logger.instance = Datadog::Core::Logger.new(StringIO.new) +# end +# end + +# it { is_expected.to include debug: true } +# end + +# context 'with analytics enabled' do +# before { Datadog.configure { |c| c.tracing.analytics.enabled = true } } + +# it { is_expected.to include analytics_enabled: true } +# end - context 'with runtime metrics enabled' do - before { Datadog.configure { |c| c.runtime_metrics.enabled = true } } +# context 'with runtime metrics enabled' do +# before { Datadog.configure { |c| c.runtime_metrics.enabled = true } } - after { Datadog.configuration.runtime_metrics.reset! } - - it { is_expected.to include runtime_metrics_enabled: true } - end +# after { Datadog.configuration.runtime_metrics.reset! } + +# it { is_expected.to include runtime_metrics_enabled: true } +# end - context 'with partial flushing enabled' do - before { Datadog.configure { |c| c.tracing.partial_flush.enabled = true } } +# context 'with partial flushing enabled' do +# before { Datadog.configure { |c| c.tracing.partial_flush.enabled = true } } - it { is_expected.to include partial_flushing_enabled: true } - end +# it { is_expected.to include partial_flushing_enabled: true } +# end - context 'with priority sampling enabled' do - before { Datadog.configure { |c| c.tracing.priority_sampling = true } } +# context 'with priority sampling enabled' do +# before { Datadog.configure { |c| c.tracing.priority_sampling = true } } - it { is_expected.to include priority_sampling_enabled: true } - end +# it { is_expected.to include priority_sampling_enabled: true } +# end - context 'with health metrics enabled' do - before { Datadog.configure { |c| c.diagnostics.health_metrics.enabled = true } } +# context 'with health metrics enabled' do +# before { Datadog.configure { |c| c.diagnostics.health_metrics.enabled = true } } - it { is_expected.to include health_metrics_enabled: true } - end +# it { is_expected.to include health_metrics_enabled: true } +# end - context 'with agent connectivity issues' do - let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } +# context 'with agent connectivity issues' do +# let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } - it { is_expected.to include agent_error: include('ZeroDivisionError') } - it { is_expected.to include agent_error: include('msg') } - end +# it { is_expected.to include agent_error: include('ZeroDivisionError') } +# it { is_expected.to include agent_error: include('msg') } +# end - context 'with IO transport' do - before do - Datadog.configure do |c| - c.tracing.writer = Datadog::Tracing::SyncWriter.new( - transport: Datadog::Transport::IO.default - ) - end - end +# context 'with IO transport' do +# before do +# Datadog.configure do |c| +# c.tracing.writer = Datadog::Tracing::SyncWriter.new( +# transport: Datadog::Transport::IO.default +# ) +# end +# end - after { Datadog.configure { |c| c.tracing.writer = nil } } +# after { Datadog.configure { |c| c.tracing.writer = nil } } - it { is_expected.to include agent_url: nil } - end +# it { is_expected.to include agent_url: nil } +# end - context 'with unix socket transport' do - before do - Datadog.configure do |c| - c.tracing.transport_options = ->(t) { t.adapter :unix, '/tmp/trace.sock' } - end - end +# context 'with unix socket transport' do +# before do +# Datadog.configure do |c| +# c.tracing.transport_options = ->(t) { t.adapter :unix, '/tmp/trace.sock' } +# end +# end - after { Datadog.configure { |c| c.tracing.transport_options = {} } } +# after { Datadog.configure { |c| c.tracing.transport_options = {} } } - it { is_expected.to include agent_url: include('unix') } - it { is_expected.to include agent_url: include('/tmp/trace.sock') } - end +# it { is_expected.to include agent_url: include('unix') } +# it { is_expected.to include agent_url: include('/tmp/trace.sock') } +# end - context 'with integrations loaded' do - before { Datadog.configure { |c| c.tracing.instrument :http, options } } +# context 'with integrations loaded' do +# before { Datadog.configure { |c| c.tracing.instrument :http, options } } - let(:options) { {} } +# let(:options) { {} } - it { is_expected.to include integrations_loaded: start_with('http') } +# it { is_expected.to include integrations_loaded: start_with('http') } - it do - # Because net/http is default gem, we use the Ruby version as the library version. - is_expected.to include integrations_loaded: end_with("@#{RUBY_VERSION}") - end +# it do +# # Because net/http is default gem, we use the Ruby version as the library version. +# is_expected.to include integrations_loaded: end_with("@#{RUBY_VERSION}") +# end - context 'with integration-specific settings' do - let(:options) { { service_name: 'my-http' } } +# context 'with integration-specific settings' do +# let(:options) { { service_name: 'my-http' } } - it { is_expected.to include integration_http_analytics_enabled: 'false' } - it { is_expected.to include integration_http_analytics_sample_rate: '1.0' } - it { is_expected.to include integration_http_service_name: 'my-http' } - it { is_expected.to include integration_http_distributed_tracing: 'true' } - it { is_expected.to include integration_http_split_by_domain: 'false' } - end +# it { is_expected.to include integration_http_analytics_enabled: 'false' } +# it { is_expected.to include integration_http_analytics_sample_rate: '1.0' } +# it { is_expected.to include integration_http_service_name: 'my-http' } +# it { is_expected.to include integration_http_distributed_tracing: 'true' } +# it { is_expected.to include integration_http_split_by_domain: 'false' } +# end - context 'with a complex setting value' do - let(:options) { { service_name: Class.new } } +# context 'with a complex setting value' do +# let(:options) { { service_name: Class.new } } - it 'converts to a string' do - is_expected.to include integration_http_service_name: start_with('# Date: Thu, 20 Jul 2023 15:35:22 -0400 Subject: [PATCH 4/7] removed original environmentlogger files and updated .rubocop_todo.yml and Steepfile. --- .rubocop_todo.yml | 2 +- Steepfile | 2 +- lib/datadog/core/configuration/components.rb | 2 +- .../core/diagnostics/environment_logger.rb | 286 --------------- .../core/configuration/components_spec.rb | 2 +- .../diagnostics/environment_logger_spec.rb | 331 ------------------ spec/datadog/tracing/writer_spec.rb | 2 +- 7 files changed, 5 insertions(+), 622 deletions(-) delete mode 100644 lib/datadog/core/diagnostics/environment_logger.rb delete mode 100644 spec/datadog/core/diagnostics/environment_logger_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 90064a42cb0..f223e2cdd51 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -178,7 +178,6 @@ Style/FrozenStringLiteralComment: - 'lib/datadog/core/configuration/components.rb' - 'lib/datadog/core/configuration/options.rb' - 'lib/datadog/core/configuration/settings.rb' - - 'lib/datadog/core/diagnostics/environment_logger.rb' - 'lib/datadog/core/encoding.rb' - 'lib/datadog/core/environment/cgroup.rb' - 'lib/datadog/core/environment/container.rb' @@ -373,6 +372,7 @@ Style/FrozenStringLiteralComment: - 'lib/datadog/tracing/contrib/utils/quantization/hash.rb' - 'lib/datadog/tracing/contrib/utils/quantization/http.rb' - 'lib/datadog/tracing/correlation.rb' + - 'lib/datadog/tracing/diagnostics/environment_logger.rb' - 'lib/datadog/tracing/event.rb' - 'lib/datadog/tracing/metadata/tagging.rb' - 'lib/datadog/tracing/pipeline.rb' diff --git a/Steepfile b/Steepfile index e05c2283c5b..f2c299a2dd7 100644 --- a/Steepfile +++ b/Steepfile @@ -72,7 +72,6 @@ target :ddtrace do ignore 'lib/datadog/core/configuration/option_definition_set.rb' ignore 'lib/datadog/core/configuration/options.rb' ignore 'lib/datadog/core/configuration/settings.rb' - ignore 'lib/datadog/core/diagnostics/environment_logger.rb' ignore 'lib/datadog/core/diagnostics/health.rb' ignore 'lib/datadog/core/encoding.rb' ignore 'lib/datadog/core/environment/container.rb' @@ -554,6 +553,7 @@ target :ddtrace do ignore 'lib/datadog/tracing/contrib/utils/quantization/hash.rb' ignore 'lib/datadog/tracing/contrib/utils/quantization/http.rb' ignore 'lib/datadog/tracing/correlation.rb' + ignore 'lib/datadog/tracing/diagnostics/environment_logger.rb' ignore 'lib/datadog/tracing/diagnostics/ext.rb' ignore 'lib/datadog/tracing/diagnostics/health.rb' ignore 'lib/datadog/tracing/distributed/b3_multi.rb' diff --git a/lib/datadog/core/configuration/components.rb b/lib/datadog/core/configuration/components.rb index 94bf476280c..3a7d43979ec 100644 --- a/lib/datadog/core/configuration/components.rb +++ b/lib/datadog/core/configuration/components.rb @@ -1,5 +1,5 @@ require_relative 'agent_settings_resolver' -require_relative '../diagnostics/environment_logger' +require_relative '../../tracing/diagnostics/environment_logger' require_relative '../diagnostics/health' require_relative '../logger' require_relative '../runtime/metrics' diff --git a/lib/datadog/core/diagnostics/environment_logger.rb b/lib/datadog/core/diagnostics/environment_logger.rb deleted file mode 100644 index 308800cc0ee..00000000000 --- a/lib/datadog/core/diagnostics/environment_logger.rb +++ /dev/null @@ -1,286 +0,0 @@ -# require 'date' -# require 'json' -# require 'rbconfig' - -# module Datadog -# module Core -# module Diagnostics -# # A holistic collection of the environment in which ddtrace is running. -# # This logger should allow for easy reporting by users to Datadog support. -# # -# module EnvironmentLogger -# class << self -# # Outputs environment information to {Datadog.logger}. -# # Executes only once for the lifetime of the program. -# def log!(transport_responses) -# return if (defined?(@executed) && @executed) || !log? - -# @executed = true - -# data = EnvironmentCollector.new.collect!(transport_responses) -# data.reject! { |_, v| v.nil? } # Remove empty values from hash output - -# log_environment!(data.to_json) -# log_error!('Agent Error'.freeze, data[:agent_error]) if data[:agent_error] -# rescue => e -# Datadog.logger.warn("Failed to collect environment information: #{e} Location: #{Array(e.backtrace).first}") -# end - -# private - -# def log_environment!(line) -# Datadog.logger.info("DATADOG CONFIGURATION - #{line}") -# end - -# def log_error!(type, error) -# Datadog.logger.warn("DATADOG DIAGNOSTIC - #{type}: #{error}") -# end - -# # Are we logging the environment data? -# def log? -# startup_logs_enabled = Datadog.configuration.diagnostics.startup_logs.enabled -# if startup_logs_enabled.nil? -# !repl? # Suppress logs if we running in a REPL -# else -# startup_logs_enabled -# end -# end - -# REPL_PROGRAM_NAMES = %w[irb pry].freeze - -# def repl? -# REPL_PROGRAM_NAMES.include?($PROGRAM_NAME) -# end -# end -# end - -# # Collects environment information for diagnostic logging -# class EnvironmentCollector -# # @return [String] current time in ISO8601 format -# def date -# DateTime.now.iso8601 -# end - -# # Best portable guess of OS information. -# # @return [String] platform string -# def os_name -# RbConfig::CONFIG['host'.freeze] -# end - -# # @return [String] ddtrace version -# def version -# DDTrace::VERSION::STRING -# end - -# # @return [String] "ruby" -# def lang -# Core::Environment::Ext::LANG -# end - -# # Supported Ruby language version. -# # Will be distinct from VM version for non-MRI environments. -# # @return [String] -# def lang_version -# Core::Environment::Ext::LANG_VERSION -# end - -# # @return [String] configured application environment -# def env -# Datadog.configuration.env -# end - -# # @return [Boolean, nil] -# def enabled -# Datadog.configuration.tracing.enabled -# end - -# # @return [String] configured application service name -# def service -# Datadog.configuration.service -# end - -# # @return [String] configured application version -# def dd_version -# Datadog.configuration.version -# end - -# # @return [String, nil] target agent URL for trace flushing -# def agent_url -# # Retrieve the effect agent URL, regardless of how it was configured -# transport = Tracing.send(:tracer).writer.transport - -# # return `nil` with IO transport -# return unless transport.respond_to?(:client) - -# adapter = transport.client.api.adapter -# adapter.url -# end - -# # Error returned by Datadog agent during a tracer flush attempt -# # @return [String] concatenated list of transport errors -# def agent_error(transport_responses) -# error_responses = transport_responses.reject(&:ok?) - -# return nil if error_responses.empty? - -# error_responses.map(&:inspect).join(','.freeze) -# end - -# # @return [Boolean, nil] debug mode enabled in configuration -# def debug -# !!Datadog.configuration.diagnostics.debug -# end - -# # @return [Boolean, nil] analytics enabled in configuration -# def analytics_enabled -# !!Datadog.configuration.tracing.analytics.enabled -# end - -# # @return [Numeric, nil] tracer sample rate configured -# def sample_rate -# sampler = Datadog.configuration.tracing.sampler -# return nil unless sampler - -# sampler.sample_rate(nil) rescue nil -# end - -# # DEV: We currently only support SimpleRule instances. -# # DEV: These are the most commonly used rules. -# # DEV: We should expand support for other rules in the future, -# # DEV: although it is tricky to serialize arbitrary rules. -# # -# # @return [Hash, nil] sample rules configured -# def sampling_rules -# sampler = Datadog.configuration.tracing.sampler -# return nil unless sampler.is_a?(Tracing::Sampling::PrioritySampler) && -# sampler.priority_sampler.is_a?(Tracing::Sampling::RuleSampler) - -# sampler.priority_sampler.rules.map do |rule| -# next unless rule.is_a?(Tracing::Sampling::SimpleRule) - -# { -# name: rule.matcher.name, -# service: rule.matcher.service, -# sample_rate: rule.sampler.sample_rate(nil) -# } -# end.compact -# end - -# # @return [Hash, nil] concatenated list of global tracer tags configured -# def tags -# tags = Datadog.configuration.tags -# return nil if tags.empty? - -# hash_serializer(tags) -# end - -# # @return [Boolean, nil] runtime metrics enabled in configuration -# def runtime_metrics_enabled -# Datadog.configuration.runtime_metrics.enabled -# end - -# # Concatenated list of integrations activated, with their gem version. -# # Example: "rails@6.0.3,rack@2.2.3" -# # -# # @return [String, nil] -# def integrations_loaded -# integrations = instrumented_integrations -# return if integrations.empty? - -# integrations.map { |name, integration| "#{name}@#{integration.class.version}" }.join(','.freeze) -# end - -# # Ruby VM name and version. -# # Examples: "ruby-2.7.1", "jruby-9.2.11.1", "truffleruby-20.1.0" -# # @return [String, nil] -# def vm -# # RUBY_ENGINE_VERSION returns the VM version, which -# # will differ from RUBY_VERSION for non-mri VMs. -# if defined?(RUBY_ENGINE_VERSION) -# "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" -# else -# # Ruby < 2.3 doesn't support RUBY_ENGINE_VERSION -# "#{RUBY_ENGINE}-#{RUBY_VERSION}" -# end -# end - -# # @return [Boolean, nil] partial flushing enabled in configuration -# def partial_flushing_enabled -# !!Datadog.configuration.tracing.partial_flush.enabled -# end - -# # @return [Boolean, nil] priority sampling enabled in configuration -# def priority_sampling_enabled -# !!Datadog.configuration.tracing.priority_sampling -# end - -# # @return [Boolean, nil] health metrics enabled in configuration -# def health_metrics_enabled -# !!Datadog.configuration.diagnostics.health_metrics.enabled -# end - -# def profiling_enabled -# !!Datadog.configuration.profiling.enabled -# end - -# # TODO: Populate when automatic log correlation is implemented -# # def logs_correlation_enabled -# # end - -# # @return [Hash] environment information available at call time -# def collect!(transport_responses) -# { -# date: date, -# os_name: os_name, -# version: version, -# lang: lang, -# lang_version: lang_version, -# env: env, -# enabled: enabled, -# service: service, -# dd_version: dd_version, -# agent_url: agent_url, -# agent_error: agent_error(transport_responses), -# debug: debug, -# analytics_enabled: analytics_enabled, -# sample_rate: sample_rate, -# sampling_rules: sampling_rules, -# tags: tags, -# runtime_metrics_enabled: runtime_metrics_enabled, -# integrations_loaded: integrations_loaded, -# vm: vm, -# partial_flushing_enabled: partial_flushing_enabled, -# priority_sampling_enabled: priority_sampling_enabled, -# health_metrics_enabled: health_metrics_enabled, -# profiling_enabled: profiling_enabled, -# **instrumented_integrations_settings -# } -# end - -# private - -# def instrumented_integrations -# Datadog.configuration.tracing.instrumented_integrations -# end - -# # Capture all active integration settings into "integrationName_settingName: value" entries. -# def instrumented_integrations_settings -# instrumented_integrations.flat_map do |name, integration| -# integration.configuration.to_h.flat_map do |setting, value| -# next [] if setting == :tracer # Skip internal Ruby objects - -# # Convert value to a string to avoid custom #to_json -# # handlers possibly causing errors. -# [[:"integration_#{name}_#{setting}", value.to_s]] -# end -# end.to_h -# end - -# # Outputs "k1:v1,k2:v2,..." -# def hash_serializer(h) -# h.map { |k, v| "#{k}:#{v}" }.join(','.freeze) -# end -# end -# end -# end -# end diff --git a/spec/datadog/core/configuration/components_spec.rb b/spec/datadog/core/configuration/components_spec.rb index 764a885267e..1c7a3ba1764 100644 --- a/spec/datadog/core/configuration/components_spec.rb +++ b/spec/datadog/core/configuration/components_spec.rb @@ -5,7 +5,6 @@ require 'datadog/core/configuration/agent_settings_resolver' require 'datadog/core/configuration/components' -require 'datadog/core/diagnostics/environment_logger' require 'datadog/core/diagnostics/health' require 'datadog/core/logger' require 'datadog/core/telemetry/client' @@ -21,6 +20,7 @@ require 'datadog/profiling/tasks/setup' require 'datadog/profiling/trace_identifiers/helper' require 'datadog/statsd' +require 'datadog/tracing/diagnostics/environment_logger' require 'datadog/tracing/flush' require 'datadog/tracing/sampling/all_sampler' require 'datadog/tracing/sampling/priority_sampler' diff --git a/spec/datadog/core/diagnostics/environment_logger_spec.rb b/spec/datadog/core/diagnostics/environment_logger_spec.rb deleted file mode 100644 index bb1652b6339..00000000000 --- a/spec/datadog/core/diagnostics/environment_logger_spec.rb +++ /dev/null @@ -1,331 +0,0 @@ -# require 'spec_helper' - -# require 'datadog/core/diagnostics/environment_logger' -# require 'ddtrace/transport/io' - -# RSpec.describe Datadog::Core::Diagnostics::EnvironmentLogger do -# subject(:env_logger) { described_class } - -# # Reading DD_AGENT_HOST allows this to work in CI -# let(:agent_hostname) { ENV['DD_AGENT_HOST'] || '127.0.0.1' } -# let(:agent_port) { ENV['DD_TRACE_AGENT_PORT'] || 8126 } - -# before do -# allow(DateTime).to receive(:now).and_return(DateTime.new(2020)) - -# # Resets "only-once" execution pattern of `log!` -# env_logger.instance_variable_set(:@executed, nil) - -# Datadog.configuration.reset! -# end - -# describe '#log!' do -# subject(:log!) { env_logger.log!([response]) } - -# let(:logger) do -# log! -# tracer_logger -# end - -# let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } -# let(:tracer_logger) { instance_double(Datadog::Core::Logger) } - -# before do -# allow(Datadog).to receive(:logger).and_return(tracer_logger) -# allow(tracer_logger).to receive(:debug?).and_return true -# allow(tracer_logger).to receive(:debug) -# allow(tracer_logger).to receive(:info) -# allow(tracer_logger).to receive(:warn) -# allow(tracer_logger).to receive(:error) -# end - -# it 'with a default tracer settings' do -# expect(logger).to have_received(:info).with start_with('DATADOG CONFIGURATION') do |msg| -# json = JSON.parse(msg.partition('-')[2].strip) -# expect(json).to match( -# 'agent_url' => start_with("http://#{agent_hostname}:#{agent_port}?timeout="), -# 'analytics_enabled' => false, -# 'date' => '2020-01-01T00:00:00+00:00', -# 'debug' => false, -# 'enabled' => true, -# 'health_metrics_enabled' => false, -# 'lang' => 'ruby', -# 'lang_version' => match(/[23]\./), -# 'os_name' => (include('x86_64').or include('i686').or include('aarch64').or include('arm')), -# 'partial_flushing_enabled' => false, -# 'priority_sampling_enabled' => false, -# 'runtime_metrics_enabled' => false, -# 'version' => DDTrace::VERSION::STRING, -# 'vm' => be_a(String), -# 'service' => be_a(String), -# 'profiling_enabled' => false, -# ) -# end -# end - -# context 'with multiple invocations' do -# it 'executes only once' do -# env_logger.log!([response]) -# env_logger.log!([response]) - -# expect(logger).to have_received(:info).once -# end -# end - -# context 'with agent error' do -# before { allow(tracer_logger).to receive(:warn) } - -# let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } - -# it do -# expect(logger).to have_received(:warn).with start_with('DATADOG DIAGNOSTIC') do |msg| -# error_line = msg.partition('-')[2].strip -# error = error_line.partition(':')[2].strip - -# expect(error_line).to start_with('Agent Error') -# expect(error).to include('ZeroDivisionError') -# expect(error).to include('msg') -# end -# end -# end - -# context 'under a REPL' do -# around do |example| -# begin -# original = $PROGRAM_NAME -# $0 = 'irb' -# example.run -# ensure -# $0 = original -# end -# end - -# context 'with default settings' do -# it { expect(logger).to_not have_received(:info) } -# end - -# context 'with explicit setting' do -# before do -# Datadog.configure { |c| c.diagnostics.startup_logs.enabled = true } -# end - -# it { expect(logger).to have_received(:info) } -# end -# end - -# context 'with error collecting information' do -# before do -# allow(tracer_logger).to receive(:warn) -# expect_any_instance_of(Datadog::Core::Diagnostics::EnvironmentCollector).to receive(:collect!).and_raise -# end - -# it 'rescues error and logs exception' do -# expect(logger).to have_received(:warn).with start_with('Failed to collect environment information') -# end -# end -# end - -# describe Datadog::Core::Diagnostics::EnvironmentCollector do -# describe '#collect!' do -# subject(:collect!) { collector.collect!([response]) } - -# let(:collector) { described_class.new } -# let(:response) { instance_double(Datadog::Transport::Response, ok?: true) } - -# it 'with a default tracer' do -# is_expected.to match( -# agent_error: nil, -# agent_url: start_with("http://#{agent_hostname}:#{agent_port}?timeout="), -# analytics_enabled: false, -# date: '2020-01-01T00:00:00+00:00', -# dd_version: nil, -# debug: false, -# enabled: true, -# env: nil, -# health_metrics_enabled: false, -# integrations_loaded: nil, -# lang: 'ruby', -# lang_version: match(/[23]\./), -# os_name: (include('x86_64').or include('i686').or include('aarch64').or include('arm')), -# partial_flushing_enabled: false, -# priority_sampling_enabled: false, -# runtime_metrics_enabled: false, -# sample_rate: nil, -# sampling_rules: nil, -# service: be_a(String), -# tags: nil, -# version: DDTrace::VERSION::STRING, -# vm: be_a(String), -# profiling_enabled: false, -# ) -# end - -# context 'with tracer disabled' do -# before { Datadog.configure { |c| c.tracing.enabled = false } } - -# after { Datadog.configure { |c| c.tracing.enabled = true } } - -# it { is_expected.to include enabled: false } -# end - -# context 'with env configured' do -# before { Datadog.configure { |c| c.env = 'env' } } - -# it { is_expected.to include env: 'env' } -# end - -# context 'with tags configured' do -# before { Datadog.configure { |c| c.tags = { 'k1' => 'v1', 'k2' => 'v2' } } } - -# it { is_expected.to include tags: 'k1:v1,k2:v2' } -# end - -# context 'with service configured' do -# before { Datadog.configure { |c| c.service = 'svc' } } - -# it { is_expected.to include service: 'svc' } -# end - -# context 'with version configured' do -# before { Datadog.configure { |c| c.version = '1.2' } } - -# it { is_expected.to include dd_version: '1.2' } -# end - -# context 'with debug enabled' do -# before do -# Datadog.configure do |c| -# c.diagnostics.debug = true -# c.logger.instance = Datadog::Core::Logger.new(StringIO.new) -# end -# end - -# it { is_expected.to include debug: true } -# end - -# context 'with analytics enabled' do -# before { Datadog.configure { |c| c.tracing.analytics.enabled = true } } - -# it { is_expected.to include analytics_enabled: true } -# end - -# context 'with runtime metrics enabled' do -# before { Datadog.configure { |c| c.runtime_metrics.enabled = true } } - -# after { Datadog.configuration.runtime_metrics.reset! } - -# it { is_expected.to include runtime_metrics_enabled: true } -# end - -# context 'with partial flushing enabled' do -# before { Datadog.configure { |c| c.tracing.partial_flush.enabled = true } } - -# it { is_expected.to include partial_flushing_enabled: true } -# end - -# context 'with priority sampling enabled' do -# before { Datadog.configure { |c| c.tracing.priority_sampling = true } } - -# it { is_expected.to include priority_sampling_enabled: true } -# end - -# context 'with health metrics enabled' do -# before { Datadog.configure { |c| c.diagnostics.health_metrics.enabled = true } } - -# it { is_expected.to include health_metrics_enabled: true } -# end - -# context 'with agent connectivity issues' do -# let(:response) { Datadog::Transport::InternalErrorResponse.new(ZeroDivisionError.new('msg')) } - -# it { is_expected.to include agent_error: include('ZeroDivisionError') } -# it { is_expected.to include agent_error: include('msg') } -# end - -# context 'with IO transport' do -# before do -# Datadog.configure do |c| -# c.tracing.writer = Datadog::Tracing::SyncWriter.new( -# transport: Datadog::Transport::IO.default -# ) -# end -# end - -# after { Datadog.configure { |c| c.tracing.writer = nil } } - -# it { is_expected.to include agent_url: nil } -# end - -# context 'with unix socket transport' do -# before do -# Datadog.configure do |c| -# c.tracing.transport_options = ->(t) { t.adapter :unix, '/tmp/trace.sock' } -# end -# end - -# after { Datadog.configure { |c| c.tracing.transport_options = {} } } - -# it { is_expected.to include agent_url: include('unix') } -# it { is_expected.to include agent_url: include('/tmp/trace.sock') } -# end - -# context 'with integrations loaded' do -# before { Datadog.configure { |c| c.tracing.instrument :http, options } } - -# let(:options) { {} } - -# it { is_expected.to include integrations_loaded: start_with('http') } - -# it do -# # Because net/http is default gem, we use the Ruby version as the library version. -# is_expected.to include integrations_loaded: end_with("@#{RUBY_VERSION}") -# end - -# context 'with integration-specific settings' do -# let(:options) { { service_name: 'my-http' } } - -# it { is_expected.to include integration_http_analytics_enabled: 'false' } -# it { is_expected.to include integration_http_analytics_sample_rate: '1.0' } -# it { is_expected.to include integration_http_service_name: 'my-http' } -# it { is_expected.to include integration_http_distributed_tracing: 'true' } -# it { is_expected.to include integration_http_split_by_domain: 'false' } -# end - -# context 'with a complex setting value' do -# let(:options) { { service_name: Class.new } } - -# it 'converts to a string' do -# is_expected.to include integration_http_service_name: start_with('# Date: Thu, 20 Jul 2023 16:31:59 -0400 Subject: [PATCH 5/7] updated sig directory. --- .../{core => tracing}/diagnostics/environment_logger.rbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename sig/datadog/{core => tracing}/diagnostics/environment_logger.rbs (99%) diff --git a/sig/datadog/core/diagnostics/environment_logger.rbs b/sig/datadog/tracing/diagnostics/environment_logger.rbs similarity index 99% rename from sig/datadog/core/diagnostics/environment_logger.rbs rename to sig/datadog/tracing/diagnostics/environment_logger.rbs index bd40e47427f..86eefe23f8b 100644 --- a/sig/datadog/core/diagnostics/environment_logger.rbs +++ b/sig/datadog/tracing/diagnostics/environment_logger.rbs @@ -1,5 +1,5 @@ module Datadog - module Core + module Tracing module Diagnostics module EnvironmentLogger def self.log!: (untyped transport_responses) -> untyped From 53ecc8e345f952904abe92adc1203f4525bb4a80 Mon Sep 17 00:00:00 2001 From: Sarah Chen Date: Fri, 21 Jul 2023 14:56:44 -0400 Subject: [PATCH 6/7] empty commit. From 6d0b2b7e7cc7d63dcc3947af8c3670e04fd8bafd Mon Sep 17 00:00:00 2001 From: Sarah Chen Date: Fri, 21 Jul 2023 15:55:16 -0400 Subject: [PATCH 7/7] adjusted LANG constant based on marco's comment. --- lib/datadog/tracing/diagnostics/environment_logger.rb | 4 ++-- lib/datadog/tracing/diagnostics/ext.rb | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/datadog/tracing/diagnostics/environment_logger.rb b/lib/datadog/tracing/diagnostics/environment_logger.rb index df9e9a8c10f..20fe1f5f694 100644 --- a/lib/datadog/tracing/diagnostics/environment_logger.rb +++ b/lib/datadog/tracing/diagnostics/environment_logger.rb @@ -74,14 +74,14 @@ def version # @return [String] "ruby" def lang - Diagnostics::Ext::LANG + Core::Environment::Ext::LANG end # Supported Ruby language version. # Will be distinct from VM version for non-MRI environments. # @return [String] def lang_version - Diagnostics::Ext::LANG_VERSION + Core::Environment::Ext::LANG_VERSION end # @return [String] configured application environment diff --git a/lib/datadog/tracing/diagnostics/ext.rb b/lib/datadog/tracing/diagnostics/ext.rb index 32fc66d5580..a0b3aa30062 100644 --- a/lib/datadog/tracing/diagnostics/ext.rb +++ b/lib/datadog/tracing/diagnostics/ext.rb @@ -5,8 +5,6 @@ module Tracing module Diagnostics # @public_api module Ext - LANG = 'ruby' - LANG_VERSION = RUBY_VERSION # Health module Health # Metrics