ddtrace 1.4.1 → 1.6.1

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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +144 -1
  3. data/LICENSE-3rdparty.csv +1 -0
  4. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +9 -2
  5. data/ext/ddtrace_profiling_loader/extconf.rb +17 -0
  6. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +38 -2
  7. data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -0
  8. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -0
  9. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +517 -42
  10. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +3 -0
  11. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +208 -30
  12. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +156 -46
  13. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +11 -2
  14. data/ext/ddtrace_profiling_native_extension/extconf.rb +11 -1
  15. data/ext/ddtrace_profiling_native_extension/http_transport.c +83 -64
  16. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +4 -4
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +3 -4
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +59 -0
  19. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
  20. data/ext/ddtrace_profiling_native_extension/profiling.c +10 -0
  21. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -1
  22. data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +4 -2
  23. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +45 -29
  24. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +7 -7
  25. data/lib/datadog/appsec/assets/waf_rules/recommended.json +1169 -275
  26. data/lib/datadog/appsec/assets/waf_rules/risky.json +78 -78
  27. data/lib/datadog/appsec/assets/waf_rules/strict.json +278 -88
  28. data/lib/datadog/appsec/configuration/settings.rb +0 -2
  29. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +25 -20
  30. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +11 -11
  31. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +11 -11
  32. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +11 -11
  33. data/lib/datadog/appsec/contrib/rack/request.rb +3 -0
  34. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +46 -19
  35. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -6
  36. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  37. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +11 -11
  38. data/lib/datadog/appsec/contrib/rails/request.rb +3 -0
  39. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -12
  40. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +11 -11
  41. data/lib/datadog/appsec/event.rb +6 -10
  42. data/lib/datadog/appsec/instrumentation/gateway.rb +16 -2
  43. data/lib/datadog/appsec/processor.rb +18 -2
  44. data/lib/datadog/ci/ext/environment.rb +16 -4
  45. data/lib/datadog/core/configuration/agent_settings_resolver.rb +0 -3
  46. data/lib/datadog/core/configuration/components.rb +28 -16
  47. data/lib/datadog/core/configuration/settings.rb +127 -8
  48. data/lib/datadog/core/configuration.rb +1 -1
  49. data/lib/datadog/core/diagnostics/environment_logger.rb +5 -1
  50. data/lib/datadog/core/header_collection.rb +41 -0
  51. data/lib/datadog/core/telemetry/collector.rb +0 -2
  52. data/lib/datadog/core/utils/compression.rb +5 -1
  53. data/lib/datadog/core/workers/async.rb +0 -2
  54. data/lib/datadog/core.rb +0 -54
  55. data/lib/datadog/opentracer/tracer.rb +4 -6
  56. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +12 -2
  57. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -3
  58. data/lib/datadog/profiling/collectors/old_stack.rb +1 -1
  59. data/lib/datadog/profiling/exporter.rb +2 -4
  60. data/lib/datadog/profiling/http_transport.rb +1 -1
  61. data/lib/datadog/profiling.rb +1 -1
  62. data/lib/datadog/tracing/client_ip.rb +164 -0
  63. data/lib/datadog/tracing/configuration/ext.rb +14 -0
  64. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -0
  65. data/lib/datadog/tracing/contrib/aws/services.rb +0 -2
  66. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  67. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -0
  68. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +2 -0
  69. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +3 -0
  70. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -2
  71. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +2 -0
  72. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -0
  73. data/lib/datadog/tracing/contrib/ext.rb +25 -0
  74. data/lib/datadog/tracing/contrib/faraday/middleware.rb +3 -2
  75. data/lib/datadog/tracing/contrib/grape/endpoint.rb +0 -2
  76. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -1
  77. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +5 -0
  78. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +7 -1
  79. data/lib/datadog/tracing/contrib/grpc/ext.rb +2 -0
  80. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +47 -0
  81. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +22 -0
  82. data/lib/datadog/tracing/contrib/hanami/ext.rb +24 -0
  83. data/lib/datadog/tracing/contrib/hanami/integration.rb +44 -0
  84. data/lib/datadog/tracing/contrib/hanami/patcher.rb +33 -0
  85. data/lib/datadog/tracing/contrib/hanami/plugin.rb +23 -0
  86. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +41 -0
  87. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +44 -0
  88. data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -0
  89. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +2 -0
  90. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -0
  91. data/lib/datadog/tracing/contrib/mongodb/ext.rb +7 -0
  92. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +4 -0
  93. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +12 -0
  94. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  95. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -0
  96. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +12 -0
  97. data/lib/datadog/tracing/contrib/pg/ext.rb +2 -1
  98. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +38 -21
  99. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +43 -0
  100. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +32 -0
  101. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +28 -0
  102. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +49 -0
  103. data/lib/datadog/tracing/contrib/rack/header_collection.rb +35 -0
  104. data/lib/datadog/tracing/contrib/rack/middlewares.rb +105 -43
  105. data/lib/datadog/tracing/contrib/redis/ext.rb +2 -0
  106. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +4 -2
  107. data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
  108. data/lib/datadog/tracing/contrib/redis/patcher.rb +40 -0
  109. data/lib/datadog/tracing/contrib/redis/tags.rb +5 -0
  110. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +2 -0
  111. data/lib/datadog/tracing/contrib/sinatra/env.rb +12 -23
  112. data/lib/datadog/tracing/contrib/sinatra/ext.rb +7 -3
  113. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +2 -2
  114. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +8 -80
  115. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +14 -9
  116. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +92 -10
  117. data/lib/datadog/tracing/contrib.rb +1 -0
  118. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +84 -0
  119. data/lib/datadog/tracing/distributed/headers/datadog.rb +122 -30
  120. data/lib/datadog/tracing/distributed/headers/ext.rb +2 -0
  121. data/lib/datadog/tracing/flush.rb +57 -35
  122. data/lib/datadog/tracing/metadata/ext.rb +11 -9
  123. data/lib/datadog/tracing/metadata/tagging.rb +9 -0
  124. data/lib/datadog/tracing/propagation/http.rb +9 -1
  125. data/lib/datadog/tracing/sampling/ext.rb +31 -0
  126. data/lib/datadog/tracing/sampling/priority_sampler.rb +46 -4
  127. data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +8 -9
  128. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +29 -5
  129. data/lib/datadog/tracing/sampling/rate_limiter.rb +3 -0
  130. data/lib/datadog/tracing/sampling/rate_sampler.rb +20 -3
  131. data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -3
  132. data/lib/datadog/tracing/sampling/span/ext.rb +25 -0
  133. data/lib/datadog/tracing/sampling/span/matcher.rb +9 -0
  134. data/lib/datadog/tracing/sampling/span/rule.rb +82 -0
  135. data/lib/datadog/tracing/sampling/span/rule_parser.rb +104 -0
  136. data/lib/datadog/tracing/sampling/span/sampler.rb +75 -0
  137. data/lib/datadog/tracing/span_operation.rb +0 -2
  138. data/lib/datadog/tracing/trace_digest.rb +3 -0
  139. data/lib/datadog/tracing/trace_operation.rb +32 -3
  140. data/lib/datadog/tracing/trace_segment.rb +7 -2
  141. data/lib/datadog/tracing/tracer.rb +34 -6
  142. data/lib/datadog/tracing/writer.rb +7 -0
  143. data/lib/ddtrace/transport/trace_formatter.rb +7 -0
  144. data/lib/ddtrace/transport/traces.rb +3 -1
  145. data/lib/ddtrace/version.rb +1 -1
  146. metadata +36 -18
  147. data/lib/datadog/profiling/old_ext.rb +0 -42
  148. data/lib/datadog/profiling/transport/http/api/endpoint.rb +0 -85
  149. data/lib/datadog/profiling/transport/http/api/instance.rb +0 -38
  150. data/lib/datadog/profiling/transport/http/api/spec.rb +0 -42
  151. data/lib/datadog/profiling/transport/http/api.rb +0 -45
  152. data/lib/datadog/profiling/transport/http/builder.rb +0 -30
  153. data/lib/datadog/profiling/transport/http/client.rb +0 -37
  154. data/lib/datadog/profiling/transport/http/response.rb +0 -21
  155. data/lib/datadog/profiling/transport/http.rb +0 -118
