ddtrace 1.13.0 → 1.14.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -1
  3. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +15 -0
  4. data/lib/datadog/appsec/configuration/settings.rb +7 -1
  5. data/lib/datadog/core/configuration/agent_settings_resolver.rb +9 -5
  6. data/lib/datadog/core/configuration/components.rb +2 -0
  7. data/lib/datadog/core/configuration/settings.rb +25 -2
  8. data/lib/datadog/core/diagnostics/environment_logger.rb +130 -234
  9. data/lib/datadog/core/environment/execution.rb +65 -0
  10. data/lib/datadog/core/telemetry/collector.rb +10 -2
  11. data/lib/datadog/profiling/component.rb +14 -4
  12. data/lib/datadog/profiling/diagnostics/environment_logger.rb +39 -0
  13. data/lib/datadog/profiling/exporter.rb +4 -4
  14. data/lib/datadog/profiling/flush.rb +2 -4
  15. data/lib/datadog/profiling/http_transport.rb +9 -2
  16. data/lib/datadog/profiling.rb +1 -0
  17. data/lib/datadog/tracing/component.rb +2 -1
  18. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +18 -11
  19. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  20. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +99 -102
  21. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -2
  22. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -17
  23. data/lib/datadog/tracing/contrib/rails/log_injection.rb +6 -3
  24. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  25. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +3 -20
  26. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +9 -9
  27. data/lib/datadog/tracing/contrib.rb +1 -0
  28. data/lib/datadog/tracing/correlation.rb +20 -0
  29. data/lib/datadog/tracing/diagnostics/environment_logger.rb +159 -0
  30. data/lib/datadog/tracing/workers/trace_writer.rb +1 -1
  31. data/lib/ddtrace/version.rb +1 -1
  32. metadata +9 -6
@@ -48,11 +48,14 @@ module Datadog
48
48
  Datadog.logger.debug('Successfully reported profiling data')
49
49
  true
50
50
  else
51
- Datadog.logger.error("Failed to report profiling data: server returned unexpected HTTP #{result} status code")
51
+ Datadog.logger.error(
52
+ "Failed to report profiling data (#{config_without_api_key}): " \
53
+ "server returned unexpected HTTP #{result} status code"
54
+ )
52
55
  false
53
56
  end
54
57
  else
55
- Datadog.logger.error("Failed to report profiling data: #{result}")
58
+ Datadog.logger.error("Failed to report profiling data (#{config_without_api_key}): #{result}")
56
59
  false
57
60
  end
58
61
  end
@@ -128,6 +131,10 @@ module Datadog
128
131
  internal_metadata_json,
129
132
  )
130
133
  end
134
+
135
+ def config_without_api_key
136
+ [@exporter_configuration[0..1]].to_h
137
+ end
131
138
  end
132
139
  end
133
140
  end
@@ -198,6 +198,7 @@ module Datadog
198
198
  require_relative 'profiling/collectors/old_stack'
199
199
  require_relative 'profiling/collectors/stack'
200
200
  require_relative 'profiling/collectors/thread_context'
201
+ require_relative 'profiling/diagnostics/environment_logger'
201
202
  require_relative 'profiling/stack_recorder'
202
203
  require_relative 'profiling/old_recorder'
203
204
  require_relative 'profiling/exporter'
@@ -5,6 +5,7 @@ require_relative 'flush'
5
5
  require_relative 'sync_writer'
6
6
  require_relative 'sampling/span/rule_parser'
7
7
  require_relative 'sampling/span/sampler'
8
+ require_relative 'diagnostics/environment_logger'
8
9
 
9
10
  module Datadog
10
11
  module Tracing
@@ -154,7 +155,7 @@ module Datadog
154
155
  end
155
156
 
156
157
  WRITER_RECORD_ENVIRONMENT_INFORMATION_CALLBACK = lambda do |_, responses|
157
- Core::Diagnostics::EnvironmentLogger.log!(responses)
158
+ Tracing::Diagnostics::EnvironmentLogger.collect_and_log!(responses: responses)
158
159
  end
