ddtrace 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -16
  3. data/CHANGELOG.md +31 -2
  4. data/LICENSE-3rdparty.csv +3 -2
  5. data/README.md +2 -2
  6. data/ddtrace.gemspec +12 -3
  7. data/docs/GettingStarted.md +19 -2
  8. data/docs/ProfilingDevelopment.md +8 -8
  9. data/docs/UpgradeGuide.md +3 -3
  10. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +118 -0
  11. data/ext/ddtrace_profiling_loader/extconf.rb +53 -0
  12. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +31 -5
  13. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +0 -8
  14. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +278 -0
  15. data/ext/ddtrace_profiling_native_extension/extconf.rb +70 -100
  16. data/ext/ddtrace_profiling_native_extension/libddprof_helpers.h +13 -0
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +186 -0
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +579 -7
  19. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +30 -0
  20. data/ext/ddtrace_profiling_native_extension/profiling.c +7 -0
  21. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +139 -0
  22. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +28 -0
  23. data/lib/datadog/appsec/autoload.rb +2 -2
  24. data/lib/datadog/appsec/configuration/settings.rb +19 -0
  25. data/lib/datadog/appsec/configuration.rb +8 -0
  26. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +76 -33
  27. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -0
  28. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -1
  29. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +64 -0
  30. data/lib/datadog/appsec/contrib/rack/request.rb +6 -0
  31. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +41 -0
  32. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +60 -5
  33. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +81 -0
  34. data/lib/datadog/appsec/contrib/rails/patcher.rb +34 -1
  35. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +68 -0
  36. data/lib/datadog/appsec/contrib/rails/request.rb +33 -0
  37. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +124 -0
  38. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +69 -2
  39. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +63 -0
  40. data/lib/datadog/appsec/event.rb +33 -18
  41. data/lib/datadog/appsec/extensions.rb +0 -3
  42. data/lib/datadog/appsec/processor.rb +45 -2
  43. data/lib/datadog/appsec/rate_limiter.rb +5 -0
  44. data/lib/datadog/appsec/reactive/operation.rb +0 -1
  45. data/lib/datadog/ci/ext/environment.rb +21 -7
  46. data/lib/datadog/core/configuration/agent_settings_resolver.rb +1 -1
  47. data/lib/datadog/core/configuration/components.rb +22 -4
  48. data/lib/datadog/core/configuration/settings.rb +3 -3
  49. data/lib/datadog/core/configuration.rb +7 -5
  50. data/lib/datadog/core/environment/cgroup.rb +3 -1
  51. data/lib/datadog/core/environment/container.rb +2 -1
  52. data/lib/datadog/core/environment/variable_helpers.rb +26 -2
  53. data/lib/datadog/core/logging/ext.rb +11 -0
  54. data/lib/datadog/core/metrics/client.rb +15 -5
  55. data/lib/datadog/core/runtime/metrics.rb +1 -1
  56. data/lib/datadog/core/workers/async.rb +3 -1
  57. data/lib/datadog/core/workers/runtime_metrics.rb +0 -3
  58. data/lib/datadog/core.rb +6 -0
  59. data/lib/datadog/kit/enable_core_dumps.rb +50 -0
  60. data/lib/datadog/kit/identity.rb +63 -0
  61. data/lib/datadog/kit.rb +11 -0
  62. data/lib/datadog/opentracer/tracer.rb +0 -2
  63. data/lib/datadog/profiling/collectors/old_stack.rb +298 -0
  64. data/lib/datadog/profiling/collectors/stack.rb +6 -287
  65. data/lib/datadog/profiling/encoding/profile.rb +0 -1
  66. data/lib/datadog/profiling/ext.rb +1 -1
  67. data/lib/datadog/profiling/flush.rb +1 -1
  68. data/lib/datadog/profiling/load_native_extension.rb +22 -0
  69. data/lib/datadog/profiling/recorder.rb +1 -1
  70. data/lib/datadog/profiling/scheduler.rb +1 -1
  71. data/lib/datadog/profiling/stack_recorder.rb +33 -0
  72. data/lib/datadog/profiling/tag_builder.rb +48 -0
  73. data/lib/datadog/profiling/tasks/exec.rb +2 -2
  74. data/lib/datadog/profiling/tasks/setup.rb +6 -4
  75. data/lib/datadog/profiling.rb +29 -27
  76. data/lib/datadog/tracing/buffer.rb +9 -3
  77. data/lib/datadog/tracing/contrib/action_view/patcher.rb +0 -1
  78. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  79. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  80. data/lib/datadog/tracing/contrib/active_record/vendor/connection_specification.rb +1 -1
  81. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +4 -2
  82. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +10 -3
  83. data/lib/datadog/tracing/contrib/dalli/patcher.rb +0 -1
  84. data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +0 -1
  85. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +9 -3
  86. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +38 -2
  87. data/lib/datadog/tracing/contrib/ethon/patcher.rb +0 -1
  88. data/lib/datadog/tracing/contrib/extensions.rb +0 -2
  89. data/lib/datadog/tracing/contrib/faraday/patcher.rb +0 -1
  90. data/lib/datadog/tracing/contrib/grape/patcher.rb +0 -1
  91. data/lib/datadog/tracing/contrib/graphql/patcher.rb +0 -1
  92. data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -1
  93. data/lib/datadog/tracing/contrib/kafka/patcher.rb +0 -1
  94. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -1
  95. data/lib/datadog/tracing/contrib/qless/patcher.rb +0 -1
  96. data/lib/datadog/tracing/contrib/que/patcher.rb +0 -1
  97. data/lib/datadog/tracing/contrib/racecar/patcher.rb +0 -1
  98. data/lib/datadog/tracing/contrib/rails/log_injection.rb +3 -16
  99. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
  100. data/lib/datadog/tracing/contrib/rake/patcher.rb +0 -1
  101. data/lib/datadog/tracing/contrib/redis/patcher.rb +0 -1
  102. data/lib/datadog/tracing/contrib/resque/patcher.rb +0 -1
  103. data/lib/datadog/tracing/contrib/rest_client/patcher.rb +0 -1
  104. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +2 -1
  105. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
  106. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +20 -1
  107. data/lib/datadog/tracing/contrib/sinatra/framework.rb +11 -0
  108. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +0 -1
  109. data/lib/datadog/tracing/contrib/sneakers/patcher.rb +0 -1
  110. data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +0 -1
  111. data/lib/datadog/tracing/event.rb +2 -1
  112. data/lib/datadog/tracing/sampling/priority_sampler.rb +4 -5
  113. data/lib/datadog/tracing/sampling/rule.rb +12 -6
  114. data/lib/datadog/tracing/sampling/rule_sampler.rb +3 -5
  115. data/lib/datadog/tracing/span_operation.rb +2 -3
  116. data/lib/datadog/tracing/trace_operation.rb +0 -1
  117. data/lib/ddtrace/transport/http/client.rb +2 -1
  118. data/lib/ddtrace/transport/http/response.rb +34 -4
  119. data/lib/ddtrace/transport/io/client.rb +3 -1
  120. data/lib/ddtrace/version.rb +1 -1
  121. data/lib/ddtrace.rb +1 -0
  122. metadata +43 -6