@@ -151,12 +151,10 @@ module Datadog
151
151
  tags: tags || {}
152
152
  )
153
153
 
154
- # Build or extend the OpenTracer::SpanContext
155
- span_context = if parent_span_context
156
- SpanContextFactory.clone(span_context: parent_span_context)
157
- else
158
- SpanContextFactory.build(datadog_context: datadog_context)
159
- end
154
+ span_context = SpanContextFactory.build(
155
+ datadog_context: datadog_context || datadog_tracer.send(:call_context),
156
+ baggage: parent_span_context ? parent_span_context.baggage.dup : {}
157
+ )
160
158
 
161
159
  # Wrap the Datadog span and OpenTracer::Span context in a OpenTracer::Span
162
160
  Span.new(datadog_span: datadog_span, span_context: span_context)
@@ -11,8 +11,9 @@ module Datadog
11
11
  #
12
12
  # Methods prefixed with _native_ are implemented in `collectors_cpu_and_wall_time.c`
13
13
  class CpuAndWallTime
14
- def initialize(recorder:, max_frames:)
15
- self.class._native_initialize(self, recorder, max_frames)
14
+ def initialize(recorder:, max_frames:, tracer:)
15
+ tracer_context_key = safely_extract_context_key_from(tracer)
16
+ self.class._native_initialize(self, recorder, max_frames, tracer_context_key)
16
17
  end
