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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bef2da14245890c8187ebffd9cce972da89a177a806c6991f2e3050e1de62bc3
4
- data.tar.gz: d37dcaf645e16177c6f7a3dd77628f2e5a4920c45fca8e3f78665c34a4d76db2
3
+ metadata.gz: 000f0860f13e54bd5d4e0e2d0c4803eb8c568e808379f6ad58b9c9132c03562e
4
+ data.tar.gz: 26433871947470f4ba39de8b0790385a7dd3e7d8ff6e04aa28aff717ec81a490
5
5
  SHA512:
6
- metadata.gz: c59d7c5b2f363eb96f78ad602489ccbd0ed94ae9d6e856c70272ddb21ba467255179814db1831518789b7c32e9ab5d0f13421dd67ea585d0b39fe78849bcfe81
7
- data.tar.gz: 97dcba8ee6eda7c3cafdb39946863d337ef67843ac7f071890ce6253786b9d9a26ca8a9f181a8c0dad44c01a3ffab53c146ea4848b6497552d26558f9f1278ce
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', '= 0.10.12'
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
@@ -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 ` on Microsoft Windows is currently unsupported. We'll still accept community contributions and issues,
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 exist on their systems.
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 "rb_mjit_min_header-#{RUBY_VERSION}.h"
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
- FORM_FIELD_DATA = 'data[0]'.freeze
27
- FORM_FIELD_FORMAT = 'format'.freeze
28
- FORM_FIELD_FORMAT_PPROF = 'pprof'.freeze
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
- FORM_FIELD_TYPES = 'types[0]'.freeze
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
- PPROF_DEFAULT_FILENAME = 'profile.pb.gz'.freeze
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
@@ -88,10 +88,6 @@ module Datadog
88
88
  collect_and_wait
89
89
  end
90
90
 
91
- def loop_back_off?
92
- false
93
- end
94
-
95
91
  def collect_and_wait
96
92
  run_time = Datadog::Utils::Time.measure do
97
93
  collect_events
@@ -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, types = build_pprof(flush)
44
+ pprof_file = build_pprof(flush)
45
45
 
46
46
  form = {
47
- # NOTE: Redundant w/ 'runtime-id' tag below; may want to remove this later.
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
- FORM_FIELD_DATA => pprof_file,
68
- FORM_FIELD_RUNTIME => flush.language,
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
- # Wrap pprof as a gzipped file
87
- gzipped_data = Datadog::Utils::Compression.gzip(pprof.data)
88
- pprof_file = Datadog::Vendor::Multipart::Post::UploadIO.new(
89
- StringIO.new(gzipped_data),
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
@@ -3,7 +3,7 @@ module Datadog
3
3
  module VERSION
4
4
  MAJOR = 0
5
5
  MINOR = 54
6
- PATCH = 1
6
+ PATCH = 2
7
7
  PRE = nil
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
@@ -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.
@@ -1,6 +1,6 @@
1
1
  # typed: false
2
2
  require 'ddtrace/workers/async'
3
- require 'ddtrace/workers/loop'
3
+ require 'ddtrace/workers/interval_loop'
4
4
 
5
5
  module Datadog
6
6
  module Workers
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.1
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: 2021-12-01 00:00:00.000000000 Z
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.12
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.12
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/loop.rb
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