@@ -0,0 +1,33 @@
1
+ # typed: false
2
+
3
+ module Datadog
4
+ module Profiling
5
+ # Used to wrap a ddprof_ffi_Profile in a Ruby object and expose Ruby-level serialization APIs
6
+ # Methods prefixed with _native_ are implemented in `stack_recorder.c`
7
+ class StackRecorder
8
+ def serialize
9
+ status, result = self.class._native_serialize(self)
10
+
11
+ if status == :ok
12
+ start, finish, encoded_pprof = result
13
+
14
+ Datadog.logger.debug { "Encoded profile covering #{start.iso8601} to #{finish.iso8601}" }
15
+
16
+ [start, finish, encoded_pprof]
17
+ else
18
+ error_message = result
19
+
20
+ Datadog.logger.error("Failed to serialize profiling data: #{error_message}")
21
+
22
+ nil
23
+ end
24
+ end
25
+
26
+ # Used only for Ruby 2.2 and below which don't have the native `rb_time_timespec_new` API
27
+ # Called from native code
28
+ def self.ruby_time_from(timespec_seconds, timespec_nanoseconds)
29
+ Time.at(0).utc + timespec_seconds + (timespec_nanoseconds.to_r / 1_000_000_000)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,48 @@
1
+ # typed: true
2
+
3
+ module Datadog
4
+ module Profiling
5
+ # Builds a hash of default plus user tags to be included in a profile
6
+ module TagBuilder
7
+ include Datadog::Profiling::Ext::Transport::HTTP # Tag name constants
8
+
9
+ def self.call(
10
+ settings:,
11
+ # Unified service tagging
12
+ env: settings.env,
13
+ service: settings.service,
14
+ version: settings.version,
15
+ # Other metadata
16
+ host: Core::Environment::Socket.hostname,
17
+ language: Core::Environment::Identity.lang,
18
+ pid: Process.pid.to_s,
19
+ profiler_version: Core::Environment::Identity.tracer_version,
20
+ runtime_engine: Core::Environment::Identity.lang_engine,
21
+ runtime_id: Core::Environment::Identity.id,
22
+ runtime_platform: Core::Environment::Identity.lang_platform,
23
+ runtime_version: Core::Environment::Identity.lang_version,
24
+ # User-provided tags
25
+ user_tags: settings.tags
26
+ )
27
+ tags = {
28
+ # When changing or adding these, make sure they are kept in sync with
29
+ # https://docs.google.com/spreadsheets/d/1LOGMf4c4Avbtn36uZ2SWvhIGKRPLM1BoWkUP4JYj7hA/ (Datadog internal link)
30
+ FORM_FIELD_TAG_HOST => host,
31
+ FORM_FIELD_TAG_LANGUAGE => language,
32
+ FORM_FIELD_TAG_PID => pid,
33
+ FORM_FIELD_TAG_PROFILER_VERSION => profiler_version,
34
+ FORM_FIELD_TAG_RUNTIME => language, # This is known to be repeated from language, above
35
+ FORM_FIELD_TAG_RUNTIME_ENGINE => runtime_engine,
36
+ FORM_FIELD_TAG_RUNTIME_ID => runtime_id,
37
+ FORM_FIELD_TAG_RUNTIME_PLATFORM => runtime_platform,
38
+ FORM_FIELD_TAG_RUNTIME_VERSION => runtime_version,
39
+ }
40
+ tags[FORM_FIELD_TAG_ENV] = env if env
41
+ tags[FORM_FIELD_TAG_SERVICE] = service if service
42
+ tags[FORM_FIELD_TAG_VERSION] = version if version
43
+
44
+ user_tags.merge(tags)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -38,10 +38,10 @@ module Datadog
38
38
  def exec_with_error_handling(args)