17
18
 
18
19
  def inspect
@@ -21,6 +22,15 @@ module Datadog
21
22
  result[-1] = "#{self.class._native_inspect(self)}>"
22
23
  result
23
24
  end
25
+
26
+ private
27
+
28
+ def safely_extract_context_key_from(tracer)
29
+ tracer &&
30
+ tracer.respond_to?(:provider) &&
31
+ # NOTE: instance_variable_get always works, even on nil -- it just returns nil if the variable doesn't exist
32
+ tracer.provider.instance_variable_get(:@context).instance_variable_get(:@key)
33
+ end
24
34
  end
25
35
  end
26
36
  end
@@ -18,9 +18,11 @@ module Datadog
18
18
  def initialize(
19
19
  recorder:,
20
20
  max_frames:,
21
- cpu_and_wall_time_collector: CpuAndWallTime.new(recorder: recorder, max_frames: max_frames)
21
+ tracer:,
22
+ gc_profiling_enabled:,
23
+ cpu_and_wall_time_collector: CpuAndWallTime.new(recorder: recorder, max_frames: max_frames, tracer: tracer)
22
24
  )
23
- self.class._native_initialize(self, cpu_and_wall_time_collector)
25
+ self.class._native_initialize(self, cpu_and_wall_time_collector, gc_profiling_enabled)
24
26
  @worker_thread = nil
25
27
  @failure_exception = nil
26
28
  @start_stop_mutex = Mutex.new
@@ -28,7 +30,7 @@ module Datadog
28
30
 
29
31
  def start
30
32
  @start_stop_mutex.synchronize do
31
- return if @worker_thread
33
+ return if @worker_thread && @worker_thread.alive?
32
34
 
33
35
  Datadog.logger.debug { "Starting thread for: #{self}" }
34
36
  @worker_thread = Thread.new do
@@ -15,7 +15,7 @@ module Datadog
15
15
  # Runs on its own background thread.
16
16
  #
17
17
  # This class has the prefix "Old" because it will be deprecated by the new native CPU Profiler
18
- class OldStack < Core::Worker # rubocop:disable Metrics/ClassLength
18
+ class OldStack < Core::Worker
19
19
  include Core::Workers::Polling
20
20
 
21
21
  DEFAULT_MAX_TIME_USAGE_PCT = 2.0
@@ -1,7 +1,6 @@
1
1
  # typed: true
2
2
 
3
3
  require_relative 'ext'
4
- require_relative '../core/utils/compression'
5
4
  require_relative 'tag_builder'
6
5
 
7
6
  module Datadog
@@ -60,10 +59,9 @@ module Datadog
60
59
  start: start,
61
60
  finish: finish,
62
61
  pprof_file_name: Datadog::Profiling::Ext::Transport::HTTP::PPROF_DEFAULT_FILENAME,
