datadog 2.0.0.beta2 → 2.0.0.rc1
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 +57 -1
- data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +1 -1
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +8 -20
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +18 -10
- data/ext/datadog_profiling_native_extension/crashtracker.c +108 -0
- data/ext/datadog_profiling_native_extension/extconf.rb +9 -23
- data/ext/datadog_profiling_native_extension/heap_recorder.c +38 -3
- data/ext/datadog_profiling_native_extension/heap_recorder.h +5 -0
- data/ext/datadog_profiling_native_extension/http_transport.c +0 -93
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +86 -0
- data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +4 -0
- data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +2 -12
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +25 -86
- data/ext/datadog_profiling_native_extension/profiling.c +2 -0
- data/ext/datadog_profiling_native_extension/ruby_helpers.h +3 -5
- data/ext/datadog_profiling_native_extension/stack_recorder.c +156 -55
- data/lib/datadog/appsec/contrib/devise/tracking.rb +8 -0
- data/lib/datadog/core/configuration/settings.rb +10 -79
- data/lib/datadog/core/remote/client.rb +1 -5
- data/lib/datadog/core/remote/configuration/repository.rb +1 -1
- data/lib/datadog/core/remote/dispatcher.rb +3 -3
- data/lib/datadog/core/telemetry/emitter.rb +1 -1
- data/lib/datadog/core/telemetry/http/response.rb +4 -0
- data/lib/datadog/opentelemetry/sdk/span_processor.rb +18 -1
- data/lib/datadog/profiling/component.rb +26 -2
- data/lib/datadog/profiling/crashtracker.rb +91 -0
- data/lib/datadog/profiling/exporter.rb +6 -3
- data/lib/datadog/profiling/http_transport.rb +7 -11
- data/lib/datadog/profiling/profiler.rb +9 -2
- data/lib/datadog/profiling/stack_recorder.rb +6 -2
- data/lib/datadog/profiling.rb +1 -0
- data/lib/datadog/tracing/component.rb +5 -1
- data/lib/datadog/tracing/configuration/dynamic.rb +39 -1
- data/lib/datadog/tracing/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/integration.rb +10 -0
- data/lib/datadog/tracing/contrib/configuration/resolver.rb +43 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +1 -1
- data/lib/datadog/tracing/remote.rb +5 -1
- data/lib/datadog/tracing/sampling/ext.rb +5 -1
- data/lib/datadog/tracing/sampling/matcher.rb +60 -31
- data/lib/datadog/tracing/sampling/rule.rb +12 -5
- data/lib/datadog/tracing/sampling/rule_sampler.rb +17 -1
- data/lib/datadog/tracing/sampling/span/matcher.rb +13 -41
- data/lib/datadog/tracing/span_link.rb +12 -6
- data/lib/datadog/tracing/span_operation.rb +6 -4
- data/lib/datadog/version.rb +1 -1
- metadata +7 -5
@@ -6,6 +6,9 @@ module Datadog
|
|
6
6
|
# Checks if a trace conforms to a matching criteria.
|
7
7
|
# @abstract
|
8
8
|
class Matcher
|
9
|
+
# Pattern that matches any string
|
10
|
+
MATCH_ALL_PATTERN = '*'
|
11
|
+
|
9
12
|
# Returns `true` if the trace should conforms to this rule, `false` otherwise
|
10
13
|
#
|
11
14
|
# @param [TraceOperation] trace
|
@@ -13,20 +16,49 @@ module Datadog
|
|
13
16
|
def match?(trace)
|
14
17
|
raise NotImplementedError
|
15
18
|
end
|
16
|
-
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
#
|
20
|
+
# Converts a glob pattern String to a case-insensitive String matcher object.
|
21
|
+
# The match object will only return `true` if it matches the complete String.
|
22
|
+
#
|
23
|
+
# The following special characters are supported:
|
24
|
+
# - `?` matches any single character
|
25
|
+
# - `*` matches any substring
|
26
|
+
#
|
27
|
+
# @param glob [String]
|
28
|
+
# @return [#match?(String)]
|
29
|
+
def self.glob_to_regex(glob)
|
30
|
+
# Optimization for match-all case
|
31
|
+
return MATCH_ALL if glob == MATCH_ALL_PATTERN
|
32
|
+
|
33
|
+
# Ensure no undesired characters are treated as regex.
|
34
|
+
glob = Regexp.quote(glob)
|
35
|
+
|
36
|
+
# Our valid special characters, `?` and `*`, were just escaped
|
37
|
+
# by `Regexp.quote` above. We need to unescape them:
|
38
|
+
glob.gsub!('\?', '.') # Any single character
|
39
|
+
glob.gsub!('\*', '.*') # Any substring
|
40
|
+
|
41
|
+
# Patterns have to match the whole input string
|
42
|
+
glob = "\\A#{glob}\\z"
|
43
|
+
|
44
|
+
Regexp.new(glob, Regexp::IGNORECASE)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns `true` for any input
|
22
48
|
MATCH_ALL = Class.new do
|
23
|
-
|
24
|
-
# DEV: a `Proc` that always returns `true`.
|
25
|
-
def ===(other)
|
49
|
+
def match?(_other)
|
26
50
|
true
|
27
51
|
end
|
52
|
+
|
53
|
+
def inspect
|
54
|
+
"MATCH_ALL:Matcher('*')"
|
55
|
+
end
|
28
56
|
end.new
|
57
|
+
end
|
29
58
|
|
59
|
+
# A {Datadog::Sampling::Matcher} that supports matching a trace by
|
60
|
+
# trace name and/or service name.
|
61
|
+
class SimpleMatcher < Matcher
|
30
62
|
attr_reader :name, :service, :resource, :tags
|
31
63
|
|
32
64
|
# @param name [String,Regexp,Proc] Matcher for case equality (===) with the trace name,
|
@@ -35,16 +67,30 @@ module Datadog
|
|
35
67
|
# defaults to always match
|
36
68
|
# @param resource [String,Regexp,Proc] Matcher for case equality (===) with the resource name,
|
37
69
|
# defaults to always match
|
38
|
-
def initialize(
|
70
|
+
def initialize(
|
71
|
+
name: MATCH_ALL_PATTERN,
|
72
|
+
service: MATCH_ALL_PATTERN,
|
73
|
+
resource: MATCH_ALL_PATTERN,
|
74
|
+
tags: {}
|
75
|
+
)
|
39
76
|
super()
|
40
|
-
|
41
|
-
|
42
|
-
|
77
|
+
|
78
|
+
name = Matcher.glob_to_regex(name)
|
79
|
+
service = Matcher.glob_to_regex(service)
|
80
|
+
resource = Matcher.glob_to_regex(resource)
|
81
|
+
tags = tags.transform_values { |matcher| Matcher.glob_to_regex(matcher) }
|
82
|
+
|
83
|
+
@name = name || Datadog::Tracing::Sampling::Matcher::MATCH_ALL
|
84
|
+
@service = service || Datadog::Tracing::Sampling::Matcher::MATCH_ALL
|
85
|
+
@resource = resource || Datadog::Tracing::Sampling::Matcher::MATCH_ALL
|
43
86
|
@tags = tags
|
44
87
|
end
|
45
88
|
|
46
89
|
def match?(trace)
|
47
|
-
name
|
90
|
+
@name.match?(trace.name) &&
|
91
|
+
@service.match?(trace.service) &&
|
92
|
+
@resource.match?(trace.resource) &&
|
93
|
+
tags_match?(trace)
|
48
94
|
end
|
49
95
|
|
50
96
|
private
|
@@ -59,27 +105,10 @@ module Datadog
|
|
59
105
|
# can affect exact string matching (e.g. '400' matching '400.0').
|
60
106
|
tag = format('%g', tag) if tag.is_a?(Numeric)
|
61
107
|
|
62
|
-
matcher
|
108
|
+
matcher.match?(tag)
|
63
109
|
end
|
64
110
|
end
|
65
111
|
end
|
66
|
-
|
67
|
-
# A {Datadog::Tracing::Sampling::Matcher} that allows for arbitrary trace matching
|
68
|
-
# based on the return value of a provided block.
|
69
|
-
class ProcMatcher < Matcher
|
70
|
-
attr_reader :block
|
71
|
-
|
72
|
-
# @yield [name, service] Provides trace name and service to the block
|
73
|
-
# @yieldreturn [Boolean] Whether the trace conforms to this matcher
|
74
|
-
def initialize(&block)
|
75
|
-
super()
|
76
|
-
@block = block
|
77
|
-
end
|
78
|
-
|
79
|
-
def match?(trace)
|
80
|
-
block.call(trace.name, trace.service)
|
81
|
-
end
|
82
|
-
end
|
83
112
|
end
|
84
113
|
end
|
85
114
|
end
|
@@ -10,13 +10,18 @@ module Datadog
|
|
10
10
|
# a specific criteria and what sampling strategy to
|
11
11
|
# apply in case of a positive match.
|
12
12
|
class Rule
|
13
|
-
|
13
|
+
PROVENANCE_LOCAL = :local
|
14
|
+
PROVENANCE_REMOTE_USER = :customer
|
15
|
+
PROVENANCE_REMOTE_DYNAMIC = :dynamic
|
16
|
+
|
17
|
+
attr_reader :matcher, :sampler, :provenance
|
14
18
|
|
15
19
|
# @param [Matcher] matcher A matcher to verify trace conformity against
|
16
20
|
# @param [Sampler] sampler A sampler to be consulted on a positive match
|
17
|
-
def initialize(matcher, sampler)
|
21
|
+
def initialize(matcher, sampler, provenance)
|
18
22
|
@matcher = matcher
|
19
23
|
@sampler = sampler
|
24
|
+
@provenance = provenance
|
20
25
|
end
|
21
26
|
|
22
27
|
# Evaluates if the provided `trace` conforms to the `matcher`.
|
@@ -55,8 +60,10 @@ module Datadog
|
|
55
60
|
# defaults to always match
|
56
61
|
# @param sample_rate [Float] Sampling rate between +[0,1]+
|
57
62
|
def initialize(
|
58
|
-
name: SimpleMatcher::
|
59
|
-
resource: SimpleMatcher::
|
63
|
+
name: SimpleMatcher::MATCH_ALL_PATTERN, service: SimpleMatcher::MATCH_ALL_PATTERN,
|
64
|
+
resource: SimpleMatcher::MATCH_ALL_PATTERN, tags: {},
|
65
|
+
provenance: Rule::PROVENANCE_LOCAL,
|
66
|
+
sample_rate: 1.0
|
60
67
|
)
|
61
68
|
# We want to allow 0.0 to drop all traces, but {Datadog::Tracing::Sampling::RateSampler}
|
62
69
|
# considers 0.0 an invalid rate and falls back to 100% sampling.
|
@@ -69,7 +76,7 @@ module Datadog
|
|
69
76
|
sampler = RateSampler.new
|
70
77
|
sampler.sample_rate = sample_rate
|
71
78
|
|
72
|
-
super(SimpleMatcher.new(name: name, service: service, resource: resource, tags: tags), sampler)
|
79
|
+
super(SimpleMatcher.new(name: name, service: service, resource: resource, tags: tags), sampler, provenance)
|
73
80
|
end
|
74
81
|
end
|
75
82
|
end
|
@@ -65,6 +65,12 @@ module Datadog
|
|
65
65
|
resource: rule['resource'],
|
66
66
|
tags: rule['tags'],
|
67
67
|
sample_rate: sample_rate,
|
68
|
+
provenance: if (provenance = rule['provenance'])
|
69
|
+
# `Rule::PROVENANCE_*` values are symbols, so convert strings to match
|
70
|
+
provenance.to_sym
|
71
|
+
else
|
72
|
+
Rule::PROVENANCE_LOCAL
|
73
|
+
end,
|
68
74
|
}
|
69
75
|
|
70
76
|
kwargs.compact!
|
@@ -118,7 +124,17 @@ module Datadog
|
|
118
124
|
rate_limiter.allow?(1).tap do |allowed|
|
119
125
|
set_priority(trace, allowed)
|
120
126
|
set_limiter_metrics(trace, rate_limiter.effective_rate)
|
121
|
-
|
127
|
+
|
128
|
+
provenance = case rule.provenance
|
129
|
+
when Rule::PROVENANCE_REMOTE_USER
|
130
|
+
Ext::Decision::REMOTE_USER_RULE
|
131
|
+
when Rule::PROVENANCE_REMOTE_DYNAMIC
|
132
|
+
Ext::Decision::REMOTE_DYNAMIC_RULE
|
133
|
+
else
|
134
|
+
Ext::Decision::TRACE_SAMPLING_RULE
|
135
|
+
end
|
136
|
+
|
137
|
+
trace.set_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, provenance)
|
122
138
|
end
|
123
139
|
rescue StandardError => e
|
124
140
|
Datadog.logger.error(
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../matcher'
|
4
|
+
|
3
5
|
module Datadog
|
4
6
|
module Tracing
|
5
7
|
module Sampling
|
@@ -31,29 +33,19 @@ module Datadog
|
|
31
33
|
# @param name_pattern [String] a pattern to be matched against {SpanOperation#name}
|
32
34
|
# @param service_pattern [String] a pattern to be matched against {SpanOperation#service}
|
33
35
|
def initialize(name_pattern: MATCH_ALL_PATTERN, service_pattern: MATCH_ALL_PATTERN)
|
34
|
-
@name =
|
35
|
-
@service =
|
36
|
+
@name = Sampling::Matcher.glob_to_regex(name_pattern)
|
37
|
+
@service = Sampling::Matcher.glob_to_regex(service_pattern)
|
36
38
|
end
|
37
39
|
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
#
|
46
|
-
|
47
|
-
def match?(span)
|
48
|
-
# Matching is performed at the end of the lifecycle of a Span,
|
49
|
-
# thus both `name` and `service` are guaranteed to be not `nil`.
|
50
|
-
@name.match?(span.name) && @service.match?(span.service)
|
51
|
-
end
|
52
|
-
else
|
53
|
-
# DEV: Remove when support for Ruby 2.3 and older is removed.
|
54
|
-
def match?(span)
|
55
|
-
@name === span.name && @service === span.service
|
56
|
-
end
|
40
|
+
# Returns `true` if the span conforms to the configured patterns,
|
41
|
+
# `false` otherwise
|
42
|
+
#
|
43
|
+
# @param [SpanOperation] span
|
44
|
+
# @return [Boolean]
|
45
|
+
def match?(span)
|
46
|
+
# Matching is performed at the end of the lifecycle of a Span,
|
47
|
+
# thus both `name` and `service` are guaranteed to be not `nil`.
|
48
|
+
@name.match?(span.name) && @service.match?(span.service)
|
57
49
|
end
|
58
50
|
|
59
51
|
def ==(other)
|
@@ -62,26 +54,6 @@ module Datadog
|
|
62
54
|
name == other.name &&
|
63
55
|
service == other.service
|
64
56
|
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
# @param pattern [String]
|
69
|
-
# @return [Regexp]
|
70
|
-
def pattern_to_regex(pattern)
|
71
|
-
# Ensure no undesired characters are treated as regex.
|
72
|
-
# Our valid special characters, `?` and `*`,
|
73
|
-
# will be escaped so...
|
74
|
-
pattern = Regexp.quote(pattern)
|
75
|
-
|
76
|
-
# ...we account for that here:
|
77
|
-
pattern.gsub!('\?', '.') # Any single character
|
78
|
-
pattern.gsub!('\*', '.*') # Any substring
|
79
|
-
|
80
|
-
# Patterns have to match the whole input string
|
81
|
-
pattern = "\\A#{pattern}\\z"
|
82
|
-
|
83
|
-
Regexp.new(pattern)
|
84
|
-
end
|
85
57
|
end
|
86
58
|
end
|
87
59
|
end
|
@@ -41,13 +41,19 @@ module Datadog
|
|
41
41
|
attr_reader :dropped_attributes
|
42
42
|
|
43
43
|
def initialize(
|
44
|
-
|
45
|
-
|
44
|
+
digest,
|
45
|
+
attributes: nil
|
46
46
|
)
|
47
|
-
@span_id = digest
|
48
|
-
@trace_id = digest
|
49
|
-
@trace_flags = digest
|
50
|
-
|
47
|
+
@span_id = digest.span_id
|
48
|
+
@trace_id = digest.trace_id
|
49
|
+
@trace_flags = if digest.trace_sampling_priority.nil?
|
50
|
+
nil
|
51
|
+
elsif digest.trace_sampling_priority > 0
|
52
|
+
1
|
53
|
+
else
|
54
|
+
0
|
55
|
+
end
|
56
|
+
@trace_state = digest.trace_state && digest.trace_state.dup
|
51
57
|
@dropped_attributes = 0
|
52
58
|
@attributes = (attributes && attributes.dup) || {}
|
53
59
|
end
|
@@ -35,9 +35,7 @@ module Datadog
|
|
35
35
|
:start_time,
|
36
36
|
:trace_id,
|
37
37
|
:type
|
38
|
-
|
39
|
-
attr_accessor \
|
40
|
-
:status
|
38
|
+
attr_accessor :links, :status
|
41
39
|
|
42
40
|
def initialize(
|
43
41
|
name,
|
@@ -49,7 +47,8 @@ module Datadog
|
|
49
47
|
start_time: nil,
|
50
48
|
tags: nil,
|
51
49
|
trace_id: nil,
|
52
|
-
type: nil
|
50
|
+
type: nil,
|
51
|
+
links: nil
|
53
52
|
)
|
54
53
|
# Ensure dynamically created strings are UTF-8 encoded.
|
55
54
|
#
|
@@ -66,6 +65,8 @@ module Datadog
|
|
66
65
|
@trace_id = trace_id || Tracing::Utils::TraceId.next_id
|
67
66
|
|
68
67
|
@status = 0
|
68
|
+
# stores array of span links
|
69
|
+
@links = links || []
|
69
70
|
|
70
71
|
# start_time and end_time track wall clock. In Ruby, wall clock
|
71
72
|
# has less accuracy than monotonic clock, so if possible we look to only use wall clock
|
@@ -452,6 +453,7 @@ module Datadog
|
|
452
453
|
status: @status,
|
453
454
|
type: @type,
|
454
455
|
trace_id: @trace_id,
|
456
|
+
links: @links,
|
455
457
|
service_entry: parent.nil? || (service && parent.service != service)
|
456
458
|
)
|
457
459
|
end
|
data/lib/datadog/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datadog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 9.0.0.1.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 9.0.0.1.0
|
69
69
|
description: |
|
70
70
|
datadog is Datadog's client library for Ruby. It includes a suite of tools
|
71
71
|
which provide visibility into the performance and security of Ruby applications,
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- ext/datadog_profiling_native_extension/collectors_stack.h
|
107
107
|
- ext/datadog_profiling_native_extension/collectors_thread_context.c
|
108
108
|
- ext/datadog_profiling_native_extension/collectors_thread_context.h
|
109
|
+
- ext/datadog_profiling_native_extension/crashtracker.c
|
109
110
|
- ext/datadog_profiling_native_extension/extconf.rb
|
110
111
|
- ext/datadog_profiling_native_extension/heap_recorder.c
|
111
112
|
- ext/datadog_profiling_native_extension/heap_recorder.h
|
@@ -351,6 +352,7 @@ files:
|
|
351
352
|
- lib/datadog/profiling/collectors/stack.rb
|
352
353
|
- lib/datadog/profiling/collectors/thread_context.rb
|
353
354
|
- lib/datadog/profiling/component.rb
|
355
|
+
- lib/datadog/profiling/crashtracker.rb
|
354
356
|
- lib/datadog/profiling/exporter.rb
|
355
357
|
- lib/datadog/profiling/ext.rb
|
356
358
|
- lib/datadog/profiling/ext/forking.rb
|
@@ -856,7 +858,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
856
858
|
- !ruby/object:Gem::Version
|
857
859
|
version: 2.0.0
|
858
860
|
requirements: []
|
859
|
-
rubygems_version: 3.4.
|
861
|
+
rubygems_version: 3.4.10
|
860
862
|
signing_key:
|
861
863
|
specification_version: 4
|
862
864
|
summary: Datadog tracing code for your Ruby applications
|