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