159
160
 
160
161
  # Create new lambda for writer callback,
@@ -90,18 +90,25 @@ module Datadog
90
90
  )
91
91
  end
92
92
 
93
+ #
94
+ # `::ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver` exists from 4+ til from 6.0.x
95
+ #
96
+ # `::ActiveRecord::DatabaseConfigurations` was introduced from 6+,
97
+ # but from 6.1.x, it was refactored to encapsulates the resolving logic, hence removing the resolver
98
+ #
93
99
  def connection_resolver
94
- @resolver ||= if defined?(::ActiveRecord::Base.configurations.resolve)
95
- ::ActiveRecord::DatabaseConfigurations.new(active_record_configuration)
96
- elsif defined?(::ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver)
97
- ::ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(
98
- active_record_configuration
99
- )
100
- else
101
- Contrib::ActiveRecord::Vendor::ConnectionAdapters::ConnectionSpecification::Resolver.new(
102
- active_record_configuration
103
- )
104
- end
100
+ @resolver ||=
101
+ # From 6.1+
102
+ if defined?(::ActiveRecord::Base.configurations.resolve)
103
+ ::ActiveRecord::DatabaseConfigurations.new(active_record_configuration)
104
+ # From 4+ to 6.0.x
105
+ elsif defined?(::ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver)
106
+ ::ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(active_record_configuration)
107
+ else
108
+ Contrib::ActiveRecord::Vendor::ConnectionAdapters::ConnectionSpecification::Resolver.new(
109
+ active_record_configuration
110
+ )
111
+ end
105
112
  end
106
113
 
107
114
  def resolve_connection_key(key)
@@ -113,7 +113,7 @@ module Datadog
113
113
 
114
114
  # @return [Hash]
115
115
  def self.db_config(connection_pool)
116
- if ::Rails::VERSION::MAJOR >= 6 && ::Rails::VERSION::MINOR >= 1
116
+ if connection_pool.respond_to? :db_config
117
117
  connection_pool.db_config.configuration_hash
118
118
  else
119
119
  connection_pool.spec.config
@@ -24,123 +24,120 @@ module Datadog
24
24
  require 'json'
25
25
  require_relative 'quantize'
26
26
 
27
- patch_elasticsearch_transport_client
27
+ transport_module::Client.prepend(Client)
28
28
  end
29
29
 
30
30
  SELF_DEPRECATION_ONLY_ONCE = Core::Utils::OnlyOnce.new
31
31
 