39
39
  Kernel.exec(*args)
40
40
  rescue Errno::ENOENT => e
41
- Kernel.warn "ddtracerb exec failed: #{e.message} (command was '#{args.join(' ')}')"
41
+ Kernel.warn "ddtracerb exec failed: #{e.class.name} #{e.message} (command was '#{args.join(' ')}')"
42
42
  Kernel.exit 127
43
43
  rescue Errno::EACCES, Errno::ENOEXEC => e
44
- Kernel.warn "ddtracerb exec failed: #{e.message} (command was '#{args.join(' ')}')"
44
+ Kernel.warn "ddtracerb exec failed: #{e.class.name} #{e.message} (command was '#{args.join(' ')}')"
45
45
  Kernel.exit 126
46
46
  end
47
47
  end
@@ -1,7 +1,6 @@
1
1
  # typed: false
2
2
 
3
3
  require 'datadog/core/utils/only_once'
4
- require 'datadog/profiling'
5
4
  require 'datadog/profiling/ext/forking'
6
5
 
7
6
  module Datadog
@@ -19,7 +18,8 @@ module Datadog
19
18
  setup_at_fork_hooks
20
19
  rescue StandardError, ScriptError => e
21
20
  Datadog.logger.warn do
22
- "Profiler extensions unavailable. Cause: #{e.message} Location: #{Array(e.backtrace).first}"
21
+ "Profiler extensions unavailable. Cause: #{e.class.name} #{e.message} " \
22
+ "Location: #{Array(e.backtrace).first}"
23
23
  end
24
24
  end
25
25
  end
@@ -35,7 +35,8 @@ module Datadog
35
35
  end
36
36
  rescue StandardError, ScriptError => e
37
37
  Datadog.logger.warn do
38
- "Profiler forking extensions unavailable. Cause: #{e.message} Location: #{Array(e.backtrace).first}"
38
+ "Profiler forking extensions unavailable. Cause: #{e.class.name} #{e.message} " \
39
+ "Location: #{Array(e.backtrace).first}"
39
40
  end
40
41
  end
41
42
 
@@ -65,7 +66,8 @@ module Datadog
65
66
  Profiling.start_if_enabled
66
67
  rescue StandardError => e
67
68
  Datadog.logger.warn do
68
- "Error during post-fork hooks. Cause: #{e.message} Location: #{Array(e.backtrace).first}"
69
+ "Error during post-fork hooks. Cause: #{e.class.name} #{e.message} " \
70
+ "Location: #{Array(e.backtrace).first}"
69
71
  end
70
72
  end
71
73
  end
