ddtrace 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
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