63
- pprof_data: Datadog::Core::Utils::Compression.gzip(uncompressed_pprof),
62
+ pprof_data: uncompressed_pprof.to_s,
64
63
  code_provenance_file_name: Datadog::Profiling::Ext::Transport::HTTP::CODE_PROVENANCE_FILENAME,
65
- code_provenance_data:
66
- (Datadog::Core::Utils::Compression.gzip(uncompressed_code_provenance) if uncompressed_code_provenance),
64
+ code_provenance_data: uncompressed_code_provenance,
67
65
  tags_as_array: Datadog::Profiling::TagBuilder.call(settings: Datadog.configuration).to_a,
68
66
  )
69
67
  end
@@ -58,7 +58,7 @@ module Datadog
58
58
  end
59
59
  end
60
60
 
61
- # Used to log soft failures in `ddprof_ffi_Vec_tag_push` (e.g. we still report the profile in these cases)
61
+ # Used to log soft failures in `ddog_Vec_tag_push` (e.g. we still report the profile in these cases)
62
62
  # Called from native code
63
63
  def self.log_failure_to_process_tag(failure_details)
64
64
  Datadog.logger.warn("Failed to add tag to profiling request: #{failure_details}")
@@ -6,7 +6,7 @@ require_relative 'core/utils/only_once'
6
6
 
7
7
  module Datadog
8
8
  # Contains profiler for generating stack profiles, etc.
9
- module Profiling # rubocop:disable Metrics/ModuleLength
9
+ module Profiling
10
10
  GOOGLE_PROTOBUF_MINIMUM_VERSION = Gem::Version.new('3.0')
11
11
  private_constant :GOOGLE_PROTOBUF_MINIMUM_VERSION
12
12
 