@@ -10,9 +10,6 @@ module Datadog
10
10
  GOOGLE_PROTOBUF_MINIMUM_VERSION = Gem::Version.new('3.0')
11
11
  private_constant :GOOGLE_PROTOBUF_MINIMUM_VERSION
12
12
 
13
- SKIPPED_NATIVE_EXTENSION_ONLY_ONCE = Core::Utils::OnlyOnce.new
14
- private_constant :SKIPPED_NATIVE_EXTENSION_ONLY_ONCE
15
-
16
13
  def self.supported?
17
14
  unsupported_reason.nil?
18
15
  end
@@ -21,7 +18,7 @@ module Datadog
21
18
  # NOTE: Only the first matching reason is returned, so try to keep a nice order on reasons -- e.g. tell users
22
19
  # first that they can't use this on JRuby before telling them that they are missing protobuf
23
20
 
24
- ruby_engine_unsupported? ||
21
+ native_library_compilation_skipped? ||
25
22
  native_library_failed_to_load? ||
26
23
  protobuf_gem_unavailable? ||
27
24
  protobuf_version_unsupported? ||
@@ -44,8 +41,24 @@ module Datadog
44
41
  !!profiler
45
42
  end
46
43
 
47
- private_class_method def self.ruby_engine_unsupported?
48
- 'JRuby is not supported' if RUBY_ENGINE == 'jruby'
44
+ private_class_method def self.native_library_compilation_skipped?
45
+ skipped_reason = try_reading_skipped_reason_file
46
+
47
+ "Your ddtrace installation is missing support for the Continuous Profiler because #{skipped_reason}" if skipped_reason
48
+ end
49
+
50
+ private_class_method def self.try_reading_skipped_reason_file(file_api = File)
51
+ # This file, if it exists, is recorded by extconf.rb during compilation of the native extension
52
+ skipped_reason_file = "#{__dir__}/../../ext/ddtrace_profiling_native_extension/skipped_reason.txt"
53
+
54
+ begin
55
+ return unless file_api.exist?(skipped_reason_file)
56
+
57
+ contents = file_api.read(skipped_reason_file).strip
58
+ contents unless contents.empty?
59
+ rescue StandardError
60
+ # Do nothing
61
+ end
49
62
  end
50
63
 
51
64
  private_class_method def self.protobuf_gem_unavailable?
@@ -93,12 +106,11 @@ module Datadog
93
106
  # In the future it'd be nice to shuffle the logger startup to happen first to avoid this special case.
94
107
  Kernel.warn(
95
108
  '[DDTRACE] Error while loading google-protobuf gem. ' \
96
- "Cause: '#{e.message}' Location: '#{Array(e.backtrace).first}'. " \
109
+ "Cause: '#{e.class.name} #{e.message}' Location: '#{Array(e.backtrace).first}'. " \
97
110
  'This can happen when google-protobuf is missing its native components. ' \
98
111
  'To fix this, try removing and reinstalling the gem, forcing it to recompile the components: ' \
99
112
  '`gem uninstall google-protobuf -a; BUNDLE_FORCE_RUBY_PLATFORM=true bundle install`. ' \
100
- 'If the error persists, please contact support via <https://docs.datadoghq.com/help/> or ' \
101
- 'file a bug at <https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug>.'
113
+ 'If the error persists, please contact Datadog support at <https://docs.datadoghq.com/help/>.'
102
114
  )
103
115
  @protobuf_loaded = false
104
116
  end
@@ -110,31 +122,18 @@ module Datadog
110
122
  unless success
111
123
  if exception
112
124
  'There was an error loading the profiling native extension due to ' \
113
- "'#{exception.message}' at '#{exception.backtrace.first}'"
125
+ "'#{exception.class.name} #{exception.message}' at '#{exception.backtrace.first}'"
114
126
  else
115
127
  'The profiling native extension did not load correctly. ' \
116
- 'If the error persists, please contact support via <https://docs.datadoghq.com/help/> or ' \
117
- 'file a bug at <https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug>.'
128
+ 'For help solving this issue, please contact Datadog support at <https://docs.datadoghq.com/help/>.' \
118
129
  end
119
130
  end
120
131
  end
121
132
 
122
133
  private_class_method def self.try_loading_native_library
123
- if Core::Environment::VariableHelpers.env_to_bool('DD_PROFILING_NO_EXTENSION', false)
124
- SKIPPED_NATIVE_EXTENSION_ONLY_ONCE.run do
125
- Kernel.warn(
126
- '[DDTRACE] Skipped loading of profiling native extension due to DD_PROFILING_NO_EXTENSION environment ' \
127
- 'variable being set. ' \
128
- 'This option is experimental and will lead to the profiler not working in future releases. ' \
129
- 'If you needed to use this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>.'
130
- )
131
- end
132
-
133
- return [true, nil]
134
- end
135
-
136
134
  begin