32
- # rubocop:disable Metrics/MethodLength
33
- # rubocop:disable Metrics/AbcSize
34
- # rubocop:disable Metrics/CyclomaticComplexity
35
- # rubocop:disable Metrics/PerceivedComplexity
36
- def patch_elasticsearch_transport_client
37
- # rubocop:disable Metrics/BlockLength
38
- transport_module::Client.class_eval do
39
- alias_method :perform_request_without_datadog, :perform_request
40
- remove_method :perform_request
41
-
42
- def perform_request(*args)
43
- # DEV-2.0: Remove this access, as `Client#self` in this context is not exposed to the user
44
- # since `elasticsearch` v8.0.0. In contrast, `Client#transport` is always available across
45
- # all `elasticsearch` gem versions and should be used instead.
46
- service = Datadog.configuration_for(self, :service_name)
47
-
48
- if service
49
- SELF_DEPRECATION_ONLY_ONCE.run do
50
- Datadog.logger.warn(
51
- 'Providing configuration though the Elasticsearch client object is deprecated.' \
52
- 'Configure the `client#transport` object instead: ' \
53
- 'Datadog.configure_onto(client.transport, service_name: service_name, ...)'
32
+ # Patches Elasticsearch::Transport::Client module
33
+ module Client
34
+ # rubocop:disable Metrics/MethodLength
35
+ # rubocop:disable Metrics/AbcSize
36
+ def perform_request(*args)
37
+ # DEV-2.0: Remove this access, as `Client#self` in this context is not exposed to the user
38
+ # since `elasticsearch` v8.0.0. In contrast, `Client#transport` is always available across
39
+ # all `elasticsearch` gem versions and should be used instead.
40
+ service = Datadog.configuration_for(self, :service_name)
41
+
42
+ if service
43
+ SELF_DEPRECATION_ONLY_ONCE.run do
44
+ Datadog.logger.warn(
45
+ 'Providing configuration though the Elasticsearch client object is deprecated.' \
46
+ 'Configure the `client#transport` object instead: ' \
47
+ 'Datadog.configure_onto(client.transport, service_name: service_name, ...)'
48
+ )
49
+ end
50
+ end
51
+
52
+ # `Client#transport` is most convenient object both this integration and the library
53
+ # user have shared access to across all `elasticsearch` versions.
54
+ #
55
+ # `Client#self` in this context is an internal object that the library user
56
+ # does not have access to since `elasticsearch` v8.0.0.
57
+ service ||= Datadog.configuration_for(transport, :service_name) || datadog_configuration[:service_name]
58
+
59
+ method = args[0]
60
+ path = args[1]
61
+ params = args[2]
62
+ body = args[3]
63
+ full_url = URI.parse(path)
64
+ url = full_url.path
65
+ response = nil
66
+
67
+ Tracing.trace(Datadog::Tracing::Contrib::Elasticsearch::Ext::SPAN_QUERY, service: service) do |span|
68
+ begin
69
+ connection = transport.connections.first
70
+ host = connection.host[:host] if connection
71
+ port = connection.host[:port] if connection
72
+
73
+ if datadog_configuration[:peer_service]
74
+ span.set_tag(
75
+ Tracing::Metadata::Ext::TAG_PEER_SERVICE,
76
+ datadog_configuration[:peer_service]
54
77
  )
55
78
  end
56
- end
57
79
 
58
- # `Client#transport` is most convenient object both this integration and the library
59
- # user have shared access to across all `elasticsearch` versions.
60
- #
61
- # `Client#self` in this context is an internal object that the library user
62
- # does not have access to since `elasticsearch` v8.0.0.
63
- service ||= Datadog.configuration_for(transport, :service_name) || datadog_configuration[:service_name]
64
-
65
- method = args[0]
66
- path = args[1]
67
- params = args[2]
68
- body = args[3]
69
- full_url = URI.parse(path)
70
-
71
- url = full_url.path
72
- response = nil
73
-
74
- Tracing.trace(Datadog::Tracing::Contrib::Elasticsearch::Ext::SPAN_QUERY, service: service) do |span|
75
- begin
76
- connection = transport.connections.first
77
- host = connection.host[:host] if connection
78
- port = connection.host[:port] if connection
79
-
80
- if datadog_configuration[:peer_service]
81
- span.set_tag(
82
- Tracing::Metadata::Ext::TAG_PEER_SERVICE,
83
- datadog_configuration[:peer_service]
84
- )
85
- end
86
-
87
- span.span_type = Datadog::Tracing::Contrib::Elasticsearch::Ext::SPAN_TYPE_QUERY
88
-
89
- span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
90
- span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_QUERY)
91
- span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
92
-
93
- span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
94
-
95
- # load JSON for the following fields unless they're already strings
96
- params = JSON.generate(params) if params && !params.is_a?(String)
97
- body = JSON.generate(body) if body && !body.is_a?(String)
98
-
99
- span.set_tag(Tracing::Metadata::Ext::TAG_PEER_HOSTNAME, host) if host
100
-
101
- # Set analytics sample rate
102
- if Contrib::Analytics.enabled?(datadog_configuration[:analytics_enabled])
103
- Contrib::Analytics.set_sample_rate(span, datadog_configuration[:analytics_sample_rate])
104
- end
105
-
106
- span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_METHOD, method)
107
- span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_URL, url)
108
- span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_PARAMS, params) if params
109
- if body
110
- quantize_options = datadog_configuration[:quantize]
111
- quantized_body = Datadog::Tracing::Contrib::Elasticsearch::Quantize.format_body(
112
- body,
113
- quantize_options
114
- )
115
- span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_BODY, quantized_body)
116
- end
117
- span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, host) if host
118
- span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, port) if port
119
-
120
- quantized_url = Datadog::Tracing::Contrib::Elasticsearch::Quantize.format_url(url)
121
- span.resource = "#{method} #{quantized_url}"
122
- Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
123
- rescue StandardError => e
124
- Datadog.logger.error(e.message)
125
- ensure
126
- # the call is still executed
127
- response = perform_request_without_datadog(*args)
128
- span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.status)
80
+ span.span_type = Datadog::Tracing::Contrib::Elasticsearch::Ext::SPAN_TYPE_QUERY
81
+
82
+ span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
83
+ span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_QUERY)
84
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
85
+
86
+ span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
87
+
88
+ span.set_tag(Tracing::Metadata::Ext::TAG_PEER_HOSTNAME, host) if host
89
+
90
+ # Set analytics sample rate
91
+ if Contrib::Analytics.enabled?(datadog_configuration[:analytics_enabled])
92
+ Contrib::Analytics.set_sample_rate(span, datadog_configuration[:analytics_sample_rate])
129
93
  end