@@ -0,0 +1,164 @@
1
+ # typed: true
2
+
3
+ require_relative '../core/configuration'
4
+ require_relative 'metadata/ext'
5
+ require_relative 'span'
6
+
7
+ require 'ipaddr'
8
+
9
+ module Datadog
10
+ module Tracing
11
+ # Common functions for supporting the `http.client_ip` span attribute.
12
+ module ClientIp
13
+ DEFAULT_IP_HEADERS_NAMES = %w[
14
+ x-forwarded-for
15
+ x-real-ip
16
+ x-client-ip
17
+ x-forwarded
18
+ x-cluster-client-ip
19
+ forwarded-for
20
+ forwarded
21
+ via
22
+ true-client-ip
23
+ ].freeze
24
+
25
+ TAG_MULTIPLE_IP_HEADERS = '_dd.multiple-ip-headers'.freeze
26
+
27
+ # Sets the `http.client_ip` tag on the given span.
28
+ #
29
+ # This function respects the user's settings: if they disable the client IP tagging,
30
+ # or provide a different IP header name.
31
+ #
32
+ # If multiple IP headers are present in the request, this function will instead set
33
+ # the `_dd.multiple-ip-headers` tag with the names of the present headers,
34
+ # and **NOT** set the `http.client_ip` tag.
35
+ #
36
+ # @param [Span] span The span that's associated with the request.
37
+ # @param [HeaderCollection, #get, nil] headers A collection with the request headers.
38
+ # @param [String, nil] remote_ip The remote IP the request associated with the span is sent to.
39
+ def self.set_client_ip_tag(span, headers: nil, remote_ip: nil)
40
+ return unless configuration.enabled
41
+
42
+ set_client_ip_tag!(span, headers: headers, remote_ip: remote_ip)
43
+ end
44
+
45
+ # Forcefully sets the `http.client_ip` tag on the given span.
46
+ #
47
+ # This function ignores the user's `enabled` setting.
48
+ #
49
+ # @param [Span] span The span that's associated with the request.
50
+ # @param [HeaderCollection, #get, nil] headers A collection with the request headers.
51
+ # @param [String, nil] remote_ip The remote IP the request associated with the span is sent to.
52
+ def self.set_client_ip_tag!(span, headers: nil, remote_ip: nil)
53
+ result = raw_ip_from_request(headers, remote_ip)
54
+
55
+ if result.raw_ip
56
+ ip = strip_decorations(result.raw_ip)
57
+ return unless valid_ip?(ip)
58
+
59
+ span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_CLIENT_IP, ip)
60
+ elsif result.multiple_ip_headers
61
+ span.set_tag(TAG_MULTIPLE_IP_HEADERS, result.multiple_ip_headers.keys.join(','))
62
+ end
63
+ end
64
+
65
+ IpExtractionResult = Struct.new(:raw_ip, :multiple_ip_headers)
66
+
67
+ # Returns a result struct that holds the raw client IP associated with the request if it was
68
+ # retrieved successfully.
69
+ #
70
+ # The client IP is looked up by the following logic:
71
+ # * If the user has configured a header name, return that header's value.
72
+ # * If exactly one of the known IP headers is present, return that header's value.
73
+ # * If none of the known IP headers are present, return the remote IP from the request.
74
+ #
75
+ # If more than one of the known IP headers is present, the result will have a `multiple_ip_headers`
76
+ # field with the name of the present IP headers.
77
+ #
78
+ # @param [Datadog::Core::HeaderCollection, #get, nil] headers The request headers
79
+ # @param [String] remote_ip The remote IP of the request.
80
+ # @return [IpExtractionResult] A struct that holds the unprocessed IP value,
81
+ # or `nil` if it wasn't found. Additionally, the `multiple_ip_headers` fields will hold the
82
+ # name of known IP headers present in the request if more than one of these were found.
83
+ def self.raw_ip_from_request(headers, remote_ip)
84
+ return IpExtractionResult.new(headers && headers.get(configuration.header_name), nil) if configuration.header_name
85
+
86
+ headers_present = ip_headers(headers)
87
+
88
+ case headers_present.size
89
+ when 0
90
+ IpExtractionResult.new(remote_ip, nil)
91
+ when 1
92
+ IpExtractionResult.new(headers_present.values.first, nil)
93
+ else
94
+ IpExtractionResult.new(nil, headers_present)
95
+ end
96
+ end
97
+
98
+ # Removes any port notations or zone specifiers from the IP address without
99
+ # verifying its validity.
100
+ def self.strip_decorations(address)
101
+ return strip_ipv4_port(address) if likely_ipv4?(address)
102
+
103
+ address = strip_ipv6_port(address)
104
+
105
+ strip_zone_specifier(address)
106
+ end
107
+
108
+ def self.strip_zone_specifier(ipv6)
109
+ ipv6.gsub(/%.*/, '')
110
+ end
111
+
112
+ def self.strip_ipv4_port(ip)
113
+ ip.gsub(/:\d+\z/, '')
114
+ end
115
+
116
+ def self.strip_ipv6_port(ip)
117
+ if /\[(.*)\](?::\d+)?/ =~ ip
118
+ Regexp.last_match(1)
119
+ else
120
+ ip
121
+ end
122
+ end
123
+
124
+ # Returns whether the given value is more likely to be an IPv4 than an IPv6 address.
125
+ #
126
+ # This is done by checking if a dot (`'.'`) character appears before a colon (`':'`) in the value.
127
+ # The rationale is that in valid IPv6 addresses, colons will always preced dots,
128
+ # and in valid IPv4 addresses dots will always preced colons.
129
+ def self.likely_ipv4?(value)
130
+ dot_index = value.index('.') || value.size
131
+ colon_index = value.index(':') || value.size
132
+
133
+ dot_index < colon_index
134
+ end
135
+
136
+ # Determines whether the given string is a valid IPv4 or IPv6 address.
137
+ def self.valid_ip?(ip)
138
+ # Client IPs should not have subnet masks even though IPAddr can parse them.
139
+ return false if ip.include?('/')
140
+
141
+ begin
142
+ IPAddr.new(ip)
143
+
144
+ true
145
+ rescue IPAddr::Error
146
+ false
147
+ end
148
+ end
149
+
150
+ def self.ip_headers(headers)
151
+ return {} unless headers
152
+
153
+ DEFAULT_IP_HEADERS_NAMES.each_with_object({}) do |name, result|
154
+ value = headers.get(name)
155
+ result[name] = value unless value.nil?
156
+ end
157
+ end
158
+
159
+ def self.configuration
160
+ Datadog.configuration.tracing.client_ip
161
+ end
162
+ end
163
+ end
164
+ end
@@ -21,6 +21,7 @@ module Datadog
21
21
  PROPAGATION_STYLE_B3_SINGLE_HEADER = 'B3 single header'.freeze
