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 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