94
+
95
+ span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_METHOD, method)
96
+ tag_params(params, span)
97
+ tag_body(body, span)
98
+ span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_URL, url)
99
+ span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, host) if host
100
+ span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, port) if port
101
+
102
+ quantized_url = Datadog::Tracing::Contrib::Elasticsearch::Quantize.format_url(url)
103
+ span.resource = "#{method} #{quantized_url}"
104
+ Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
105
+ rescue StandardError => e
106
+ Datadog.logger.error(e.message)
107
+ ensure
108
+ # the call is still executed
109
+ response = super
110
+ span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response.status)
130
111
  end
131
- response
132
112
  end
113
+ response
114
+ end
133
115
 
134
- def datadog_configuration
135
- Datadog.configuration.tracing[:elasticsearch]
136
- end
116
+ def tag_params(params, span)
117
+ return unless params
118
+
119
+ params = JSON.generate(params) unless params.is_a?(String)
120
+ span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_PARAMS, params)
121
+ end
122
+
123
+ def tag_body(body, span)
124
+ return unless body
125
+
126
+ body = JSON.generate(body) unless body.is_a?(String)
127
+ quantize_options = datadog_configuration[:quantize]
128
+ quantized_body = Datadog::Tracing::Contrib::Elasticsearch::Quantize.format_body(
129
+ body,
130
+ quantize_options
131
+ )
132
+ span.set_tag(Datadog::Tracing::Contrib::Elasticsearch::Ext::TAG_BODY, quantized_body)
133
+ end
134
+
135
+ def datadog_configuration
136
+ Datadog.configuration.tracing[:elasticsearch]
137
137
  end
138
- # rubocop:enable Metrics/BlockLength
139
138
  end
140
139
  # rubocop:enable Metrics/MethodLength
141
140
  # rubocop:enable Metrics/AbcSize
142
- # rubocop:enable Metrics/CyclomaticComplexity
143
- # rubocop:enable Metrics/PerceivedComplexity
144
141
 
145
142
  # `Elasticsearch` namespace renamed to `Elastic` in version 8.0.0 of the transport gem:
146
143
  # @see https://github.com/elastic/elastic-transport-ruby/commit/ef804cbbd284f2a82d825221f87124f8b5ff823c
@@ -3,6 +3,7 @@ require 'uri'
3
3
  require_relative '../../metadata/ext'
4
4
  require_relative '../analytics'
5
5
  require_relative '../http_annotation_helper'
6
+ require_relative '../utils/quantization/http'
6
7
 
7
8
  module Datadog
8
9
  module Tracing
@@ -79,8 +80,10 @@ module Datadog
79
80
 