22
22
  ENV_PROPAGATION_STYLE_INJECT = 'DD_PROPAGATION_STYLE_INJECT'.freeze
23
23
  ENV_PROPAGATION_STYLE_EXTRACT = 'DD_PROPAGATION_STYLE_EXTRACT'.freeze
24
+ ENV_X_DATADOG_TAGS_MAX_LENGTH = 'DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH'.freeze
24
25
  end
25
26
 
26
27
  # @public_api
@@ -32,6 +33,12 @@ module Datadog
32
33
  module Sampling
33
34
  ENV_SAMPLE_RATE = 'DD_TRACE_SAMPLE_RATE'.freeze
34
35
  ENV_RATE_LIMIT = 'DD_TRACE_RATE_LIMIT'.freeze
36
+
37
+ # @public_api
38
+ module Span
39
+ ENV_SPAN_SAMPLING_RULES = 'DD_SPAN_SAMPLING_RULES'.freeze
40
+ ENV_SPAN_SAMPLING_RULES_FILE = 'DD_SPAN_SAMPLING_RULES_FILE'.freeze
41
+ end
35
42
  end
36
43
 
37
44
  # @public_api
@@ -45,6 +52,13 @@ module Datadog
45
52
  ENV_DEFAULT_PORT = 'DD_TRACE_AGENT_PORT'.freeze
46
53
  ENV_DEFAULT_URL = 'DD_TRACE_AGENT_URL'.freeze
47
54
  end
55
+
56
+ # @public_api
57
+ module ClientIp
58
+ ENV_ENABLED = 'DD_TRACE_CLIENT_IP_ENABLED'.freeze
59
+ ENV_DISABLED = 'DD_TRACE_CLIENT_IP_HEADER_DISABLED'.freeze # TODO: deprecated, remove later
60
+ ENV_HEADER_NAME = 'DD_TRACE_CLIENT_IP_HEADER'.freeze
61
+ end
48
62
  end
49
63
  end
50
64
  end
@@ -33,6 +33,8 @@ module Datadog
33
33
  span.name = Ext::SPAN_COMMAND
34
34
  span.resource = context.safely(:resource)
35
35
 
36
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
37
+
36
38
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
37
39
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_COMMAND)
38
40
 
@@ -3,7 +3,6 @@
3
3
  module Datadog
4
4
  module Tracing
5
5
  module Contrib
6
- # rubocop:disable Metrics/ModuleLength:
7
6
  module Aws
8
7
  SERVICES = %w[
9
8
  ACM
@@ -117,7 +116,6 @@ module Datadog
117
116
  XRay
118
117
  ].freeze
119
118
  end
120
- # rubocop:enable Metrics/ModuleLength:
121
119
  end
122
120
  end
123
121
  end
@@ -17,6 +17,7 @@ module Datadog
17
17
  TAG_COMMAND = 'memcached.command'.freeze
18
18
  TAG_COMPONENT = 'dalli'.freeze
19
19
  TAG_OPERATION_COMMAND = 'command'.freeze
20
+ TAG_SYSTEM = 'memcached'.freeze
20
21
  end
21
22
  end
22
23
  end
@@ -3,6 +3,7 @@
3
3
  require_relative '../../metadata/ext'
4
4
  require_relative '../analytics'
5
5
  require_relative 'ext'
6
+ require_relative '../ext'
6
7
  require_relative 'quantize'
7
8
 
8
9
  module Datadog
@@ -37,6 +38,9 @@ module Datadog
37
38
 
38
39
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, hostname)
39
40
  span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, port)
41
+
42
+ span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
43
+
40
44
  cmd = Quantize.format_command(op, args)
41
45
  span.set_tag(Ext::TAG_COMMAND, cmd)
42
46
 
@@ -19,6 +19,8 @@ module Datadog
19
19
  TAG_URL = 'elasticsearch.url'.freeze
20
20
  TAG_COMPONENT = 'elasticsearch'.freeze
