ddtrace 0.54.1 → 0.54.2
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 +21 -0
- data/ddtrace.gemspec +1 -1
- data/docs/GettingStarted.md +5 -1
- data/ext/ddtrace_profiling_native_extension/extconf.rb +39 -8
- data/lib/ddtrace/ext/profiling.rb +6 -10
- data/lib/ddtrace/profiling/collectors/stack.rb +0 -4
- data/lib/ddtrace/profiling/scheduler.rb +20 -4
- data/lib/ddtrace/profiling/transport/http/api/endpoint.rb +8 -15
- data/lib/ddtrace/version.rb +1 -1
- data/lib/ddtrace/workers/{loop.rb → interval_loop.rb} +0 -16
- data/lib/ddtrace/workers/polling.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 000f0860f13e54bd5d4e0e2d0c4803eb8c568e808379f6ad58b9c9132c03562e
|
4
|
+
data.tar.gz: 26433871947470f4ba39de8b0790385a7dd3e7d8ff6e04aa28aff717ec81a490
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f2282c9f65efc83c4b815f64f51cb352adb443ca059b6fbeed921a8db83bd0f076060b190ff2a41e024a77599e80b7e2fdbc0a53c0f701a799f0541a53a64cc
|
7
|
+
data.tar.gz: aa4c8ef2ab73071bd1e58c367d300799483aac3c79e1fee3483bc917316da1cd49fae8a999f4a2c0dfc4a7b081478bd872ca2b6fbfe812f07f6bfa7329de304b
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,22 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [0.54.2] - 2022-01-18
|
6
|
+
|
7
|
+
Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.54.2
|
8
|
+
|
9
|
+
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.54.1...v0.54.2
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
- Bump `debase-ruby_core_source` dependency version; also allow older versions to be used ([#1798][], [#1829][])
|
14
|
+
- Profiler: Reduce impact of reporting data in multi-process applications ([#1807][])
|
15
|
+
- Profiler: Update API used to report data to backend ([#1820][])
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
|
19
|
+
- Gracefully handle installation on environments where Ruby JIT seems to be available but is actually broken ([#1801][])
|
20
|
+
|
5
21
|
## [0.54.1] - 2021-11-30
|
6
22
|
|
7
23
|
Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.54.1
|
@@ -2682,6 +2698,11 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2682
2698
|
[#1771]: https://github.com/DataDog/dd-trace-rb/issues/1771
|
2683
2699
|
[#1774]: https://github.com/DataDog/dd-trace-rb/issues/1774
|
2684
2700
|
[#1776]: https://github.com/DataDog/dd-trace-rb/issues/1776
|
2701
|
+
[#1798]: https://github.com/DataDog/dd-trace-rb/issues/1798
|
2702
|
+
[#1801]: https://github.com/DataDog/dd-trace-rb/issues/1801
|
2703
|
+
[#1807]: https://github.com/DataDog/dd-trace-rb/issues/1807
|
2704
|
+
[#1820]: https://github.com/DataDog/dd-trace-rb/issues/1820
|
2705
|
+
[#1829]: https://github.com/DataDog/dd-trace-rb/issues/1829
|
2685
2706
|
[@AdrianLC]: https://github.com/AdrianLC
|
2686
2707
|
[@Azure7111]: https://github.com/Azure7111
|
2687
2708
|
[@BabyGroot]: https://github.com/BabyGroot
|
data/ddtrace.gemspec
CHANGED
@@ -50,7 +50,7 @@ Gem::Specification.new do |spec|
|
|
50
50
|
#
|
51
51
|
# Because we only use this for older Rubies, and we consider it "feature-complete" for those older Rubies,
|
52
52
|
# we're pinning it at the latest available version and will manually bump the dependency as needed.
|
53
|
-
spec.add_dependency 'debase-ruby_core_source', '
|
53
|
+
spec.add_dependency 'debase-ruby_core_source', '<= 0.10.14'
|
54
54
|
|
55
55
|
spec.extensions = ['ext/ddtrace_profiling_native_extension/extconf.rb']
|
56
56
|
end
|
data/docs/GettingStarted.md
CHANGED
@@ -135,9 +135,13 @@ To contribute, check out the [contribution guidelines][contribution docs] and [d
|
|
135
135
|
|
136
136
|
*EOL* indicates support is no longer provided.
|
137
137
|
|
138
|
+
### Apple macOS support
|
139
|
+
|
140
|
+
Use of `ddtrace` on macOS is supported for development, but not for production deployments.
|
141
|
+
|
138
142
|
### Microsoft Windows support
|
139
143
|
|
140
|
-
Using `ddtrace
|
144
|
+
Using `ddtrace` on Microsoft Windows is currently unsupported. We'll still accept community contributions and issues,
|
141
145
|
but will consider them as having low priority.
|
142
146
|
|
143
147
|
## Installation
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# typed: ignore
|
2
|
+
# rubocop:disable Style/StderrPuts
|
2
3
|
|
3
4
|
# Older Rubies don't have the MJIT header, used by the JIT compiler, so we need to use a different approach
|
4
5
|
CAN_USE_MJIT_HEADER = RUBY_VERSION >= '2.6'
|
@@ -26,7 +27,6 @@ def expected_to_use_mjit_but_mjit_is_disabled?
|
|
26
27
|
mjit_disabled = CAN_USE_MJIT_HEADER && RbConfig::CONFIG['MJIT_SUPPORT'] != 'yes'
|
27
28
|
|
28
29
|
if mjit_disabled
|
29
|
-
# rubocop:disable Style/StderrPuts
|
30
30
|
$stderr.puts(%(
|
31
31
|
+------------------------------------------------------------------------------+
|
32
32
|
| Your Ruby has been compiled without JIT support (--disable-jit-support). |
|
@@ -55,11 +55,16 @@ def skip_building_extension?
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# IMPORTANT: When adding flags, remember that our customers compile with a wide range of gcc/clang versions, so
|
58
|
-
# doublecheck that what you're adding can be reasonably expected to
|
58
|
+
# doublecheck that what you're adding can be reasonably expected to work on their systems.
|
59
59
|
def add_compiler_flag(flag)
|
60
60
|
$CFLAGS << ' ' << flag
|
61
61
|
end
|
62
62
|
|
63
|
+
def skip_building_extension!
|
64
|
+
File.write('Makefile', 'all install clean: # dummy makefile that does nothing')
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
|
63
68
|
if skip_building_extension?
|
64
69
|
$stderr.puts(%(
|
65
70
|
+------------------------------------------------------------------------------+
|
@@ -68,14 +73,12 @@ if skip_building_extension?
|
|
68
73
|
+------------------------------------------------------------------------------+
|
69
74
|
|
70
75
|
))
|
71
|
-
|
72
|
-
File.write('Makefile', 'all install clean: # dummy makefile that does nothing')
|
73
|
-
return
|
76
|
+
skip_building_extension!
|
74
77
|
end
|
75
78
|
|
76
79
|
$stderr.puts(%(
|
77
80
|
+------------------------------------------------------------------------------+
|
78
|
-
| **Preparing to build the ddtrace native extension
|
81
|
+
| ** Preparing to build the ddtrace native extension... ** |
|
79
82
|
| |
|
80
83
|
| If you run into any failures during this step, you can set the |
|
81
84
|
| `DD_PROFILING_NO_EXTENSION` environment variable to `true` e.g. |
|
@@ -90,7 +93,6 @@ $stderr.puts(%(
|
|
90
93
|
+------------------------------------------------------------------------------+
|
91
94
|
|
92
95
|
))
|
93
|
-
# rubocop:enable Style/StderrPuts
|
94
96
|
|
95
97
|
# NOTE: we MUST NOT require 'mkmf' before we check the #skip_building_extension? because the require triggers checks
|
96
98
|
# that may fail on an environment not properly setup for building Ruby extensions.
|
@@ -124,6 +126,34 @@ end
|
|
124
126
|
EXTENSION_NAME = "ddtrace_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}".freeze
|
125
127
|
|
126
128
|
if CAN_USE_MJIT_HEADER
|
129
|
+
mjit_header_file_name = "rb_mjit_min_header-#{RUBY_VERSION}.h"
|
130
|
+
|
131
|
+
# Validate that the mjit header can actually be compiled on this system. We learned via
|
132
|
+
# https://github.com/DataDog/dd-trace-rb/issues/1799 and https://github.com/DataDog/dd-trace-rb/issues/1792
|
133
|
+
# that even if the header seems to exist, it may not even compile.
|
134
|
+
# `have_macro` actually tries to compile a file that mentions the given macro, so if this passes, we should be good to
|
135
|
+
# use the MJIT header.
|
136
|
+
# Finally, the `COMMON_HEADERS` conflict with the MJIT header so we need to temporarily disable them for this check.
|
137
|
+
original_common_headers = MakeMakefile::COMMON_HEADERS
|
138
|
+
MakeMakefile::COMMON_HEADERS = ''.freeze
|
139
|
+
unless have_macro('RUBY_MJIT_H', mjit_header_file_name)
|
140
|
+
$stderr.puts(%(
|
141
|
+
+------------------------------------------------------------------------------+
|
142
|
+
| WARNING: Unable to compile a needed component for ddtrace native extension. |
|
143
|
+
| Your C compiler or Ruby VM just-in-time compiler seems to be broken. |
|
144
|
+
| |
|
145
|
+
| You will be NOT be able to use ddtrace profiling features, |
|
146
|
+
| but all other features will work fine! |
|
147
|
+
| |
|
148
|
+
| For help solving this issue, please contact Datadog support at |
|
149
|
+
| <https://docs.datadoghq.com/help/>. |
|
150
|
+
+------------------------------------------------------------------------------+
|
151
|
+
|
152
|
+
))
|
153
|
+
skip_building_extension!
|
154
|
+
end
|
155
|
+
MakeMakefile::COMMON_HEADERS = original_common_headers
|
156
|
+
|
127
157
|
$defs << '-DUSE_MJIT_HEADER'
|
128
158
|
|
129
159
|
# NOTE: This needs to come after all changes to $defs
|
@@ -136,7 +166,7 @@ if CAN_USE_MJIT_HEADER
|
|
136
166
|
File.read($extconf_h)
|
137
167
|
.sub('#endif',
|
138
168
|
<<-EXTCONF_H.strip
|
139
|
-
#define RUBY_MJIT_HEADER "
|
169
|
+
#define RUBY_MJIT_HEADER "#{mjit_header_file_name}"
|
140
170
|
|
141
171
|
#endif
|
142
172
|
EXTCONF_H
|
@@ -164,3 +194,4 @@ else
|
|
164
194
|
Debase::RubyCoreSource
|
165
195
|
.create_makefile_with_core(proc { have_header('vm_core.h') && thread_native_for_ruby_2_1.call }, EXTENSION_NAME)
|
166
196
|
end
|
197
|
+
# rubocop:enable Style/StderrPuts
|
@@ -23,13 +23,9 @@ module Datadog
|
|
23
23
|
module HTTP
|
24
24
|
URI_TEMPLATE_DD_API = 'https://intake.profile.%s/'.freeze
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
FORM_FIELD_RECORDING_END = 'recording-end'.freeze
|
30
|
-
FORM_FIELD_RECORDING_START = 'recording-start'.freeze
|
31
|
-
FORM_FIELD_RUNTIME = 'runtime'.freeze
|
32
|
-
FORM_FIELD_RUNTIME_ID = 'runtime-id'.freeze
|
26
|
+
FORM_FIELD_RECORDING_START = 'start'.freeze
|
27
|
+
FORM_FIELD_RECORDING_END = 'end'.freeze
|
28
|
+
FORM_FIELD_FAMILY = 'family'.freeze
|
33
29
|
FORM_FIELD_TAG_ENV = 'env'.freeze
|
34
30
|
FORM_FIELD_TAG_HOST = 'host'.freeze
|
35
31
|
FORM_FIELD_TAG_LANGUAGE = 'language'.freeze
|
@@ -43,13 +39,13 @@ module Datadog
|
|
43
39
|
FORM_FIELD_TAG_SERVICE = 'service'.freeze
|
44
40
|
FORM_FIELD_TAG_VERSION = 'version'.freeze
|
45
41
|
FORM_FIELD_TAGS = 'tags'.freeze
|
46
|
-
|
47
|
-
FORM_FIELD_TYPES_AUTO = 'auto'.freeze
|
42
|
+
FORM_FIELD_INTAKE_VERSION = 'version'.freeze
|
48
43
|
|
49
44
|
HEADER_CONTENT_TYPE = 'Content-Type'.freeze
|
50
45
|
HEADER_CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream'.freeze
|
51
46
|
|
52
|
-
|
47
|
+
FORM_FIELD_PPROF_DATA = 'data[rubyprofile.pprof]'.freeze
|
48
|
+
PPROF_DEFAULT_FILENAME = 'rubyprofile.pprof.gz'.freeze
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
@@ -17,6 +17,10 @@ module Datadog
|
|
17
17
|
# Profiles with duration less than this will not be reported
|
18
18
|
PROFILE_DURATION_THRESHOLD_SECONDS = 1
|
19
19
|
|
20
|
+
# We sleep for at most this duration seconds before reporting data to avoid multi-process applications all
|
21
|
+
# reporting profiles at the exact same time
|
22
|
+
DEFAULT_FLUSH_JITTER_MAXIMUM_SECONDS = 3
|
23
|
+
|
20
24
|
private_constant :DEFAULT_INTERVAL_SECONDS, :MINIMUM_INTERVAL_SECONDS, :PROFILE_DURATION_THRESHOLD_SECONDS
|
21
25
|
|
22
26
|
attr_reader \
|
@@ -62,10 +66,6 @@ module Datadog
|
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
65
|
-
def loop_back_off?
|
66
|
-
false
|
67
|
-
end
|
68
|
-
|
69
69
|
def after_fork
|
70
70
|
# Clear recorder's buffers by flushing events.
|
71
71
|
# Objects from parent process will copy-on-write,
|
@@ -110,6 +110,22 @@ module Datadog
|
|
110
110
|
return flush
|
111
111
|
end
|
112
112
|
|
113
|
+
# Sleep for a bit to cause misalignment between profilers in multi-process applications
|
114
|
+
#
|
115
|
+
# When not being run in a loop, it means the scheduler has not been started or was stopped, and thus
|
116
|
+
# a) it's being shutting down (and is trying to report the last profile)
|
117
|
+
# b) it's being run as a one-shot, usually in a test
|
118
|
+
# ...so in those cases we don't sleep
|
119
|
+
#
|
120
|
+
# During PR review (https://github.com/DataDog/dd-trace-rb/pull/1807) we discussed the possible alternative of
|
121
|
+
# just sleeping before starting the scheduler loop. We ended up not going with that option to avoid the first
|
122
|
+
# profile containing up to DEFAULT_INTERVAL_SECONDS + DEFAULT_FLUSH_JITTER_MAXIMUM_SECONDS instead of the
|
123
|
+
# usual DEFAULT_INTERVAL_SECONDS size.
|
124
|
+
if run_loop?
|
125
|
+
jitter_seconds = rand * DEFAULT_FLUSH_JITTER_MAXIMUM_SECONDS # floating point number between (0.0...maximum)
|
126
|
+
sleep(jitter_seconds)
|
127
|
+
end
|
128
|
+
|
113
129
|
# Send events to each exporter
|
114
130
|
if flush.event_count > 0
|
115
131
|
exporters.each do |exporter|
|
@@ -41,11 +41,10 @@ module Datadog
|
|
41
41
|
|
42
42
|
def build_form(env)
|
43
43
|
flush = env.request.parcel.data
|
44
|
-
pprof_file
|
44
|
+
pprof_file = build_pprof(flush)
|
45
45
|
|
46
46
|
form = {
|
47
|
-
|
48
|
-
FORM_FIELD_RUNTIME_ID => flush.runtime_id,
|
47
|
+
FORM_FIELD_INTAKE_VERSION => '3', # Aka 1.3 intake format
|
49
48
|
FORM_FIELD_RECORDING_START => flush.start.utc.iso8601,
|
50
49
|
FORM_FIELD_RECORDING_END => flush.finish.utc.iso8601,
|
51
50
|
FORM_FIELD_TAGS => [
|
@@ -64,14 +63,10 @@ module Datadog
|
|
64
63
|
.reject { |tag_key| TAGS_TO_IGNORE_IN_TAGS_HASH.include?(tag_key) }
|
65
64
|
.map { |tag_key, tag_value| "#{tag_key}:#{tag_value}" }
|
66
65
|
],
|
67
|
-
|
68
|
-
|
69
|
-
FORM_FIELD_FORMAT => FORM_FIELD_FORMAT_PPROF
|
66
|
+
FORM_FIELD_PPROF_DATA => pprof_file,
|
67
|
+
FORM_FIELD_FAMILY => flush.language,
|
70
68
|
}
|
71
69
|
|
72
|
-
# Add types
|
73
|
-
form[FORM_FIELD_TYPES] = types.join(',')
|
74
|
-
|
75
70
|
# Optional fields
|
76
71
|
form[FORM_FIELD_TAGS] << "#{FORM_FIELD_TAG_SERVICE}:#{flush.service}" unless flush.service.nil?
|
77
72
|
form[FORM_FIELD_TAGS] << "#{FORM_FIELD_TAG_ENV}:#{flush.env}" unless flush.env.nil?
|
@@ -83,15 +78,13 @@ module Datadog
|
|
83
78
|
def build_pprof(flush)
|
84
79
|
pprof = encoder.encode(flush)
|
85
80
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
StringIO.new(
|
81
|
+
gzipped_pprof_data = Datadog::Utils::Compression.gzip(pprof.data)
|
82
|
+
|
83
|
+
Datadog::Vendor::Multipart::Post::UploadIO.new(
|
84
|
+
StringIO.new(gzipped_pprof_data),
|
90
85
|
HEADER_CONTENT_TYPE_OCTET_STREAM,
|
91
86
|
PPROF_DEFAULT_FILENAME
|
92
87
|
)
|
93
|
-
|
94
|
-
[pprof_file, [FORM_FIELD_TYPES_AUTO]]
|
95
88
|
end
|
96
89
|
end
|
97
90
|
end
|
data/lib/ddtrace/version.rb
CHANGED
@@ -60,15 +60,6 @@ module Datadog
|
|
60
60
|
@loop_wait_time = value
|
61
61
|
end
|
62
62
|
|
63
|
-
def reset_loop_wait_time
|
64
|
-
self.loop_wait_time = loop_base_interval
|
65
|
-
end
|
66
|
-
|
67
|
-
# Should the loop "back off" when there's no work?
|
68
|
-
def loop_back_off?
|
69
|
-
false
|
70
|
-
end
|
71
|
-
|
72
63
|
def loop_back_off!
|
73
64
|
self.loop_wait_time = [loop_wait_time * BACK_OFF_RATIO, BACK_OFF_MAX].min
|
74
65
|
end
|
@@ -106,13 +97,6 @@ module Datadog
|
|
106
97
|
# There's work to do...
|
107
98
|
# Run the task
|
108
99
|
yield
|
109
|
-
|
110
|
-
# Reset the wait interval
|
111
|
-
reset_loop_wait_time if loop_back_off?
|
112
|
-
elsif loop_back_off?
|
113
|
-
# There's no work to do...
|
114
|
-
# Back off the wait interval a bit
|
115
|
-
loop_back_off!
|
116
100
|
end
|
117
101
|
|
118
102
|
# Wait for an interval, unless shutdown has been signaled.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddtrace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.54.
|
4
|
+
version: 0.54.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: debase-ruby_core_source
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - "<="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.10.
|
33
|
+
version: 0.10.14
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - "<="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.10.
|
40
|
+
version: 0.10.14
|
41
41
|
description: |
|
42
42
|
ddtrace is Datadog’s tracing client for Ruby. It is used to trace requests
|
43
43
|
as they flow across web servers, databases and microservices so that developers
|
@@ -611,7 +611,7 @@ files:
|
|
611
611
|
- lib/ddtrace/worker.rb
|
612
612
|
- lib/ddtrace/workers.rb
|
613
613
|
- lib/ddtrace/workers/async.rb
|
614
|
-
- lib/ddtrace/workers/
|
614
|
+
- lib/ddtrace/workers/interval_loop.rb
|
615
615
|
- lib/ddtrace/workers/polling.rb
|
616
616
|
- lib/ddtrace/workers/queue.rb
|
617
617
|
- lib/ddtrace/workers/runtime_metrics.rb
|