ddtrace 1.11.0.beta1 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -1
  3. data/README.md +0 -1
  4. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +34 -7
  5. data/lib/datadog/appsec/component.rb +1 -1
  6. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -3
  7. data/lib/datadog/core/configuration/agent_settings_resolver.rb +62 -11
  8. data/lib/datadog/core/configuration/settings.rb +5 -6
  9. data/lib/datadog/core/environment/identity.rb +56 -0
  10. data/lib/datadog/core/remote/client.rb +98 -19
  11. data/lib/datadog/core/remote/component.rb +29 -21
  12. data/lib/datadog/core/remote/configuration/content.rb +2 -0
  13. data/lib/datadog/core/remote/configuration/repository.rb +15 -1
  14. data/lib/datadog/core/remote/configuration/target.rb +5 -3
  15. data/lib/datadog/core/remote/negotiation.rb +57 -0
  16. data/lib/datadog/core/transport/http/negotiation.rb +1 -1
  17. data/lib/datadog/core/workers/async.rb +6 -2
  18. data/lib/datadog/core/workers/interval_loop.rb +5 -1
  19. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +6 -1
  20. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +4 -1
  21. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +4 -2
  22. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -1
  23. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +6 -1
  24. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -1
  25. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +6 -1
  26. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +4 -1
  27. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +6 -1
  28. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +5 -3
  29. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +4 -2
  30. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +6 -1
  31. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -2
  32. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +6 -1
  33. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -2
  34. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +6 -1
  35. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +5 -2
  36. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +6 -1
  37. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -2
  38. data/lib/datadog/tracing/contrib/sidekiq/integration.rb +8 -0
  39. data/lib/datadog/tracing/contrib/sidekiq/patcher.rb +14 -2
  40. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/heartbeat.rb +9 -4
  41. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/stop.rb +34 -0
  42. data/lib/ddtrace/version.rb +4 -2
  43. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83276ed5293cf8971f19f7a1fb1198e01f5ff8d48d3dd440deff0ef3518939d6
4
- data.tar.gz: 12d22b6020e8830c91b2f68aed9ce03a2d201eafc4911c0a95171df6480cf754
3
+ metadata.gz: bf1177aae94a3724758e48ce461638de0a4b75956c8c1318251f2b568de28c5d
4
+ data.tar.gz: f42454cd32ff7eaf91c7beda1e6ff8a99726efddc8e01fdb4797b4f115c29df4
5
5
  SHA512:
6
- metadata.gz: 4d4f7fb37bd10399053c026ff92545c5a1d600447cb94b3b35439fb37008154687c09f1834115afe4ed5cddc55fe84b458db955fcd4dbd0140444ffdaa01f8a9
7
- data.tar.gz: 39d5ac62e456654550f70989e18dd3b122d3167aefc4a6b55ed5dc2ffd22c8f2b51c2f8261b2e4c009310acc2001be1a8f6ab6b0651850a45cc49cf0319ba6b1
6
+ metadata.gz: 5d5787eb9f073043151922af478a75affcfe8f2a9723fbe6c8e0561be6c7f95c700c91e1f4ca10401e018f1587f0289b1720d5c38e2cccdb80f7fcffd7eba0ba
7
+ data.tar.gz: 5f9d0adcfc38de9d60c51a46360ce60351228db21cabd07dc176a99f4bf77f80b0cc8f12dbe844ea3ae88f2384174158415a28de3e6adc1b6b54e56be1186665
data/CHANGELOG.md CHANGED
@@ -2,6 +2,52 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.11.0] - 2023-04-27
6
+
7
+ ### Highlights
8
+
9
+ As of ddtrace 1.11.0, these features are GA and emabled by default:
10
+
11
+ - CPU Profiling 2.0
12
+ - Remote Configuration
13
+ - Telemetry
14
+
15
+ For more details, check the release notes.
16
+
17
+ ### Added
18
+
19
+ * Add remote configuration, enabled by default ([#2674][], [#2678][], [#2686][], [#2687][], [#2688][], [#2689][], [#2696][], [#2705][], [#2731][], [#2732][], [#2733][], [#2739][], [#2756][], [#2769][], [#2771][], [#2773][], [#2789][], [#2805][], [#2794][])
20
+ * AppSec: Add response headers passing to WAF ([#2701][])
21
+ * Tracing: Distributed tracing for Sidekiq ([#2513][])
22
+ * Tracing: Add Roda integration ([#2368][])
23
+ * Profiling: Support disabling endpoint names collection in new profiler ([#2698][])
24
+ * Tracing: Support Sidekiq 7 ([#2810][])
25
+ * Core: Add support for Unix Domain Socket (UDS) configuration via `DD_TRACE_AGENT_URL` ([#2806][])
26
+ * Core: Enable Telemetry by default ([#2762][])
27
+
28
+ ### Changed
29
+
30
+ * Core: Allow `1` as true value in environment variables ([#2710][])
31
+ * Profiling: Enable CPU Profiling 2.0 by default ([#2702][])
32
+ * Tracing: Improve controller instrumentation and deprecate option `exception_controller` ([#2726][])
33
+ * Tracing: Implement Span Attribute Schema Environment Variable ([#2727][])
34
+ * Tracing: Change default `service_name` values (gated by feature flag) ([#2760][])
35
+
36
+ ### Fixed
37
+
38
+ * Bug: Tracing: Fix w3c propagation special character handling ([#2720][])
39
+ * Performance: Tracing: Use `+@` instead of `dup` for duplicating strings ([#2704][])
40
+ * Profiling: Avoid triggering allocation sampling during sampling ([#2690][])
41
+ * Integrations: Tracing: Fix Rails < 3 conditional check in Utils#railtie_supported? ([#2695][])
42
+ * Profiling: Do not auto-enable new profiler when rugged gem is detected ([#2741][])
43
+ * Tracing: Fix using SemanticLogger#log(severity, message, progname) ([#2748][]) ([@rqz13][])
44
+ * Profiling: Improve detection of mysql2 gem incompatibilities with profiler ([#2770][])
45
+ * AppSec: Remove check for `::Rack::Request.instance_methods.include?(:each_header)` at load time ([#2778][])
46
+ * Tracing: Fix quadratic backtracking on invalid URI ([#2788][])
47
+ * Community: Correctly set mutex ([#2757][]) ([@ixti][])
48
+
49
+ Read the [full changeset](https://github.com/DataDog/dd-trace-rb/compare/v1.10.1...v1.11.0.beta1) and the release [milestone](https://github.com/DataDog/dd-trace-rb/milestone/121?closed=1).
50
+
5
51
  ## [1.11.0.beta1] - 2023-04-14
6
52
 
7
53
  As of ddtrace 1.11.0.beta1, CPU Profiling 2.0 is now GA and enabled by default. For more details, check the release notes.
@@ -2356,7 +2402,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
2356
2402
 
2357
2403
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
2358
2404
 
2359
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.11.0.beta1...master
2405
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.11.0...master
2406
+ [1.11.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.10.1...v1.11.0
2360
2407
  [1.11.0.beta1]: https://github.com/DataDog/dd-trace-rb/compare/v1.10.1...v1.11.0.beta1
2361
2408
  [1.10.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.10.0...v1.10.1
2362
2409
  [1.10.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.9.0...v1.10.0
@@ -3396,6 +3443,9 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3396
3443
  [#2741]: https://github.com/DataDog/dd-trace-rb/issues/2741
3397
3444
  [#2748]: https://github.com/DataDog/dd-trace-rb/issues/2748
3398
3445
  [#2756]: https://github.com/DataDog/dd-trace-rb/issues/2756
3446
+ [#2757]: https://github.com/DataDog/dd-trace-rb/issues/2757
3447
+ [#2760]: https://github.com/DataDog/dd-trace-rb/issues/2760
3448
+ [#2762]: https://github.com/DataDog/dd-trace-rb/issues/2762
3399
3449
  [#2769]: https://github.com/DataDog/dd-trace-rb/issues/2769
3400
3450
  [#2770]: https://github.com/DataDog/dd-trace-rb/issues/2770
3401
3451
  [#2771]: https://github.com/DataDog/dd-trace-rb/issues/2771
@@ -3403,6 +3453,10 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3403
3453
  [#2778]: https://github.com/DataDog/dd-trace-rb/issues/2778
3404
3454
  [#2788]: https://github.com/DataDog/dd-trace-rb/issues/2788
3405
3455
  [#2789]: https://github.com/DataDog/dd-trace-rb/issues/2789
3456
+ [#2794]: https://github.com/DataDog/dd-trace-rb/issues/2794
3457
+ [#2805]: https://github.com/DataDog/dd-trace-rb/issues/2805
3458
+ [#2806]: https://github.com/DataDog/dd-trace-rb/issues/2806
3459
+ [#2810]: https://github.com/DataDog/dd-trace-rb/issues/2810
3406
3460
  [@AdrianLC]: https://github.com/AdrianLC
3407
3461
  [@Azure7111]: https://github.com/Azure7111
3408
3462
  [@BabyGroot]: https://github.com/BabyGroot
@@ -3481,6 +3535,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3481
3535
  [@hs-bguven]: https://github.com/hs-bguven
3482
3536
  [@illdelph]: https://github.com/illdelph
3483
3537
  [@ioquatix]: https://github.com/ioquatix
3538
+ [@ixti]: https://github.com/ixti
3484
3539
  [@jamiehodge]: https://github.com/jamiehodge
3485
3540
  [@janz93]: https://github.com/janz93
3486
3541
  [@jeffjo]: https://github.com/jeffjo
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Datadog Trace Client
2
2
 
3
3
  [![Gem](https://img.shields.io/gem/v/ddtrace)](https://rubygems.org/gems/ddtrace/)
4
- [![CircleCI](https://circleci.com/gh/DataDog/dd-trace-rb/tree/master.svg?style=svg&circle-token=b0bd5ef866ec7f7b018f48731bb495f2d1372cc1)](https://circleci.com/gh/DataDog/dd-trace-rb/tree/master)
5
4
  [![codecov](https://codecov.io/gh/DataDog/dd-trace-rb/branch/master/graph/badge.svg)](https://app.codecov.io/gh/DataDog/dd-trace-rb/branch/master)
6
5
  [![YARD documentation](https://img.shields.io/badge/YARD-documentation-blue)][api docs]
7
6
 
@@ -118,6 +118,19 @@ struct cpu_and_wall_time_worker_state {
118
118
  unsigned int signal_handler_wrong_thread;
119
119
  // How many times we actually sampled (except GC samples)
120
120
  unsigned int sampled;
121
+ // How many times we skipped a sample because of the dynamic sampling rate mechanism
122
+ unsigned int skipped_sample_because_of_dynamic_sampling_rate;
123
+
124
+ // Stats for the results of calling rb_postponed_job_register_one
125
+ // The same function was already waiting to be executed
126
+ unsigned int postponed_job_skipped_already_existed;
127
+ // The function was added to the queue successfully
128
+ unsigned int postponed_job_success;
129
+ // The queue was full
130
+ unsigned int postponed_job_full;
131
+ // The function returned an unknown result code
132
+ unsigned int postponed_job_unknown_result;
133
+
121
134
  // Min/max/total wall-time spent sampling (except GC samples)
122
135
  uint64_t sampling_time_ns_min;
123
136
  uint64_t sampling_time_ns_max;
@@ -438,8 +451,20 @@ static void handle_sampling_signal(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED si
438
451
 
439
452
  // Note: If we ever want to get rid of rb_postponed_job_register_one, remember not to clobber Ruby exceptions, as
440
453
  // this function does this helpful job for us now -- https://github.com/ruby/ruby/commit/a98e343d39c4d7bf1e2190b076720f32d9f298b3.
441
- /*int result =*/ rb_postponed_job_register_one(0, sample_from_postponed_job, NULL);
442
- // TODO: Do something with result (potentially update tracking counters?)
454
+ int result = rb_postponed_job_register_one(0, sample_from_postponed_job, NULL);
455
+
456
+ // Officially, the result of rb_postponed_job_register_one is documented as being opaque, but in practice it does not
457
+ // seem to have changed between Ruby 2.3 and 3.2, and so we track it as a debugging mechanism
458
+ switch (result) {
459
+ case 0:
460
+ state->stats.postponed_job_full++; break;
461
+ case 1:
462
+ state->stats.postponed_job_success++; break;
463
+ case 2:
464
+ state->stats.postponed_job_skipped_already_existed++; break;
465
+ default:
466
+ state->stats.postponed_job_unknown_result++;
467
+ }
443
468
  }
444
469
 
445
470
  // The actual sampling trigger loop always runs **without** the global vm lock.
@@ -451,9 +476,6 @@ static void *run_sampling_trigger_loop(void *state_ptr) {
451
476
  while (atomic_load(&state->should_run)) {
452
477
  state->stats.trigger_sample_attempts++;
453
478
 
454
- // TODO: This is still a placeholder for a more complex mechanism. In particular:
455
- // * We want to do more than having a fixed sampling rate
456
-
457
479
  current_gvl_owner owner = gvl_owner();
458
480
  if (owner.valid) {
459
481
  // Note that reading the GVL owner and sending them a signal is a race -- the Ruby VM keeps on executing while
@@ -519,8 +541,8 @@ static VALUE rescued_sample_from_postponed_job(VALUE self_instance) {
519
541
 
520
542
  long wall_time_ns_before_sample = monotonic_wall_time_now_ns(RAISE_ON_FAILURE);
521
543
 
522
- if (!dynamic_sampling_rate_should_sample(&state->dynamic_sampling_rate, wall_time_ns_before_sample)) {
523
- // TODO: Add a counter for this
544
+ if (state->dynamic_sampling_rate_enabled && !dynamic_sampling_rate_should_sample(&state->dynamic_sampling_rate, wall_time_ns_before_sample)) {
545
+ state->stats.skipped_sample_because_of_dynamic_sampling_rate++;
524
546
  return Qnil;
525
547
  }
526
548
 
@@ -777,6 +799,11 @@ static VALUE _native_stats(DDTRACE_UNUSED VALUE self, VALUE instance) {
777
799
  ID2SYM(rb_intern("signal_handler_enqueued_sample")), /* => */ UINT2NUM(state->stats.signal_handler_enqueued_sample),
778
800
  ID2SYM(rb_intern("signal_handler_wrong_thread")), /* => */ UINT2NUM(state->stats.signal_handler_wrong_thread),
779
801
  ID2SYM(rb_intern("sampled")), /* => */ UINT2NUM(state->stats.sampled),
802
+ ID2SYM(rb_intern("skipped_sample_because_of_dynamic_sampling_rate")), /* => */ UINT2NUM(state->stats.skipped_sample_because_of_dynamic_sampling_rate),
803
+ ID2SYM(rb_intern("postponed_job_skipped_already_existed")), /* => */ UINT2NUM(state->stats.postponed_job_skipped_already_existed),
804
+ ID2SYM(rb_intern("postponed_job_success")), /* => */ UINT2NUM(state->stats.postponed_job_success),
805
+ ID2SYM(rb_intern("postponed_job_full")), /* => */ UINT2NUM(state->stats.postponed_job_full),
806
+ ID2SYM(rb_intern("postponed_job_unknown_result")), /* => */ UINT2NUM(state->stats.postponed_job_unknown_result),
780
807
  ID2SYM(rb_intern("sampling_time_ns_min")), /* => */ pretty_sampling_time_ns_min,
781
808
  ID2SYM(rb_intern("sampling_time_ns_max")), /* => */ pretty_sampling_time_ns_max,
782
809
  ID2SYM(rb_intern("sampling_time_ns_total")), /* => */ pretty_sampling_time_ns_total,
@@ -53,7 +53,7 @@ module Datadog
53
53
  if new && new.ready?
54
54
  old = @processor
55
55
  @processor = new
56
- old.finalize
56
+ old.finalize if old
57
57
  end
58
58
  end
59
59
  end
@@ -23,12 +23,11 @@ module Datadog
23
23
  @oneshot_tags_sent = false
24
24
  end
25
25
 
26
- # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
26
+ # rubocop:disable Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
27
27
  def call(env)
28
28
  return @app.call(env) unless Datadog::AppSec.enabled?
29
29
 
30
30
  Datadog::Core::Remote.active_remote.barrier(:once) unless Datadog::Core::Remote.active_remote.nil?
31
- processor = Datadog::AppSec.processor
32
31
 
33
32
  processor = nil
34
33
  ready = false
@@ -89,7 +88,7 @@ module Datadog
89
88
  processor.deactivate_context
90
89
  end
91
90
  end
92
- # rubocop:enable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
91
+ # rubocop:enable Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity,Metrics/MethodLength
93
92
 
94
93
  private
95
94
 
@@ -95,9 +95,7 @@ module Datadog
95
95
  end
96
96
 
97
97
  def adapter
98
- # If no agent settings have been provided, we try to connect using a local unix socket.
99
- # We only do so if the socket is present when `ddtrace` runs.
100
- if should_use_uds_fallback?
98
+ if should_use_uds? && !mixed_http_and_uds?
101
99
  Datadog::Transport::Ext::UnixSocket::ADAPTER
102
100
  else
103
101
  Datadog::Transport::Ext::HTTP::ADAPTER
@@ -118,7 +116,7 @@ module Datadog
118
116
  ),
119
117
  DetectedConfiguration.new(
120
118
  friendly_name: "#{Datadog::Tracing::Configuration::Ext::Transport::ENV_DEFAULT_URL} environment variable",
121
- value: parsed_url && parsed_url.hostname
119
+ value: parsed_http_url && parsed_http_url.hostname
122
120
  ),
123
121
  DetectedConfiguration.new(
124
122
  friendly_name: "#{Datadog::Core::Configuration::Ext::Transport::ENV_DEFAULT_HOST} environment variable",
@@ -141,7 +139,7 @@ module Datadog
141
139
  ),
142
140
  DetectedConfiguration.new(
143
141
  friendly_name: "#{Datadog::Tracing::Configuration::Ext::Transport::ENV_DEFAULT_URL} environment variable",
144
- value: parsed_url && parsed_url.port,
142
+ value: parsed_http_url && parsed_http_url.port,
145
143
  ),
146
144
  try_parsing_as_integer(
147
145
  friendly_name: "#{Datadog::Tracing::Configuration::Ext::Transport::ENV_DEFAULT_PORT} environment variable",
@@ -169,16 +167,29 @@ module Datadog
169
167
  end
170
168
 
171
169
  def hostname
172
- configured_hostname || (should_use_uds_fallback? ? nil : Datadog::Transport::Ext::HTTP::DEFAULT_HOST)
170
+ configured_hostname || (should_use_uds? ? nil : Datadog::Transport::Ext::HTTP::DEFAULT_HOST)
173
171
  end
174
172
 
175
173
  def port
176
- configured_port || (should_use_uds_fallback? ? nil : Datadog::Transport::Ext::HTTP::DEFAULT_PORT)
174
+ configured_port || (should_use_uds? ? nil : Datadog::Transport::Ext::HTTP::DEFAULT_PORT)
177
175
  end
178
176
 
179
177
  # Unix socket path in the file system
180
178
  def uds_path
181
- uds_fallback
179
+ if mixed_http_and_uds?
180
+ nil
181
+ elsif parsed_url && unix_scheme?(parsed_url)
182
+ path = parsed_url.to_s
183
+ # Some versions of the built-in uri gem leave the original url untouched, and others remove the //, so this
184
+ # supports both
185
+ if path.start_with?('unix://')
186
+ path.sub('unix://', '')
187
+ else
188
+ path.sub('unix:', '')
189
+ end
190
+ else
191
+ uds_fallback
192
+ end
182
193
  end
183
194
 
184
195
  # Defaults to +nil+, letting the adapter choose what default
@@ -210,8 +221,11 @@ module Datadog
210
221
  end
211
222
  end
212
223
 
213
- def should_use_uds_fallback?
214
- uds_fallback != nil
224
+ def should_use_uds?
225
+ parsed_url && unix_scheme?(parsed_url) ||
226
+ # If no agent settings have been provided, we try to connect using a local unix socket.
227
+ # We only do so if the socket is present when `ddtrace` runs.
228
+ !uds_fallback.nil?
215
229
  end
216
230
 
217
231
  def parsed_url
@@ -223,7 +237,7 @@ module Datadog
223
237
  if unparsed_url_from_env
224
238
  parsed = URI.parse(unparsed_url_from_env)
225
239
 
226
- if %w[http https].include?(parsed.scheme)
240
+ if http_scheme?(parsed) || unix_scheme?(parsed)
227
241
  parsed
228
242
  else
229
243
  # rubocop:disable Layout/LineLength
@@ -266,6 +280,43 @@ module Datadog
266
280
  logger.warn(message) if logger
267
281
  end
268
282
 
283
+ def http_scheme?(uri)
284
+ ['http', 'https'].include?(uri.scheme)
285
+ end
286
+
287
+ # Expected to return nil (not false!) when it's not http
288
+ def parsed_http_url
289
+ parsed_url if parsed_url && http_scheme?(parsed_url)
290
+ end
291
+
292
+ def unix_scheme?(uri)
293
+ uri.scheme == 'unix'
294
+ end
295
+
296
+ # When we have mixed settings for http/https and uds, we print a warning and ignore the uds settings
297
+ def mixed_http_and_uds?
298
+ return @mixed_http_and_uds if defined?(@mixed_http_and_uds)
299
+
300
+ @mixed_http_and_uds = (configured_hostname || configured_port) && should_use_uds?
301
+
302
+ if @mixed_http_and_uds
303
+ warn_if_configuration_mismatch(
304
+ [
305
+ DetectedConfiguration.new(
306
+ friendly_name: 'configuration of hostname/port for http/https use',
307
+ value: "hostname: '#{configured_hostname}', port: #{configured_port.inspect}",
308
+ ),
309
+ DetectedConfiguration.new(
310
+ friendly_name: 'configuration for unix domain socket',
311
+ value: "unix://#{uds_path}",
312
+ ),
313
+ ]
314
+ )
315
+ end
316
+
317
+ @mixed_http_and_uds
318
+ end
319
+
269
320
  # The settings.tracing.transport_options allows users to have full control over the settings used to
270
321
  # communicate with the agent. In the general case, we can't extract the configuration from this proc, but
271
322
  # in the specific case of the http and unix socket adapters we can, and we use this method together with the
@@ -468,11 +468,11 @@ module Datadog
468
468
  settings :telemetry do
469
469
  # Enable telemetry collection. This allows telemetry events to be emitted to the telemetry API.
470
470
  #
471
- # @default `DD_INSTRUMENTATION_TELEMETRY_ENABLED` environment variable, otherwise `false`. In a future release,
472
- # this value will be changed to `true` by default as documented [here](https://docs.datadoghq.com/tracing/configure_data_security/#telemetry-collection).
471
+ # @default `DD_INSTRUMENTATION_TELEMETRY_ENABLED` environment variable, otherwise `true`.
472
+ # Can be disabled as documented [here](https://docs.datadoghq.com/tracing/configure_data_security/#telemetry-collection).
473
473
  # @return [Boolean]
474
474
  option :enabled do |o|
475
- o.default { env_to_bool(Core::Telemetry::Ext::ENV_ENABLED, false) }
475
+ o.default { env_to_bool(Core::Telemetry::Ext::ENV_ENABLED, true) }
476
476
  o.lazy
477
477
  end
478
478
  end
@@ -482,11 +482,10 @@ module Datadog
482
482
  settings :remote do
483
483
  # Enable remote configuration. This allows fetching of remote configuration for live updates.
484
484
  #
485
- # @default `DD_REMOTE_CONFIGURATION_ENABLED` environment variable, otherwise `false`. In a future release,
486
- # this value will be changed to `true` by default.
485
+ # @default `DD_REMOTE_CONFIGURATION_ENABLED` environment variable, otherwise `true`.
487
486
  # @return [Boolean]
488
487
  option :enabled do |o|
489
- o.default { env_to_bool(Core::Remote::Ext::ENV_ENABLED, false) }
488
+ o.default { env_to_bool(Core::Remote::Ext::ENV_ENABLED, true) }
490
489
  o.lazy
491
490
  end
492
491
 
@@ -49,9 +49,65 @@ module Datadog
49
49
  Core::Environment::Ext::LANG_VERSION
50
50
  end
51
51
 
52
+ # Returns tracer version, rubygems-style
52
53
  def tracer_version
53
54
  Core::Environment::Ext::TRACER_VERSION
54
55
  end
56
+
57
+ # Returns tracer version, comforming to https://semver.org/spec/v2.0.0.html
58
+ def tracer_version_semver2
59
+ # from ddtrace/version.rb, we have MAJOR.MINOR.PATCH plus optional .PRE and .BUILD
60
+ # - transform .PRE to -PRE if present
61
+ # - transform .BUILD to +BUILD if present
62
+ # - keep triplet segments before that
63
+
64
+ m = SEMVER2_RE.match(tracer_version)
65
+
66
+ pre = "-#{m[:pre]}" if m[:pre]
67
+ build = "+gha#{m[:gha_run_id]}.g#{m[:git_sha]}.#{m[:branch].tr('.', '-')}" if m[:build]
68
+
69
+ "#{m[:major]}.#{m[:minor]}.#{m[:patch]}#{pre}#{build}"
70
+ end
71
+
72
+ SEMVER2_RE = /
73
+ ^
74
+ # mandatory segments
75
+ (?<major>\d+)
76
+ \.
77
+ (?<minor>\d+)
78
+ \.
79
+ (?<patch>\d+)
80
+
81
+ # pre segments start with a value
82
+ # - containing at least one alpha
83
+ # - that is not part of our build segments expected values
84
+ # and stop with a value that is not part of our build segments expected values
85
+ (?:
86
+ \.
87
+ (?<pre>
88
+ (?!gha)
89
+ [a-zA-Z0-9]*[a-zA-Z][a-zA-Z0-9]*
90
+ (?:
91
+ \.
92
+ (?!gha)
93
+ [a-zA-Z0-9]+
94
+ )*
95
+ )
96
+ )?
97
+
98
+ # build segments: ours include CI info (`gha`), then git (`g`), then branch name
99
+ (?:
100
+ \.
101
+ (?<build>
102
+ gha(?<gha_run_id>\d+)
103
+ \.
104
+ g(?<git_sha>[a-f0-9]+)
105
+ \.
106
+ (?<branch>(?:[a-zA-Z0-9.])+)
107
+ )
108
+ )?
109
+ $
110
+ /xm.freeze
55
111
  end
56
112
  end
57
113
  end
@@ -27,7 +27,7 @@ module Datadog
27
27
  end
28
28
  end
29
29
 
30
- # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity
30
+ # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/MethodLength,Metrics/CyclomaticComplexity
31
31
  def sync
32
32
  # TODO: Skip sync if no capabilities are registered
33
33
  response = transport.send_config(payload)
@@ -40,13 +40,20 @@ module Datadog
40
40
  return
41
41
  end
42
42
 
43
- paths = response.client_configs.map do |path|
44
- Configuration::Path.parse(path)
45
- end
43
+ begin
44
+ paths = response.client_configs.map do |path|
45
+ Configuration::Path.parse(path)
46
+ end
46
47
 
47
- targets = Configuration::TargetMap.parse(response.targets)
48
+ targets = Configuration::TargetMap.parse(response.targets)
48
49
 
49
- contents = Configuration::ContentList.parse(response.target_files)
50
+ contents = Configuration::ContentList.parse(response.target_files)
51
+ rescue Remote::Configuration::Path::ParseError => e
52
+ raise SyncError, e.message
53
+ end
54
+
55
+ # To make sure steep does not complain
56
+ return unless paths && targets && contents
50
57
 
51
58
  # TODO: sometimes it can strangely be so that paths.empty?
52
59
  # TODO: sometimes it can strangely be so that targets.empty?
@@ -100,17 +107,44 @@ module Datadog
100
107
  else
101
108
  dispatcher.dispatch(changes, repository)
102
109
  end
103
- else
104
- raise SyncError, "unexpected transport response: #{response.inspect}"
105
110
  end
106
111
  end
107
- # rubocop:enable Metrics/AbcSize,Metrics/PerceivedComplexity
112
+ # rubocop:enable Metrics/AbcSize,Metrics/PerceivedComplexity,Metrics/MethodLength,Metrics/CyclomaticComplexity
108
113
 
109
114
  private
110
115
 
111
- def payload
116
+ def payload # rubocop:disable Metrics/MethodLength
112
117
  state = repository.state
113
118
 
119
+ client_tracer_tags = [
120
+ "platform:#{native_platform}", # native platform
121
+ # "asm.config.rules:#{}", # TODO: defined|undefined
122
+ # "asm.config.enabled:#{}", # TODO: true|false|undefined
123
+ "ruby.tracer.version:#{Core::Environment::Identity.tracer_version}",
124
+ "ruby.runtime.platform:#{RUBY_PLATFORM}",
125
+ "ruby.runtime.version:#{RUBY_VERSION}",
126
+ "ruby.runtime.engine.name:#{RUBY_ENGINE}",
127
+ "ruby.runtime.engine.version:#{ruby_engine_version}",
128
+ "ruby.rubygems.platform.local:#{Gem::Platform.local}",
129
+ "ruby.gem.libddwaf.version:#{gem_spec('libddwaf').version}",
130
+ "ruby.gem.libddwaf.platform:#{gem_spec('libddwaf').platform}",
131
+ "ruby.gem.libdatadog.version:#{gem_spec('libdatadog').version}",
132
+ "ruby.gem.libdatadog.platform:#{gem_spec('libdatadog').platform}",
133
+ ]
134
+
135
+ client_tracer = {
136
+ runtime_id: Core::Environment::Identity.id,
137
+ language: Core::Environment::Identity.lang,
138
+ tracer_version: tracer_version_semver2,
139
+ service: Datadog.configuration.service,
140
+ env: Datadog.configuration.env,
141
+ tags: client_tracer_tags,
142
+ }
143
+
144
+ app_version = Datadog.configuration.version
145
+
146
+ client_tracer[:app_version] = app_version if app_version
147
+
114
148
  {
115
149
  client: {
116
150
  state: {
@@ -125,21 +159,66 @@ module Datadog
125
159
  products: @capabilities.products,
126
160
  is_tracer: true,
127
161
  is_agent: false,
128
- client_tracer: {
129
- runtime_id: Core::Environment::Identity.id,
130
- language: Core::Environment::Identity.lang,
131
- tracer_version: Core::Environment::Identity.tracer_version,
132
- service: Datadog.configuration.service,
133
- env: Datadog.configuration.env,
134
- # app_version: app_version, # TODO: I don't know what this is
135
- tags: [], # TODO: add nice tags!
136
- },
162
+ client_tracer: client_tracer,
137
163
  # base64 is needed otherwise the Go agent fails with an unmarshal error
138
164
  capabilities: @capabilities.base64_capabilities
139
165
  },
140
166
  cached_target_files: state.cached_target_files,
141
167
  }
142
168
  end
169
+
170
+ def tracer_version_semver2
171
+ @tracer_version_semver2 ||= Core::Environment::Identity.tracer_version_semver2
172
+ end
173
+
174
+ def ruby_engine_version
175
+ @ruby_engine_version ||= defined?(RUBY_ENGINE_VERSION) ? RUBY_ENGINE_VERSION : RUBY_VERSION
176
+ end
177
+
178
+ def gem_spec(name)
179
+ (@gem_specs ||= {})[name] ||= ::Gem.loaded_specs[name] || GemSpecificationFallback.new(nil, nil)
180
+ end
181
+
182
+ def native_platform
183
+ return @native_platform unless @native_platform.nil?
184
+
185
+ os = if RUBY_ENGINE == 'jruby'
186
+ os_name = java.lang.System.get_property('os.name')
187
+
188
+ case os_name
189
+ when /linux/i then 'linux'
190
+ when /mac/i then 'darwin'
191
+ else os_name
192
+ end
193
+ else
194
+ Gem::Platform.local.os
195
+ end
196
+
197
+ version = if os != 'linux'
198
+ nil
199
+ elsif RUBY_PLATFORM =~ /linux-(.+)$/
200
+ # Old rubygems don't handle non-gnu linux correctly
201
+ Regexp.last_match(1)
202
+ else
203
+ 'gnu'
204
+ end
205
+
206
+ cpu = if RUBY_ENGINE == 'jruby'
207
+ os_arch = java.lang.System.get_property('os.arch')
208
+
209
+ case os_arch
210
+ when 'amd64' then 'x86_64'
211
+ when 'aarch64' then os == 'darwin' ? 'arm64' : 'aarch64'
212
+ else os_arch
213
+ end
214
+ else
215
+ Gem::Platform.local.cpu
216
+ end
217
+
218
+ @native_platform = [cpu, os, version].compact.join('-')
219
+ end
220
+
221
+ GemSpecificationFallback = _ = Struct.new(:version, :platform) # rubocop:disable Naming/ConstantName
143
222
  end
144
223
  end
145
224
  end