137
- require "ddtrace_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
135
+ require 'datadog/profiling/load_native_extension'
136
+
138
137
  success =
139
138
  defined?(Profiling::NativeExtension) && Profiling::NativeExtension.send(:native_working?)
140
139
  [success, nil]
@@ -148,7 +147,9 @@ module Datadog
148
147
 
149
148
  require 'datadog/profiling/ext/forking'
150
149
  require 'datadog/profiling/collectors/code_provenance'
150
+ require 'datadog/profiling/collectors/old_stack'
151
151
  require 'datadog/profiling/collectors/stack'
152
+ require 'datadog/profiling/stack_recorder'
152
153
  require 'datadog/profiling/exporter'
153
154
  require 'datadog/profiling/recorder'
154
155
  require 'datadog/profiling/scheduler'
@@ -159,10 +160,11 @@ module Datadog
159
160
  require 'datadog/profiling/native_extension'
160
161
  require 'datadog/profiling/trace_identifiers/helper'
161
162
  require 'datadog/profiling/pprof/pprof_pb'
163
+ require 'datadog/profiling/tag_builder'
162
164
 
163
165
  true
164
166
  end
165
167
 
166
- load_profiling if supported?
168
+ load_profiling
167
169
  end
168
170
  end
@@ -58,7 +58,9 @@ module Datadog
58
58
 
59
59
  @buffer_spans += trace.length
60
60
  rescue StandardError => e