80
81
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
81
82
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
82
-
83
- span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, request.path)
83
+ span.set_tag(
84
+ Tracing::Metadata::Ext::HTTP::TAG_URL,
85
+ Contrib::Utils::Quantization::HTTP.url(request.path, { query: { exclude: :all } })
86
+ )
84
87
  span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, request.method)
85
88
 
86
89
  host, port = host_and_port(request)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../core/logging/ext'
4
-
5
3
  module Datadog
6
4
  module Tracing
7
5
  module Contrib
@@ -23,21 +21,7 @@ module Datadog
23
21
  # Retrieves trace information for current thread
24
22
  correlation = Tracing.correlation
25
23
  # merge original lambda with datadog context
26
-
27
- datadog_trace_log_hash = {
28
- # Adds IDs as tags to log output
29
- dd: {
30
- # To preserve precision during JSON serialization, use strings for large numbers
31
- trace_id: correlation.trace_id.to_s,
32
- span_id: correlation.span_id.to_s,
33
- env: correlation.env.to_s,
34
- service: correlation.service.to_s,
35
- version: correlation.version.to_s
36
- },
37
- ddsource: Core::Logging::Ext::DD_SOURCE
38
- }
39
-
40
- datadog_trace_log_hash.merge(original_custom_options)
24
+ correlation.to_h.merge(original_custom_options)
41
25
  end
42
26
  end
43
27
  end
@@ -8,9 +8,12 @@ module Datadog
8
8
  module_function
9
9
 
10
10
  # Use `app.config.log_tags` to inject propagation tags into the default Rails logger.
11
- def configure_log_tags(app)
12
- app.config.log_tags ||= [] # Can be nil, we initialized it if so
13
- app.config.log_tags << proc { Tracing.log_correlation if Datadog.configuration.tracing.log_injection }
11
+ def configure_log_tags(app_config)
12
+ # When using SemanticLogger, app_config.log_tags could be a Hash and should not be modified here
13
+ return unless app_config.log_tags.nil? || app_config.log_tags.respond_to?(:<<)
14
+
15
+ app_config.log_tags ||= [] # Can be nil, we initialized it if so
16
+ app_config.log_tags << proc { Tracing.log_correlation if Datadog.configuration.tracing.log_injection }
14
17
  rescue StandardError => e
15
18
  Datadog.logger.warn(
16
19
  "Unable to add Datadog Trace context to ActiveSupport::TaggedLogging: #{e.class.name} #{e.message}"
@@ -41,7 +41,7 @@ module Datadog
41
41
  # Sometimes we don't want to activate middleware e.g. OpenTracing, etc.
42
42
  add_middleware(app) if Datadog.configuration.tracing[:rails][:middleware]
43
43
 
44
- Rails::LogInjection.configure_log_tags(app)
44
+ Rails::LogInjection.configure_log_tags(app.config)
45
45
  end
46
46
  end
47
47
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../core/logging/ext'
4
-
5
3
  module Datadog
6
4
  module Tracing
7
5
  module Contrib
@@ -23,25 +21,10 @@ module Datadog
23
21
 
24
22
  # Retrieves trace information for current thread
25
23
  correlation = Tracing.correlation
26
- # merge original lambda with datadog context
27
-
28
- datadog_trace_log_hash = {
29
- # Adds IDs as tags to log output
30
- dd: {
31
- # To preserve precision during JSON serialization, use strings for large numbers
32
- trace_id: correlation.trace_id.to_s,
33
- span_id: correlation.span_id.to_s,
34
- env: correlation.env.to_s,
35
- service: correlation.service.to_s,
36
- version: correlation.version.to_s
37
- },
38
- ddsource: Core::Logging::Ext::DD_SOURCE
39
- }
40
24
 
41
- # # if the user already has conflicting log_tags
42
- # # we want them to clobber ours, because we should allow them to override
43
- # # if needed.
44
- log.named_tags = datadog_trace_log_hash.merge(original_named_tags)
25
+ # if the user already has conflicting log_tags
26
+ # we want them to clobber ours, because we should allow them to override if needed.
27
+ log.named_tags = correlation.to_h.merge(original_named_tags)
45
28
  super(log, message, progname, &block)
46
29
  end
47
30
  end
@@ -134,18 +134,18 @@ module Datadog
134
134
  (?:"|%22)?
135
135
  )
136
136
  (?: # common keys
137
- (?:old_?|new_?)?p(?:ass)?w(?:or)?d(?:1|2)? # pw, password variants
138
- |pass(?:_?phrase)? # pass, passphrase variants
137
+ (?:old[-_]?|new_?)?p(?:ass)?w(?:or)?d(?:1|2)? # pw, password variants
138
+ |pass(?:[-_]?phrase)? # pass, passphrase variants
139
139
  |secret
140
140
  |(?: # key, key_id variants
141
- api_?
142
- |private_?
143
- |public_?
144
- |access_?
145
- |secret_?
146
- )key(?:_?id)?
141
+ api[-_]?
142
+ |private[-_]?
143
+ |public[-_]?
144
+ |access[-_]?
145
+ |secret[-_]?
146
+ )key(?:[-_]?id)?
147
147
  |token
148
- |consumer_?(?:id|key|secret)
148
+ |consumer[-_]?(?:id|key|secret)
149
149
  |sign(?:ed|ature)?
150
150
  |auth(?:entication|orization)?
151
151
  )