21
21
  TAG_OPERATION_QUERY = 'query'.freeze
22
+
23
+ TAG_SYSTEM = 'elasticsearch'.freeze
22
24
  end
23
25
  end
24
26
  end
@@ -3,6 +3,7 @@
3
3
  require_relative '../../metadata/ext'
4
4
  require_relative '../analytics'
5
5
  require_relative 'ext'
6
+ require_relative '../ext'
6
7
  require_relative '../integration'
7
8
  require_relative '../patcher'
8
9
 
@@ -80,6 +81,8 @@ module Datadog
80
81
 
81
82
  span.span_type = Datadog::Tracing::Contrib::Elasticsearch::Ext::SPAN_TYPE_QUERY
82
83
 
84
+ span.set_tag(Contrib::Ext::DB::TAG_SYSTEM, Ext::TAG_SYSTEM)
85
+
83
86
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
84
87
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_QUERY)
85
88
 
@@ -18,7 +18,6 @@ module Datadog
18
18
  end
19
19
 
20
20
  # InstanceMethods - implementing instrumentation
21
- # rubocop:disable Metrics/ModuleLength
22
21
  module InstanceMethods
23
22
  include Contrib::HttpAnnotationHelper
24
23
 
@@ -132,6 +131,8 @@ module Datadog
132
131
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
133
132
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
134
133
 
134
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
135
+
135
136
  uri = try_parse_uri
136
137
  return unless uri
137
138
 
@@ -168,7 +169,6 @@ module Datadog
168
169
  datadog_configuration[:analytics_sample_rate]
169
170
  end
170
171
  end
171
- # rubocop:enable Metrics/ModuleLength
172
172
  end
173
173
  end
174
174
  end
@@ -67,6 +67,8 @@ module Datadog
67
67
  @datadog_multi_span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
68
68
  @datadog_multi_span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_MULTI_REQUEST)
69
69
 
70
+ @datadog_multi_span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
71
+
70
72
  # Tag as an external peer service
71
73
  @datadog_multi_span.set_tag(Tracing::Metadata::Ext::TAG_PEER_SERVICE, @datadog_multi_span.service)
72
74
 
@@ -116,6 +116,8 @@ module Datadog
116
116
  span.service = service_name(datum[:host], @options)
117
117
  span.span_type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
118
118
 
119
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
120
+
119
121
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
120
122
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
121
123
 
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ # Contrib specific constants
7
+ module Ext
8
+ # @public_api
9
+ module DB
10
+ TAG_INSTANCE = 'db.instance'
11
+ TAG_USER = 'db.user'
12
+ TAG_SYSTEM = 'db.system'
13
+ TAG_STATEMENT = 'db.statement'
14
+ TAG_ROW_COUNT = 'db.row_count'
15
+ end
16
+
17
+ module RPC
18
+ TAG_SYSTEM = 'rpc.system'
19
+ TAG_SERVICE = 'rpc.service'
20
+ TAG_METHOD = 'rpc.method'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -39,10 +39,11 @@ module Datadog
39
39
 
40
40
  def annotate!(span, env, options)
41
41
  span.resource = resource_name(env)
42
- service_name(env[:url].host, options)
43
- span.service = options[:split_by_domain] ? env[:url].host : options[:service_name]
42
+ span.service = service_name(env[:url].host, options)
44
43
  span.span_type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
45
44
 
45
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
46
+
46
47
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
47
48
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
48
49
 
@@ -9,7 +9,6 @@ module Datadog
9
9
  module Tracing
10
10
  module Contrib
11
11
  module Grape
12
- # rubocop:disable Metrics/ModuleLength
13
12
  # Endpoint module includes a list of subscribers to create
14
13
  # traces when a Grape endpoint is hit
15
14
  module Endpoint
@@ -245,7 +244,6 @@ module Datadog
245
244
  end
246
245
  end
247
246
  end
248
- # rubocop:enable Metrics/ModuleLength
249
247
  end
250
248
  end
251
249
  end
@@ -27,7 +27,7 @@ module Datadog
27
27
  end
28
28
 
29
29
  option :schemas
30
- option :service_nam
30
+ option :service_name
31
31
  end
