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