61
- Datadog.logger.debug("Failed to measure queue accept. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
61
+ Datadog.logger.debug(
62
+ "Failed to measure queue accept. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
63
+ )
62
64
  end
63
65
 
64
66
  def measure_drop(trace)
@@ -66,7 +68,9 @@ module Datadog
66
68
 
67
69
  @buffer_spans -= trace.length
68
70
  rescue StandardError => e
69
- Datadog.logger.debug("Failed to measure queue drop. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
71
+ Datadog.logger.debug(
72
+ "Failed to measure queue drop. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
73
+ )
70
74
  end
71
75
 
72
76
  def measure_pop(traces)
@@ -89,7 +93,9 @@ module Datadog
89
93
  @buffer_dropped = 0
90
94
  @buffer_spans = 0
91
95
  rescue StandardError => e
92
- Datadog.logger.debug("Failed to measure queue. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
96
+ Datadog.logger.debug(
97
+ "Failed to measure queue. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
98
+ )
93
99
  end
94
100
  end
95
101
 
@@ -4,7 +4,6 @@ require 'datadog/core'
4
4
  require 'datadog/tracing/contrib/patcher'
5
5
  require 'datadog/tracing/contrib/action_view/events'
6
6
  require 'datadog/tracing/contrib/action_view/ext'
7
- require 'datadog/tracing/contrib/action_view/integration'
8
7
  require 'datadog/tracing/contrib/action_view/instrumentation/partial_renderer'
9
8
  require 'datadog/tracing/contrib/action_view/instrumentation/template_renderer'
10
9
  require 'datadog/tracing/contrib/action_view/utils'
@@ -69,7 +69,7 @@ module Datadog
69
69
  rescue => e
70
70
  Datadog.logger.error(
71
71
  "Failed to resolve ActiveRecord configuration key #{db_config.inspect}. " \
72
- "Cause: #{e.message} Source: #{Array(e.backtrace).first}"
72
+ "Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
73
73
  )
74
74
 
75
75
  nil
@@ -88,7 +88,7 @@ module Datadog
88
88
  rescue => e
89
89
  Datadog.logger.error(
90
90
  "Failed to resolve ActiveRecord configuration key #{matcher.inspect}. " \
91
- "Cause: #{e.message} Source: #{Array(e.backtrace).first}"
91
+ "Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
92
92
  )
93
93
  end
94
94
 
@@ -77,7 +77,7 @@ module Datadog
77
77
  # in case.
78
78
  Datadog.logger.debug(
79
79
  "connection_id #{connection_id} does not represent a valid object. " \
80
- "Cause: #{e.message} Source: #{Array(e.backtrace).first}"
80
+ "Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
81
81
  )
82
82
  end
83
83
  else
@@ -216,7 +216,7 @@ module Datadog
216
216
  # Bubbled up from the adapter require. Prefix the exception message
217
217
  # with some guidance about how to address it and reraise.
218
218
  else
219
- raise e.class, "Error loading the '#{spec[:adapter]}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
219
+ raise e.class, "Error loading the '#{spec[:adapter]}' Active Record adapter. Missing a gem it depends on? #{e.class.name} #{e.message}", e.backtrace
220
220
  end
221
221
  end
222
222
 
@@ -116,7 +116,9 @@ module Datadog
116
116
  def run(span, name, id, payload)
117
117
  run!(span, name, id, payload)
118
118
  rescue StandardError => e
119
- Datadog.logger.debug("ActiveSupport::Notifications handler for '#{name}' failed: #{e.message}")
119
+ Datadog.logger.debug(
120
+ "ActiveSupport::Notifications handler for '#{name}' failed: #{e.class.name} #{e.message}"
121
+ )
120
122
  end
121
123
 
122
124
  def run!(*args)
@@ -142,7 +144,7 @@ module Datadog
142
144
  callback.call(event, key, *args)
143
145
  rescue StandardError => e
144
146
  Datadog.logger.debug(
145
- "ActiveSupport::Notifications '#{key}' callback for '#{event}' failed: #{e.message}"
147
+ "ActiveSupport::Notifications '#{key}' callback for '#{event}' failed: #{e.class.name} #{e.message}"
146
148
  )
147
149
  end
148
150
  end
@@ -8,7 +8,6 @@ module Datadog
8
8
  module ConcurrentRuby
9
9
  # wraps existing executor to carry over trace context
10
10
  class ContextCompositeExecutorService
11
- extend Forwardable
12
11
  include Concurrent::ExecutorService
13
12
 
14
13
  attr_accessor :composited_executor
@@ -34,11 +33,19 @@ module Datadog
34
33
  end
35
34
  end
36
35
 
36
+ # Respect the {Concurrent::ExecutorService} interface
37
+ def can_overflow?
38
+ @composited_executor.can_overflow?
39
+ end
40
+
41
+ # Respect the {Concurrent::ExecutorService} interface
42
+ def serialized?
43
+ @composited_executor.serialized?
44
+ end
45
+
37
46
  def datadog_configuration
38
47
  Datadog.configuration.tracing[:concurrent_ruby]
39
48
  end
40
-
41
- delegate [:can_overflow?, :serialized?] => :composited_executor
42
49
  end
43
50
  end
44
51
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'datadog/tracing/contrib/dalli/ext'
4
4
  require 'datadog/tracing/contrib/dalli/instrumentation'
5
- require 'datadog/tracing/contrib/dalli/integration'
6
5
  require 'datadog/tracing/contrib/patcher'
7
6
 
8
7
  module Datadog
@@ -1,6 +1,5 @@
1
1
  # typed: false
2
2
 
3
- require 'datadog/tracing/contrib/delayed_job/integration'
4
3
  require 'datadog/tracing/contrib/patcher'
5
4
 
6
5
  module Datadog
@@ -18,12 +18,18 @@ module Datadog
18
18
  register_as :elasticsearch, auto_patch: true
19
19
 
20
20
  def self.version
21
- Gem.loaded_specs['elasticsearch-transport'] \
22
- && Gem.loaded_specs['elasticsearch-transport'].version
21
+ # elastic-transport gem for version >= 8.0.0
22
+ # elasticsearch-transport gem for version < 8.0.0
23
+ Gem.loaded_specs['elastic-transport'] \
24
+ && Gem.loaded_specs['elastic-transport'].version || \
25
+ Gem.loaded_specs['elasticsearch-transport'] \
26
+ && Gem.loaded_specs['elasticsearch-transport'].version
23
27
  end
24
28
 
25
29
  def self.loaded?
26
- !defined?(::Elasticsearch::Transport).nil?
30
+ # Elastic::Transport gem for version >= 8.0.0
31
+ # Elasticsearch::Transport gem for version < 8.0.0
32
+ !defined?(::Elastic::Transport).nil? || !defined?(::Elasticsearch::Transport).nil?
27
33
  end
28
34
 
29
35
  def self.compatible?
@@ -29,16 +29,40 @@ module Datadog
29
29
  patch_elasticsearch_transport_client
30
30
  end
31
31
 
32
+ SELF_DEPRECATION_ONLY_ONCE = Core::Utils::OnlyOnce.new
33
+
32
34
  # rubocop:disable Metrics/MethodLength
33
35
  # rubocop:disable Metrics/AbcSize
36
+ # rubocop:disable Metrics/CyclomaticComplexity
37
+ # rubocop:disable Metrics/PerceivedComplexity
34
38
  def patch_elasticsearch_transport_client
35
39
  # rubocop:disable Metrics/BlockLength
36
- ::Elasticsearch::Transport::Client.class_eval do
40
+ transport_module::Client.class_eval do
37
41
  alias_method :perform_request_without_datadog, :perform_request
38
42
  remove_method :perform_request
39
43
 
40
44
  def perform_request(*args)
41
- service = Datadog.configuration_for(self, :service_name) || datadog_configuration[:service_name]
45
+ # DEV-2.0: Remove this access, as `Client#self` in this context is not exposed to the user
46
+ # since `elasticsearch` v8.0.0. In contrast, `Client#transport` is always available across
47
+ # all `elasticsearch` gem versions and should be used instead.
48
+ service = Datadog.configuration_for(self, :service_name)
49
+
50
+ if service
51
+ SELF_DEPRECATION_ONLY_ONCE.run do
52
+ Datadog.logger.warn(
53
+ 'Providing configuration though the Elasticsearch client object is deprecated.' \
54
+ 'Configure the `client#transport` object instead: ' \
55
+ 'Datadog.configure_onto(client.transport, service_name: service_name, ...)'
56
+ )
57
+ end
58
+ end
59
+
60
+ # `Client#transport` is most convenient object both this integration and the library
61
+ # user have shared access to across all `elasticsearch` versions.
62
+ #
63
+ # `Client#self` in this context is an internal object that the library user
64
+ # does not have access to since `elasticsearch` v8.0.0.
65
+ service ||= Datadog.configuration_for(transport, :service_name) || datadog_configuration[:service_name]
42
66
 
43
67
  method = args[0]
44
68
  path = args[1]
@@ -108,6 +132,18 @@ module Datadog
108
132
  end
109
133
  # rubocop:enable Metrics/MethodLength
110
134
  # rubocop:enable Metrics/AbcSize
135
+ # rubocop:enable Metrics/CyclomaticComplexity
136
+ # rubocop:enable Metrics/PerceivedComplexity
137
+
138
+ # `Elasticsearch` namespace renamed to `Elastic` in version 8.0.0 of the transport gem:
139
+ # @see https://github.com/elastic/elastic-transport-ruby/commit/ef804cbbd284f2a82d825221f87124f8b5ff823c
140
+ def transport_module
141
+ if Integration.version >= Gem::Version.new('8.0.0')
142
+ ::Elastic::Transport
143
+ else
144
+ ::Elasticsearch::Transport
145
+ end
146
+ end
111
147
  end
112
148
  end
113
149
  end
@@ -1,6 +1,5 @@
1
1
  # typed: true
2
2
 
3
- require 'datadog/tracing/contrib/ethon/integration'
4
3
  require 'datadog/tracing/contrib/patcher'
5
4
 
6
5
  module Datadog
@@ -1,10 +1,8 @@
1
1
  # typed: false
2
2
 
3
- require 'forwardable'
4
3
  require 'set'
5
4
 
6
5
  require 'datadog/core/configuration/settings'
7
- require 'datadog/tracing/contrib'
8
6
 
9
7
  # Datadog
10
8
  module Datadog
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'datadog/tracing/contrib/faraday/connection'
4
4
  require 'datadog/tracing/contrib/faraday/ext'
5
- require 'datadog/tracing/contrib/faraday/integration'
6
5
  require 'datadog/tracing/contrib/faraday/rack_builder'
7
6
  require 'datadog/tracing/contrib/patcher'
8
7
 
@@ -3,7 +3,6 @@
3
3
  require 'datadog/tracing/contrib/grape/endpoint'
4
4
  require 'datadog/tracing/contrib/grape/ext'
5
5
  require 'datadog/tracing/contrib/grape/instrumentation'
6
- require 'datadog/tracing/contrib/grape/integration'
7
6
  require 'datadog/tracing/contrib/patcher'
8
7
 
9
8
  module Datadog
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'datadog/tracing'
4
4
  require 'datadog/tracing/contrib/analytics'
5
- require 'datadog/tracing/contrib/graphql/integration'
6
5
  require 'datadog/tracing/contrib/patcher'
7
6
 
8
7
  module Datadog
@@ -1,7 +1,6 @@
1
1
  # typed: true
2
2
 
3
3
  require 'datadog/tracing/contrib/grpc/ext'
4
- require 'datadog/tracing/contrib/grpc/integration'
5
4
  require 'datadog/tracing/contrib/patcher'
6
5
 
7
6
  module Datadog
@@ -3,7 +3,6 @@
3
3
  require 'datadog/tracing/contrib/patcher'
4
4
  require 'datadog/tracing/contrib/kafka/ext'
5
5
  require 'datadog/tracing/contrib/kafka/events'
6
- require 'datadog/tracing/contrib/kafka/integration'
7
6
 
8
7
  module Datadog
9
8
  module Tracing
@@ -1,6 +1,7 @@
1
1
  # typed: true
2
2
 
3
3
  require 'datadog/tracing'
4
+ require 'datadog/core/logging/ext'
4
5
 
5
6
  module Datadog
6
7
  module Tracing
@@ -33,7 +34,7 @@ module Datadog
33
34
  service: correlation.service.to_s,
34
35
  version: correlation.version.to_s
35
36
  },
36
- ddsource: ['ruby']
37
+ ddsource: Core::Logging::Ext::DD_SOURCE
37
38
  }
38
39
 
39
40
  datadog_trace_log_hash.merge(original_custom_options)
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'datadog/tracing'
4
4
  require 'datadog/tracing/contrib/patcher'
5
- require 'datadog/tracing/contrib/qless/integration'
6
5
 
7
6
  module Datadog
8
7
  module Tracing
@@ -2,7 +2,6 @@
2
2
 
3
3
  # typed: false
4
4
 
5
- require 'datadog/tracing/contrib/que/integration'
6
5
  require 'datadog/tracing/contrib/que/tracer'
7
6
 
8
7
  module Datadog
@@ -3,7 +3,6 @@
3
3
  require 'datadog/tracing/contrib/patcher'
4
4
  require 'datadog/tracing/contrib/racecar/ext'
5
5
  require 'datadog/tracing/contrib/racecar/events'
6
- require 'datadog/tracing/contrib/racecar/integration'
7
6
 
8
7
  module Datadog
9
8
  module Tracing
@@ -22,24 +22,11 @@ module Datadog
22
22
  end
23
23
  rescue StandardError => e
24
24
  # TODO: can we use Datadog.logger at this point?
25
- Datadog.logger.warn("Unable to add Datadog Trace context to ActiveSupport::TaggedLogging: #{e.message}")
25
+ Datadog.logger.warn(
26
+ "Unable to add Datadog Trace context to ActiveSupport::TaggedLogging: #{e.class.name} #{e.message}"
27
+ )
26
28
  false
27
29
  end
28
-
29
- def datadog_trace_log_hash(correlation)
30
- {
31
- # Adds IDs as tags to log output
32
- dd: {
33
- # To preserve precision during JSON serialization, use strings for large numbers
34
- trace_id: correlation.trace_id.to_s,
35
- span_id: correlation.span_id.to_s,
36
- env: correlation.env.to_s,
37
- service: correlation.service.to_s,
38
- version: correlation.version.to_s
39
- },
40
- ddsource: ['ruby']
41
- }
42
- end
43
30
  end
44
31
  end
45
32
  end
@@ -61,7 +61,7 @@ module Datadog
61
61
  span.set_tag(Ext::TAG_TASK_ARG_NAMES, arg_names)
62
62
  span.set_tag(Ext::TAG_INVOKE_ARGS, quantize_args(args)) unless args.nil?
63
63
  rescue StandardError => e
64
- Datadog.logger.debug("Error while tracing Rake invoke: #{e.message}")
64
+ Datadog.logger.debug("Error while tracing Rake invoke: #{e.class.name} #{e.message}")
65
65
  end
66
66
 
67
67
  def annotate_execute!(span, args)
@@ -70,7 +70,7 @@ module Datadog
70
70
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_EXECUTE)
71
71
  span.set_tag(Ext::TAG_EXECUTE_ARGS, quantize_args(args.to_hash)) unless args.nil?
72
72
  rescue StandardError => e
73
- Datadog.logger.debug("Error while tracing Rake execute: #{e.message}")
73
+ Datadog.logger.debug("Error while tracing Rake execute: #{e.class.name} #{e.message}")
74
74
  end
75
75
 
76
76
  def quantize_args(args)
@@ -4,7 +4,6 @@ require 'datadog/tracing'
4
4
  require 'datadog/tracing/contrib/patcher'
5
5
  require 'datadog/tracing/contrib/rake/ext'
6
6
  require 'datadog/tracing/contrib/rake/instrumentation'
7
- require 'datadog/tracing/contrib/rake/integration'
8
7
 
9
8
  module Datadog
10
9
  module Tracing