@@ -58,6 +58,7 @@ require_relative 'contrib/kafka/integration'
58
58
  require_relative 'contrib/lograge/integration'
59
59
  require_relative 'contrib/mongodb/integration'
60
60
  require_relative 'contrib/mysql2/integration'
61
+ require_relative 'contrib/opensearch/integration'
61
62
  require_relative 'contrib/pg/integration'
62
63
  require_relative 'contrib/presto/integration'
63
64
  require_relative 'contrib/qless/integration'
@@ -1,5 +1,6 @@
1
1
  require_relative 'utils'
2
2
  require_relative 'metadata/ext'
3
+ require_relative '../core/logging/ext'
3
4
 
4
5
  module Datadog
5
6
  module Tracing
@@ -14,6 +15,7 @@ module Datadog
14
15
  LOG_ATTR_SPAN_ID = 'dd.span_id'.freeze
15
16
  LOG_ATTR_TRACE_ID = 'dd.trace_id'.freeze
16
17
  LOG_ATTR_VERSION = 'dd.version'.freeze
18
+ LOG_ATTR_SOURCE = 'ddsource'.freeze
17
19
 
18
20
  attr_reader \
19
21
  :env,
@@ -58,6 +60,23 @@ module Datadog
58
60
  @version = Core::Utils::SafeDup.frozen_dup(version || Datadog.configuration.version)
59
61
  end
60
62
 
63
+ def to_h
64
+ @to_h ||= {
65
+ # Adds IDs as tags to log output
66
+ dd: {
67
+ # To preserve precision during JSON serialization, use strings for large numbers
68
+ env: env.to_s,
69
+ service: service.to_s,
70
+ version: version.to_s,
71
+ trace_id: trace_id.to_s,
72
+ span_id: span_id.to_s
73
+ },
74
+ ddsource: Core::Logging::Ext::DD_SOURCE
75
+ }
76
+ end
77
+
78
+ # This method (#to_log_format) implements an algorithm by prefixing keys for nested values
79
+ # but the algorithm makes the constants implicit. Hence, we use it for validation during test.
61
80
  def to_log_format
62
81
  @log_format ||= begin
63
82
  attributes = []
@@ -66,6 +85,7 @@ module Datadog
66
85
  attributes << "#{LOG_ATTR_VERSION}=#{version}" unless version.nil?
67
86
  attributes << "#{LOG_ATTR_TRACE_ID}=#{trace_id}"
68
87
  attributes << "#{LOG_ATTR_SPAN_ID}=#{span_id}"
88
+ attributes << "#{LOG_ATTR_SOURCE}=#{Core::Logging::Ext::DD_SOURCE}"
69
89
  attributes.join(' ')
70
90
  end
71
91
  end