ddtrace 1.4.2 → 1.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -2
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +0 -2
- data/lib/datadog/appsec/configuration/settings.rb +0 -2
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +0 -2
- data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
- data/lib/datadog/ci/ext/environment.rb +16 -4
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +0 -3
- data/lib/datadog/core/configuration/components.rb +8 -2
- data/lib/datadog/core/configuration/settings.rb +69 -2
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/core/header_collection.rb +41 -0
- data/lib/datadog/core/telemetry/collector.rb +0 -2
- data/lib/datadog/core/workers/async.rb +0 -2
- data/lib/datadog/profiling/collectors/old_stack.rb +1 -1
- data/lib/datadog/profiling.rb +1 -1
- data/lib/datadog/tracing/client_ip.rb +153 -0
- data/lib/datadog/tracing/configuration/ext.rb +12 -0
- data/lib/datadog/tracing/contrib/aws/services.rb +0 -2
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +0 -2
- data/lib/datadog/tracing/contrib/ext.rb +19 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -2
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +0 -2
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +5 -4
- data/lib/datadog/tracing/contrib/rack/header_collection.rb +35 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +92 -38
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +83 -9
- data/lib/datadog/tracing/flush.rb +57 -35
- data/lib/datadog/tracing/metadata/ext.rb +3 -9
- data/lib/datadog/tracing/metadata/tagging.rb +9 -0
- data/lib/datadog/tracing/sampling/rate_limiter.rb +3 -0
- data/lib/datadog/tracing/sampling/rate_sampler.rb +10 -0
- data/lib/datadog/tracing/sampling/span/ext.rb +29 -0
- data/lib/datadog/tracing/sampling/span/matcher.rb +9 -0
- data/lib/datadog/tracing/sampling/span/rule.rb +82 -0
- data/lib/datadog/tracing/sampling/span/rule_parser.rb +104 -0
- data/lib/datadog/tracing/sampling/span/sampler.rb +64 -0
- data/lib/datadog/tracing/span_operation.rb +0 -2
- data/lib/datadog/tracing/trace_operation.rb +22 -3
- data/lib/datadog/tracing/trace_segment.rb +1 -2
- data/lib/datadog/tracing/tracer.rb +31 -5
- data/lib/ddtrace/version.rb +2 -2
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 480825e1e52697f2e7b49f605a733b2e53072b36aac74b664c62fada4e6acac2
|
4
|
+
data.tar.gz: 288731a19cf08d4fb6d546ef3481a6a571823de993df97d5e5b14ff4cfc3b820
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 902874e4c974a680373aa6c6ecf0b40a21bb285c266dd340e5d89c92827375e5e3c6480cc7988719a54eaa8e5e3829ddbb914afc84179e53d99fa1dff50759ad
|
7
|
+
data.tar.gz: 890b97da4ceda1d07358b3a019a23ce0d224410359ea30f9128050c1de3a05ce077bd4592517b0606323215a6dac9b306bde38efddf69e742c6b324f52c239e7
|
data/CHANGELOG.md
CHANGED
@@ -2,11 +2,37 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [1.5.0] - 2022-09-29
|
6
|
+
|
7
|
+
### Deprecation notice
|
8
|
+
|
9
|
+
* `c.tracing.instrument :rack, { quantize: { base: ... } }` will change its default from `:exclude` to `:show` in a future version. Voluntarily moving to `:show` is recommended.
|
10
|
+
* `c.tracing.instrument :rack, { quantize: { query: { show: ... } }` will change its default to `:all` in a future version, together with `quantize.query.obfuscate` changing to `:internal`. Voluntarily moving to these future values is recommended.
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
* Feature: Single Span Sampling ([#2128][])
|
15
|
+
* Add query string automatic redaction ([#2283][])
|
16
|
+
* Use full URL in `http.url` tag ([#2265][])
|
17
|
+
* Add `http.useragent` tag ([#2252][])
|
18
|
+
* Add `http.client_ip` tag for Rack-based frameworks ([#2248][])
|
19
|
+
* Ci-app: CI: Fetch committer and author in Bitrise ([#2258][])
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
* Bump allowed version of debase-ruby_core_source to include v0.10.17 ([#2267][])
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
* Bug: Fix `service_nam` typo to `service_name` ([#2296][])
|
28
|
+
* Bug: Check AppSec Rails for railties instead of rails meta gem ([#2293][]) ([@seuros][])
|
29
|
+
* Ci-app: Correctly extract commit message from AppVeyor ([#2257][])
|
30
|
+
|
5
31
|
## [1.4.2] - 2022-09-27
|
6
32
|
|
7
33
|
### Fixed
|
8
34
|
|
9
|
-
OpenTracing context propagation (#2191, #2289)
|
35
|
+
OpenTracing context propagation ([#2191][], [#2289][])
|
10
36
|
|
11
37
|
## [1.4.1] - 2022-09-15
|
12
38
|
|
@@ -2104,6 +2130,7 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
|
|
2104
2130
|
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
2105
2131
|
|
2106
2132
|
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.4.2...master
|
2133
|
+
[1.5.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.4.2...v1.5.0
|
2107
2134
|
[1.4.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.4.1...v1.4.2
|
2108
2135
|
[1.4.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.4.0...v1.4.1
|
2109
2136
|
[1.4.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.3.0...v1.4.0
|
@@ -2973,6 +3000,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2973
3000
|
[#2113]: https://github.com/DataDog/dd-trace-rb/issues/2113
|
2974
3001
|
[#2118]: https://github.com/DataDog/dd-trace-rb/issues/2118
|
2975
3002
|
[#2125]: https://github.com/DataDog/dd-trace-rb/issues/2125
|
3003
|
+
[#2128]: https://github.com/DataDog/dd-trace-rb/issues/2128
|
2976
3004
|
[#2134]: https://github.com/DataDog/dd-trace-rb/issues/2134
|
2977
3005
|
[#2138]: https://github.com/DataDog/dd-trace-rb/issues/2138
|
2978
3006
|
[#2140]: https://github.com/DataDog/dd-trace-rb/issues/2140
|
@@ -2985,12 +3013,23 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2985
3013
|
[#2173]: https://github.com/DataDog/dd-trace-rb/issues/2173
|
2986
3014
|
[#2174]: https://github.com/DataDog/dd-trace-rb/issues/2174
|
2987
3015
|
[#2180]: https://github.com/DataDog/dd-trace-rb/issues/2180
|
3016
|
+
[#2191]: https://github.com/DataDog/dd-trace-rb/issues/2191
|
2988
3017
|
[#2200]: https://github.com/DataDog/dd-trace-rb/issues/2200
|
2989
3018
|
[#2201]: https://github.com/DataDog/dd-trace-rb/issues/2201
|
2990
3019
|
[#2219]: https://github.com/DataDog/dd-trace-rb/issues/2219
|
2991
3020
|
[#2229]: https://github.com/DataDog/dd-trace-rb/issues/2229
|
3021
|
+
[#2248]: https://github.com/DataDog/dd-trace-rb/issues/2248
|
2992
3022
|
[#2250]: https://github.com/DataDog/dd-trace-rb/issues/2250
|
3023
|
+
[#2252]: https://github.com/DataDog/dd-trace-rb/issues/2252
|
3024
|
+
[#2257]: https://github.com/DataDog/dd-trace-rb/issues/2257
|
3025
|
+
[#2258]: https://github.com/DataDog/dd-trace-rb/issues/2258
|
3026
|
+
[#2265]: https://github.com/DataDog/dd-trace-rb/issues/2265
|
3027
|
+
[#2267]: https://github.com/DataDog/dd-trace-rb/issues/2267
|
2993
3028
|
[#2279]: https://github.com/DataDog/dd-trace-rb/issues/2279
|
3029
|
+
[#2283]: https://github.com/DataDog/dd-trace-rb/issues/2283
|
3030
|
+
[#2289]: https://github.com/DataDog/dd-trace-rb/issues/2289
|
3031
|
+
[#2293]: https://github.com/DataDog/dd-trace-rb/issues/2293
|
3032
|
+
[#2296]: https://github.com/DataDog/dd-trace-rb/issues/2296
|
2994
3033
|
[@AdrianLC]: https://github.com/AdrianLC
|
2995
3034
|
[@Azure7111]: https://github.com/Azure7111
|
2996
3035
|
[@BabyGroot]: https://github.com/BabyGroot
|
@@ -3112,6 +3151,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
3112
3151
|
[@saturnflyer]: https://github.com/saturnflyer
|
3113
3152
|
[@sco11morgan]: https://github.com/sco11morgan
|
3114
3153
|
[@senny]: https://github.com/senny
|
3154
|
+
[@seuros]: https://github.com/seuros
|
3115
3155
|
[@shayonj]: https://github.com/shayonj
|
3116
3156
|
[@sinsoku]: https://github.com/sinsoku
|
3117
3157
|
[@skcc321]: https://github.com/skcc321
|
@@ -3132,4 +3172,4 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
3132
3172
|
[@walterking]: https://github.com/walterking
|
3133
3173
|
[@y-yagi]: https://github.com/y-yagi
|
3134
3174
|
[@yukimurasawa]: https://github.com/yukimurasawa
|
3135
|
-
[@zachmccormick]: https://github.com/zachmccormick
|
3175
|
+
[@zachmccormick]: https://github.com/zachmccormick
|
@@ -68,7 +68,6 @@ module Datadog
|
|
68
68
|
|
69
69
|
# Used to check if profiler is supported, including user-visible clear messages explaining why their
|
70
70
|
# system may not be supported.
|
71
|
-
# rubocop:disable Metrics/ModuleLength
|
72
71
|
module Supported
|
73
72
|
private_class_method def self.explain_issue(*reason, suggested:)
|
74
73
|
{ reason: reason, suggested: suggested }
|
@@ -284,7 +283,6 @@ module Datadog
|
|
284
283
|
no_binaries_for_current_platform unless Libdatadog.pkgconfig_folder
|
285
284
|
end
|
286
285
|
end
|
287
|
-
# rubocop:enable Metrics/ModuleLength
|
288
286
|
end
|
289
287
|
end
|
290
288
|
end
|
@@ -5,7 +5,6 @@ module Datadog
|
|
5
5
|
module Configuration
|
6
6
|
# Configuration settings, acting as an integration registry
|
7
7
|
# TODO: as with Configuration, this is a trivial implementation
|
8
|
-
# rubocop:disable Metrics/ClassLength
|
9
8
|
class Settings
|
10
9
|
class << self
|
11
10
|
def boolean
|
@@ -188,7 +187,6 @@ module Datadog
|
|
188
187
|
initialize
|
189
188
|
end
|
190
189
|
end
|
191
|
-
# rubocop:enable Metrics/ClassLength
|
192
190
|
end
|
193
191
|
end
|
194
192
|
end
|
@@ -13,7 +13,6 @@ module Datadog
|
|
13
13
|
module Rack
|
14
14
|
module Gateway
|
15
15
|
# Watcher for Rack gateway events
|
16
|
-
# rubocop:disable Metrics/ModuleLength
|
17
16
|
module Watcher
|
18
17
|
# rubocop:disable Metrics/AbcSize
|
19
18
|
# rubocop:disable Metrics/MethodLength
|
@@ -161,7 +160,6 @@ module Datadog
|
|
161
160
|
end
|
162
161
|
end
|
163
162
|
end
|
164
|
-
# rubocop:enable Metrics/ModuleLength
|
165
163
|
end
|
166
164
|
end
|
167
165
|
end
|
@@ -10,7 +10,6 @@ module Datadog
|
|
10
10
|
module CI
|
11
11
|
module Ext
|
12
12
|
# Defines constants for CI tags
|
13
|
-
# rubocop:disable Metrics/ModuleLength:
|
14
13
|
module Environment
|
15
14
|
include Kernel # Ensure that kernel methods are always available (https://sorbet.org/docs/error-reference#7003)
|
16
15
|
|
@@ -97,6 +96,12 @@ module Datadog
|
|
97
96
|
tag = env['APPVEYOR_REPO_TAG_NAME']
|
98
97
|
end
|
99
98
|
|
99
|
+
commit_message = env['APPVEYOR_REPO_COMMIT_MESSAGE']
|
100
|
+
if commit_message
|
101
|
+
extended = env['APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED']
|
102
|
+
commit_message = "#{commit_message}\n#{extended}" if extended
|
103
|
+
end
|
104
|
+
|
100
105
|
{
|
101
106
|
TAG_PROVIDER_NAME => 'appveyor',
|
102
107
|
Core::Git::Ext::TAG_REPOSITORY_URL => repository,
|
@@ -111,7 +116,7 @@ module Datadog
|
|
111
116
|
Core::Git::Ext::TAG_TAG => tag,
|
112
117
|
Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env['APPVEYOR_REPO_COMMIT_AUTHOR'],
|
113
118
|
Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env['APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL'],
|
114
|
-
Core::Git::Ext::TAG_COMMIT_MESSAGE =>
|
119
|
+
Core::Git::Ext::TAG_COMMIT_MESSAGE => commit_message
|
115
120
|
}
|
116
121
|
end
|
117
122
|
|
@@ -330,6 +335,10 @@ module Datadog
|
|
330
335
|
branch = (
|
331
336
|
env['BITRISEIO_GIT_BRANCH_DEST'] || env['BITRISE_GIT_BRANCH']
|
332
337
|
)
|
338
|
+
commiter_email = (
|
339
|
+
env['GIT_CLONE_COMMIT_COMMITER_EMAIL'] || env['GIT_CLONE_COMMIT_COMMITER_NAME']
|
340
|
+
)
|
341
|
+
|
333
342
|
{
|
334
343
|
TAG_PROVIDER_NAME => 'bitrise',
|
335
344
|
TAG_PIPELINE_ID => env['BITRISE_BUILD_SLUG'],
|
@@ -341,7 +350,11 @@ module Datadog
|
|
341
350
|
Core::Git::Ext::TAG_COMMIT_SHA => commit,
|
342
351
|
Core::Git::Ext::TAG_BRANCH => branch,
|
343
352
|
Core::Git::Ext::TAG_TAG => env['BITRISE_GIT_TAG'],
|
344
|
-
Core::Git::Ext::TAG_COMMIT_MESSAGE => env['BITRISE_GIT_MESSAGE']
|
353
|
+
Core::Git::Ext::TAG_COMMIT_MESSAGE => env['BITRISE_GIT_MESSAGE'],
|
354
|
+
Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env['GIT_CLONE_COMMIT_AUTHOR_NAME'],
|
355
|
+
Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env['GIT_CLONE_COMMIT_AUTHOR_EMAIL'],
|
356
|
+
Core::Git::Ext::TAG_COMMIT_COMMITTER_NAME => env['GIT_CLONE_COMMIT_COMMITER_NAME'],
|
357
|
+
Core::Git::Ext::TAG_COMMIT_COMMITTER_EMAIL => commiter_email
|
345
358
|
}
|
346
359
|
end
|
347
360
|
|
@@ -499,7 +512,6 @@ module Datadog
|
|
499
512
|
[nil, name_and_email]
|
500
513
|
end
|
501
514
|
end
|
502
|
-
# rubocop:enable Metrics/ModuleLength:
|
503
515
|
end
|
504
516
|
end
|
505
517
|
end
|
@@ -18,8 +18,6 @@ module Datadog
|
|
18
18
|
#
|
19
19
|
# Whenever there is a conflict (different configurations are provided in different orders), it MUST warn the users
|
20
20
|
# about it and pick a value based on the following priority: code > environment variable > defaults.
|
21
|
-
#
|
22
|
-
# rubocop:disable Metrics/ClassLength
|
23
21
|
class AgentSettingsResolver
|
24
22
|
AgentSettings = \
|
25
23
|
Struct.new(
|
@@ -359,7 +357,6 @@ module Datadog
|
|
359
357
|
end
|
360
358
|
end
|
361
359
|
end
|
362
|
-
# rubocop:enable Metrics/ClassLength
|
363
360
|
end
|
364
361
|
end
|
365
362
|
end
|
@@ -11,12 +11,13 @@ require_relative '../workers/runtime_metrics'
|
|
11
11
|
require_relative '../../tracing/tracer'
|
12
12
|
require_relative '../../tracing/flush'
|
13
13
|
require_relative '../../tracing/sync_writer'
|
14
|
+
require_relative '../../tracing/sampling/span/rule_parser'
|
15
|
+
require_relative '../../tracing/sampling/span/sampler'
|
14
16
|
|
15
17
|
module Datadog
|
16
18
|
module Core
|
17
19
|
module Configuration
|
18
20
|
# Global components for the trace library.
|
19
|
-
# rubocop:disable Metrics/ClassLength
|
20
21
|
class Components
|
21
22
|
class << self
|
22
23
|
def build_health_metrics(settings)
|
@@ -80,6 +81,7 @@ module Datadog
|
|
80
81
|
enabled: settings.tracing.enabled,
|
81
82
|
trace_flush: trace_flush,
|
82
83
|
sampler: sampler,
|
84
|
+
span_sampler: build_span_sampler(settings),
|
83
85
|
writer: writer,
|
84
86
|
tags: build_tracer_tags(settings),
|
85
87
|
)
|
@@ -183,6 +185,11 @@ module Datadog
|
|
183
185
|
end
|
184
186
|
end
|
185
187
|
|
188
|
+
def build_span_sampler(settings)
|
189
|
+
rules = Tracing::Sampling::Span::RuleParser.parse_json(settings.tracing.sampling.span_rules)
|
190
|
+
Tracing::Sampling::Span::Sampler.new(rules || [])
|
191
|
+
end
|
192
|
+
|
186
193
|
def build_profiler(settings, agent_settings, tracer)
|
187
194
|
return unless settings.profiling.enabled
|
188
195
|
|
@@ -423,7 +430,6 @@ module Datadog
|
|
423
430
|
telemetry.emit_closing! unless replacement
|
424
431
|
end
|
425
432
|
end
|
426
|
-
# rubocop:enable Metrics/ClassLength
|
427
433
|
end
|
428
434
|
end
|
429
435
|
end
|
@@ -15,7 +15,6 @@ module Datadog
|
|
15
15
|
# Global configuration settings for the trace library.
|
16
16
|
# @public_api
|
17
17
|
# rubocop:disable Metrics/BlockLength
|
18
|
-
# rubocop:disable Metrics/ClassLength
|
19
18
|
# rubocop:disable Layout/LineLength
|
20
19
|
class Settings
|
21
20
|
include Base
|
@@ -540,6 +539,7 @@ module Datadog
|
|
540
539
|
option :sampler
|
541
540
|
|
542
541
|
# Client-side sampling configuration.
|
542
|
+
# @see https://docs.datadoghq.com/tracing/trace_ingestion/mechanisms/
|
543
543
|
# @public_api
|
544
544
|
settings :sampling do
|
545
545
|
# Default sampling rate for the tracer.
|
@@ -566,6 +566,48 @@ module Datadog
|
|
566
566
|
o.default { env_to_float(Tracing::Configuration::Ext::Sampling::ENV_RATE_LIMIT, 100) }
|
567
567
|
o.lazy
|
568
568
|
end
|
569
|
+
|
570
|
+
# Single span sampling rules.
|
571
|
+
# These rules allow a span to be kept when its encompassing trace is dropped.
|
572
|
+
#
|
573
|
+
# The syntax for single span sampling rules can be found here:
|
574
|
+
# TODO: <Single Span Sampling documentation URL here>
|
575
|
+
#
|
576
|
+
# @default `DD_SPAN_SAMPLING_RULES` environment variable.
|
577
|
+
# Otherwise, `ENV_SPAN_SAMPLING_RULES_FILE` environment variable.
|
578
|
+
# Otherwise `nil`.
|
579
|
+
# @return [String,nil]
|
580
|
+
# @public_api
|
581
|
+
option :span_rules do |o|
|
582
|
+
o.default do
|
583
|
+
rules = ENV[Tracing::Configuration::Ext::Sampling::Span::ENV_SPAN_SAMPLING_RULES]
|
584
|
+
rules_file = ENV[Tracing::Configuration::Ext::Sampling::Span::ENV_SPAN_SAMPLING_RULES_FILE]
|
585
|
+
|
586
|
+
if rules
|
587
|
+
if rules_file
|
588
|
+
Datadog.logger.warn(
|
589
|
+
'Both DD_SPAN_SAMPLING_RULES and DD_SPAN_SAMPLING_RULES_FILE were provided: only ' \
|
590
|
+
'DD_SPAN_SAMPLING_RULES will be used. Please do not provide DD_SPAN_SAMPLING_RULES_FILE when ' \
|
591
|
+
'also providing DD_SPAN_SAMPLING_RULES as their configuration conflicts. ' \
|
592
|
+
"DD_SPAN_SAMPLING_RULES_FILE=#{rules_file} DD_SPAN_SAMPLING_RULES=#{rules}"
|
593
|
+
)
|
594
|
+
end
|
595
|
+
rules
|
596
|
+
elsif rules_file
|
597
|
+
begin
|
598
|
+
File.read(rules_file)
|
599
|
+
rescue => e
|
600
|
+
# `File#read` errors have clear and actionable messages, no need to add extra exception info.
|
601
|
+
Datadog.logger.warn(
|
602
|
+
"Cannot read span sampling rules file `#{rules_file}`: #{e.message}." \
|
603
|
+
'No span sampling rules will be applied.'
|
604
|
+
)
|
605
|
+
nil
|
606
|
+
end
|
607
|
+
end
|
608
|
+
end
|
609
|
+
o.lazy
|
610
|
+
end
|
569
611
|
end
|
570
612
|
|
571
613
|
# [Continuous Integration Visibility](https://docs.datadoghq.com/continuous_integration/) configuration.
|
@@ -618,6 +660,32 @@ module Datadog
|
|
618
660
|
# @default `{}`
|
619
661
|
# @return [Hash,nil]
|
620
662
|
option :writer_options, default: ->(_i) { {} }, lazy: true
|
663
|
+
|
664
|
+
# Client IP configuration
|
665
|
+
# @public_api
|
666
|
+
settings :client_ip do
|
667
|
+
# Whether client IP collection is enabled. When enabled client IPs from HTTP requests will
|
668
|
+
# be reported in traces.
|
669
|
+
#
|
670
|
+
# @see https://docs.datadoghq.com/tracing/configure_data_security#configuring-a-client-ip-header
|
671
|
+
#
|
672
|
+
# @default The negated value of the `DD_TRACE_CLIENT_IP_HEADER_DISABLED` environment
|
673
|
+
# variable or `true` if it doesn't exist.
|
674
|
+
# @return [Boolean]
|
675
|
+
option :enabled do |o|
|
676
|
+
o.default { !env_to_bool(Tracing::Configuration::Ext::ClientIp::ENV_DISABLED, false) }
|
677
|
+
o.lazy
|
678
|
+
end
|
679
|
+
|
680
|
+
# An optional name of a custom header to resolve the client IP from.
|
681
|
+
#
|
682
|
+
# @default `DD_TRACE_CLIENT_IP_HEADER` environment variable, otherwise `nil`.
|
683
|
+
# @return [String,nil]
|
684
|
+
option :header_name do |o|
|
685
|
+
o.default { ENV.fetch(Tracing::Configuration::Ext::ClientIp::ENV_HEADER_NAME, nil) }
|
686
|
+
o.lazy
|
687
|
+
end
|
688
|
+
end
|
621
689
|
end
|
622
690
|
|
623
691
|
# The `version` tag in Datadog. Use it to enable [Deployment Tracking](https://docs.datadoghq.com/tracing/deployment_tracking/).
|
@@ -645,7 +713,6 @@ module Datadog
|
|
645
713
|
end
|
646
714
|
end
|
647
715
|
# rubocop:enable Metrics/BlockLength
|
648
|
-
# rubocop:enable Metrics/ClassLength
|
649
716
|
# rubocop:enable Layout/LineLength
|
650
717
|
end
|
651
718
|
end
|
@@ -9,7 +9,7 @@ require_relative 'pin'
|
|
9
9
|
module Datadog
|
10
10
|
module Core
|
11
11
|
# Configuration provides a unique access point for configurations
|
12
|
-
module Configuration
|
12
|
+
module Configuration
|
13
13
|
include Kernel # Ensure that kernel methods are always available (https://sorbet.org/docs/error-reference#7003)
|
14
14
|
|
15
15
|
# Used to ensure that @components initialization/reconfiguration is performed one-at-a-time, by a single thread.
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Datadog
|
2
|
+
module Core
|
3
|
+
# A some-what abstract class representing a collection of headers.
|
4
|
+
#
|
5
|
+
# Use the `HeaderCollection.from_hash` function to create a header collection from a `Hash`.
|
6
|
+
# Another option is to use `HashHeaderCollection` directly.
|
7
|
+
class HeaderCollection
|
8
|
+
# Gets a single value of the header with the given name, case insensitive.
|
9
|
+
#
|
10
|
+
# @param [String] header_name Name of the header to get the value of.
|
11
|
+
# @returns [String, nil] A single value of the header, or nil if the header with
|
12
|
+
# the given name is missing from the collection.
|
13
|
+
def get(header_name)
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create a header collection that retrieves headers from the given Hash.
|
18
|
+
#
|
19
|
+
# This can be useful for testing or other trivial use cases.
|
20
|
+
#
|
21
|
+
# @param [Hash] hash Hash with the headers.
|
22
|
+
def self.from_hash(hash)
|
23
|
+
HashHeaderCollection.new(hash)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# A header collection implementation that looks up headers in a Hash.
|
28
|
+
class HashHeaderCollection < HeaderCollection
|
29
|
+
def initialize(hash)
|
30
|
+
super()
|
31
|
+
@hash = {}.tap do |res|
|
32
|
+
hash.each_pair { |key, value| res[key.downcase] = value }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def get(header_name)
|
37
|
+
@hash[header_name.downcase]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -18,7 +18,6 @@ module Datadog
|
|
18
18
|
module Core
|
19
19
|
module Telemetry
|
20
20
|
# Module defining methods for collecting metadata for telemetry
|
21
|
-
# rubocop:disable Metrics/ModuleLength
|
22
21
|
module Collector
|
23
22
|
include Datadog::Core::Configuration
|
24
23
|
|
@@ -228,7 +227,6 @@ module Datadog
|
|
228
227
|
end
|
229
228
|
end
|
230
229
|
end
|
231
|
-
# rubocop:enable Metrics/ModuleLength
|
232
230
|
end
|
233
231
|
end
|
234
232
|
end
|
@@ -8,7 +8,6 @@ module Datadog
|
|
8
8
|
module Async
|
9
9
|
# Adds threading behavior to workers
|
10
10
|
# to run tasks asynchronously.
|
11
|
-
# rubocop:disable Metrics/ModuleLength
|
12
11
|
module Thread
|
13
12
|
FORK_POLICY_STOP = :stop
|
14
13
|
FORK_POLICY_RESTART = :restart
|
@@ -175,7 +174,6 @@ module Datadog
|
|
175
174
|
end
|
176
175
|
end
|
177
176
|
end
|
178
|
-
# rubocop:enable Metrics/ModuleLength
|
179
177
|
end
|
180
178
|
end
|
181
179
|
end
|
@@ -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
|
18
|
+
class OldStack < Core::Worker
|
19
19
|
include Core::Workers::Polling
|
20
20
|
|
21
21
|
DEFAULT_MAX_TIME_USAGE_PCT = 2.0
|
data/lib/datadog/profiling.rb
CHANGED
@@ -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
|
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,153 @@
|
|
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
|
+
result = raw_ip_from_request(headers, remote_ip)
|
43
|
+
|
44
|
+
if result.raw_ip
|
45
|
+
ip = strip_decorations(result.raw_ip)
|
46
|
+
return unless valid_ip?(ip)
|
47
|
+
|
48
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_CLIENT_IP, ip)
|
49
|
+
elsif result.multiple_ip_headers
|
50
|
+
span.set_tag(TAG_MULTIPLE_IP_HEADERS, result.multiple_ip_headers.keys.join(','))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
IpExtractionResult = Struct.new(:raw_ip, :multiple_ip_headers)
|
55
|
+
|
56
|
+
# Returns a result struct that holds the raw client IP associated with the request if it was
|
57
|
+
# retrieved successfully.
|
58
|
+
#
|
59
|
+
# The client IP is looked up by the following logic:
|
60
|
+
# * If the user has configured a header name, return that header's value.
|
61
|
+
# * If exactly one of the known IP headers is present, return that header's value.
|
62
|
+
# * If none of the known IP headers are present, return the remote IP from the request.
|
63
|
+
#
|
64
|
+
# If more than one of the known IP headers is present, the result will have a `multiple_ip_headers`
|
65
|
+
# field with the name of the present IP headers.
|
66
|
+
#
|
67
|
+
# @param [Datadog::Core::HeaderCollection, #get, nil] headers The request headers
|
68
|
+
# @param [String] remote_ip The remote IP of the request.
|
69
|
+
# @return [IpExtractionResult] A struct that holds the unprocessed IP value,
|
70
|
+
# or `nil` if it wasn't found. Additionally, the `multiple_ip_headers` fields will hold the
|
71
|
+
# name of known IP headers present in the request if more than one of these were found.
|
72
|
+
def self.raw_ip_from_request(headers, remote_ip)
|
73
|
+
return IpExtractionResult.new(headers && headers.get(configuration.header_name), nil) if configuration.header_name
|
74
|
+
|
75
|
+
headers_present = ip_headers(headers)
|
76
|
+
|
77
|
+
case headers_present.size
|
78
|
+
when 0
|
79
|
+
IpExtractionResult.new(remote_ip, nil)
|
80
|
+
when 1
|
81
|
+
IpExtractionResult.new(headers_present.values.first, nil)
|
82
|
+
else
|
83
|
+
IpExtractionResult.new(nil, headers_present)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Removes any port notations or zone specifiers from the IP address without
|
88
|
+
# verifying its validity.
|
89
|
+
def self.strip_decorations(address)
|
90
|
+
return strip_ipv4_port(address) if likely_ipv4?(address)
|
91
|
+
|
92
|
+
address = strip_ipv6_port(address)
|
93
|
+
|
94
|
+
strip_zone_specifier(address)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.strip_zone_specifier(ipv6)
|
98
|
+
ipv6.gsub(/%.*/, '')
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.strip_ipv4_port(ip)
|
102
|
+
ip.gsub(/:\d+\z/, '')
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.strip_ipv6_port(ip)
|
106
|
+
if /\[(.*)\](?::\d+)?/ =~ ip
|
107
|
+
Regexp.last_match(1)
|
108
|
+
else
|
109
|
+
ip
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns whether the given value is more likely to be an IPv4 than an IPv6 address.
|
114
|
+
#
|
115
|
+
# This is done by checking if a dot (`'.'`) character appears before a colon (`':'`) in the value.
|
116
|
+
# The rationale is that in valid IPv6 addresses, colons will always preced dots,
|
117
|
+
# and in valid IPv4 addresses dots will always preced colons.
|
118
|
+
def self.likely_ipv4?(value)
|
119
|
+
dot_index = value.index('.') || value.size
|
120
|
+
colon_index = value.index(':') || value.size
|
121
|
+
|
122
|
+
dot_index < colon_index
|
123
|
+
end
|
124
|
+
|
125
|
+
# Determines whether the given string is a valid IPv4 or IPv6 address.
|
126
|
+
def self.valid_ip?(ip)
|
127
|
+
# Client IPs should not have subnet masks even though IPAddr can parse them.
|
128
|
+
return false if ip.include?('/')
|
129
|
+
|
130
|
+
begin
|
131
|
+
IPAddr.new(ip)
|
132
|
+
|
133
|
+
true
|
134
|
+
rescue IPAddr::Error
|
135
|
+
false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.ip_headers(headers)
|
140
|
+
return {} unless headers
|
141
|
+
|
142
|
+
DEFAULT_IP_HEADERS_NAMES.each_with_object({}) do |name, result|
|
143
|
+
value = headers.get(name)
|
144
|
+
result[name] = value unless value.nil?
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.configuration
|
149
|
+
Datadog.configuration.tracing.client_ip
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -32,6 +32,12 @@ module Datadog
|
|
32
32
|
module Sampling
|
33
33
|
ENV_SAMPLE_RATE = 'DD_TRACE_SAMPLE_RATE'.freeze
|
34
34
|
ENV_RATE_LIMIT = 'DD_TRACE_RATE_LIMIT'.freeze
|
35
|
+
|
36
|
+
# @public_api
|
37
|
+
module Span
|
38
|
+
ENV_SPAN_SAMPLING_RULES = 'DD_SPAN_SAMPLING_RULES'.freeze
|
39
|
+
ENV_SPAN_SAMPLING_RULES_FILE = 'DD_SPAN_SAMPLING_RULES_FILE'.freeze
|
40
|
+
end
|
35
41
|
end
|
36
42
|
|
37
43
|
# @public_api
|
@@ -45,6 +51,12 @@ module Datadog
|
|
45
51
|
ENV_DEFAULT_PORT = 'DD_TRACE_AGENT_PORT'.freeze
|
46
52
|
ENV_DEFAULT_URL = 'DD_TRACE_AGENT_URL'.freeze
|
47
53
|
end
|
54
|
+
|
55
|
+
# @public_api
|
56
|
+
module ClientIp
|
57
|
+
ENV_DISABLED = 'DD_TRACE_CLIENT_IP_HEADER_DISABLED'.freeze
|
58
|
+
ENV_HEADER_NAME = 'DD_TRACE_CLIENT_IP_HEADER'.freeze
|
59
|
+
end
|
48
60
|
end
|
49
61
|
end
|
50
62
|
end
|