32
32
  end
33
33
  end
@@ -4,6 +4,7 @@ require_relative '../../../../tracing'
4
4
  require_relative '../../../metadata/ext'
5
5
  require_relative '../../analytics'
6
6
  require_relative '../ext'
7
+ require_relative '../../ext'
7
8
 
8
9
  module Datadog
9
10
  module Tracing
@@ -36,6 +37,10 @@ module Datadog
36
37
  def annotate!(trace, span, metadata, call)
37
38
  span.set_tags(metadata)
38
39
 
40
+ span.set_tag(Contrib::Ext::RPC::TAG_SYSTEM, Ext::TAG_SYSTEM)
41
+
42
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
43
+
39
44
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
40
45
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_CLIENT)
41
46
 
@@ -6,6 +6,7 @@ require_relative '../../../metadata/ext'
6
6
  require_relative '../../../propagation/grpc'
7
7
  require_relative '../../analytics'
8
8
  require_relative '../ext'
9
+ require_relative '../../ext'
9
10
 
10
11
  module Datadog
11
12
  module Tracing
@@ -19,10 +20,11 @@ module Datadog
19
20
  # its tracing context with a parent client-side context
20
21
  class Server < Base
21
22
  def trace(keywords)
23
+ method = keywords[:method]
22
24
  options = {
23
25
  span_type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND,
24
26
  service: service_name, # TODO: Remove server-side service name configuration
25
- resource: format_resource(keywords[:method]),
27
+ resource: format_resource(method),
26
28
  on_error: error_handler
27
29
  }
28
30
  metadata = keywords[:call].metadata
@@ -30,6 +32,10 @@ module Datadog
30
32
  set_distributed_context!(metadata)
31
33
 
32
34
  Tracing.trace(Ext::SPAN_SERVICE, **options) do |span|
35
+ span.set_tag(Contrib::Ext::RPC::TAG_SYSTEM, Ext::TAG_SYSTEM)
36
+ span.set_tag(Contrib::Ext::RPC::TAG_SERVICE, method.owner.to_s)
37
+ span.set_tag(Contrib::Ext::RPC::TAG_METHOD, method.name)
38
+
33
39
  annotate!(span, metadata)
34
40
 
35
41
  yield
@@ -17,6 +17,8 @@ module Datadog
17
17
  TAG_COMPONENT = 'grpc'.freeze
18
18
  TAG_OPERATION_CLIENT = 'client'.freeze
19
19
  TAG_OPERATION_SERVICE = 'service'.freeze
20
+
21
+ TAG_SYSTEM = 'grpc'.freeze
20
22
  end
21
23
  end
22
24
  end
@@ -0,0 +1,47 @@
1
+ # typed: ignore
2
+
3
+ require_relative '../../metadata/ext'
4
+ require_relative '../analytics'
5
+ require_relative 'ext'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Contrib
10
+ module Hanami
11
+ # Hanami Instrumentation for `hanami.action`
12
+ class ActionTracer
13
+ def initialize(app, action)
14
+ @app = app
15
+ @action = action
16
+ end
17
+
18
+ def call(env)
19
+ Tracing.trace(
20
+ Ext::SPAN_ACTION,
21
+ resource: @action.to_s,
22
+ service: configuration[:service_name],
23
+ span_type: Tracing::Metadata::Ext::HTTP::TYPE_INBOUND
24
+ ) do |span_op, trace_op|
25
+ span_op.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
26
+ span_op.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_ACTION)
27
+
28
+ if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
29
+ Contrib::Analytics.set_sample_rate(span_op, configuration[:analytics_sample_rate])
30
+ end
31
+
32
+ trace_op.resource = span_op.resource
33
+
34
+ @app.call(env)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def configuration
41
+ Datadog.configuration.tracing[:hanami]
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ # typed: ignore
2
+
3
+ require_relative '../../configuration/settings'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module Hanami
10
+ module Configuration
11
+ # Configuration for Hanami instrumentation
12
+ class Settings < Contrib::Configuration::Settings
13
+ option :enabled do |o|
14
+ o.default { env_to_bool(Ext::ENV_ENABLED, true) }
15
+ o.lazy
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end