ddtrace 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -16
  3. data/CHANGELOG.md +31 -2
  4. data/LICENSE-3rdparty.csv +3 -2
  5. data/README.md +2 -2
  6. data/ddtrace.gemspec +12 -3
  7. data/docs/GettingStarted.md +19 -2
  8. data/docs/ProfilingDevelopment.md +8 -8
  9. data/docs/UpgradeGuide.md +3 -3
  10. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +118 -0
  11. data/ext/ddtrace_profiling_loader/extconf.rb +53 -0
  12. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +31 -5
  13. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +0 -8
  14. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +278 -0
  15. data/ext/ddtrace_profiling_native_extension/extconf.rb +70 -100
  16. data/ext/ddtrace_profiling_native_extension/libddprof_helpers.h +13 -0
  17. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +186 -0
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +579 -7
  19. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +30 -0
  20. data/ext/ddtrace_profiling_native_extension/profiling.c +7 -0
  21. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +139 -0
  22. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +28 -0
  23. data/lib/datadog/appsec/autoload.rb +2 -2
  24. data/lib/datadog/appsec/configuration/settings.rb +19 -0
  25. data/lib/datadog/appsec/configuration.rb +8 -0
  26. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +76 -33
  27. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -0
  28. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -1
  29. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +64 -0
  30. data/lib/datadog/appsec/contrib/rack/request.rb +6 -0
  31. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +41 -0
  32. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +60 -5
  33. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +81 -0
  34. data/lib/datadog/appsec/contrib/rails/patcher.rb +34 -1
  35. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +68 -0
  36. data/lib/datadog/appsec/contrib/rails/request.rb +33 -0
  37. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +124 -0
  38. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +69 -2
  39. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +63 -0
  40. data/lib/datadog/appsec/event.rb +33 -18
  41. data/lib/datadog/appsec/extensions.rb +0 -3
  42. data/lib/datadog/appsec/processor.rb +45 -2
  43. data/lib/datadog/appsec/rate_limiter.rb +5 -0
  44. data/lib/datadog/appsec/reactive/operation.rb +0 -1
  45. data/lib/datadog/ci/ext/environment.rb +21 -7
  46. data/lib/datadog/core/configuration/agent_settings_resolver.rb +1 -1
  47. data/lib/datadog/core/configuration/components.rb +22 -4
  48. data/lib/datadog/core/configuration/settings.rb +3 -3
  49. data/lib/datadog/core/configuration.rb +7 -5
  50. data/lib/datadog/core/environment/cgroup.rb +3 -1
  51. data/lib/datadog/core/environment/container.rb +2 -1
  52. data/lib/datadog/core/environment/variable_helpers.rb +26 -2
  53. data/lib/datadog/core/logging/ext.rb +11 -0
  54. data/lib/datadog/core/metrics/client.rb +15 -5
  55. data/lib/datadog/core/runtime/metrics.rb +1 -1
  56. data/lib/datadog/core/workers/async.rb +3 -1
  57. data/lib/datadog/core/workers/runtime_metrics.rb +0 -3
  58. data/lib/datadog/core.rb +6 -0
  59. data/lib/datadog/kit/enable_core_dumps.rb +50 -0
  60. data/lib/datadog/kit/identity.rb +63 -0
  61. data/lib/datadog/kit.rb +11 -0
  62. data/lib/datadog/opentracer/tracer.rb +0 -2
  63. data/lib/datadog/profiling/collectors/old_stack.rb +298 -0
  64. data/lib/datadog/profiling/collectors/stack.rb +6 -287
  65. data/lib/datadog/profiling/encoding/profile.rb +0 -1
  66. data/lib/datadog/profiling/ext.rb +1 -1
  67. data/lib/datadog/profiling/flush.rb +1 -1
  68. data/lib/datadog/profiling/load_native_extension.rb +22 -0
  69. data/lib/datadog/profiling/recorder.rb +1 -1
  70. data/lib/datadog/profiling/scheduler.rb +1 -1
  71. data/lib/datadog/profiling/stack_recorder.rb +33 -0
  72. data/lib/datadog/profiling/tag_builder.rb +48 -0
  73. data/lib/datadog/profiling/tasks/exec.rb +2 -2
  74. data/lib/datadog/profiling/tasks/setup.rb +6 -4
  75. data/lib/datadog/profiling.rb +29 -27
  76. data/lib/datadog/tracing/buffer.rb +9 -3
  77. data/lib/datadog/tracing/contrib/action_view/patcher.rb +0 -1
  78. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  79. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  80. data/lib/datadog/tracing/contrib/active_record/vendor/connection_specification.rb +1 -1
  81. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +4 -2
  82. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +10 -3
  83. data/lib/datadog/tracing/contrib/dalli/patcher.rb +0 -1
  84. data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +0 -1
  85. data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +9 -3
  86. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +38 -2
  87. data/lib/datadog/tracing/contrib/ethon/patcher.rb +0 -1
  88. data/lib/datadog/tracing/contrib/extensions.rb +0 -2
  89. data/lib/datadog/tracing/contrib/faraday/patcher.rb +0 -1
  90. data/lib/datadog/tracing/contrib/grape/patcher.rb +0 -1
  91. data/lib/datadog/tracing/contrib/graphql/patcher.rb +0 -1
  92. data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -1
  93. data/lib/datadog/tracing/contrib/kafka/patcher.rb +0 -1
  94. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -1
  95. data/lib/datadog/tracing/contrib/qless/patcher.rb +0 -1
  96. data/lib/datadog/tracing/contrib/que/patcher.rb +0 -1
  97. data/lib/datadog/tracing/contrib/racecar/patcher.rb +0 -1
  98. data/lib/datadog/tracing/contrib/rails/log_injection.rb +3 -16
  99. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
  100. data/lib/datadog/tracing/contrib/rake/patcher.rb +0 -1
  101. data/lib/datadog/tracing/contrib/redis/patcher.rb +0 -1
  102. data/lib/datadog/tracing/contrib/resque/patcher.rb +0 -1
  103. data/lib/datadog/tracing/contrib/rest_client/patcher.rb +0 -1
  104. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +2 -1
  105. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
  106. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +20 -1
  107. data/lib/datadog/tracing/contrib/sinatra/framework.rb +11 -0
  108. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +0 -1
  109. data/lib/datadog/tracing/contrib/sneakers/patcher.rb +0 -1
  110. data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +0 -1
  111. data/lib/datadog/tracing/event.rb +2 -1
  112. data/lib/datadog/tracing/sampling/priority_sampler.rb +4 -5
  113. data/lib/datadog/tracing/sampling/rule.rb +12 -6
  114. data/lib/datadog/tracing/sampling/rule_sampler.rb +3 -5
  115. data/lib/datadog/tracing/span_operation.rb +2 -3
  116. data/lib/datadog/tracing/trace_operation.rb +0 -1
  117. data/lib/ddtrace/transport/http/client.rb +2 -1
  118. data/lib/ddtrace/transport/http/response.rb +34 -4
  119. data/lib/ddtrace/transport/io/client.rb +3 -1
  120. data/lib/ddtrace/version.rb +1 -1
  121. data/lib/ddtrace.rb +1 -0
  122. metadata +43 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14636ceebc61d9de8ea83328295cb728de928bd0cf80af29f6c4f73d759ff243
4
- data.tar.gz: 92110181e57676c407a782a3729a19499b3175fd653162ff260b79be8f75a502
3
+ metadata.gz: 6517e04d64a4ad46051c9841bf7438809e6379693f5796a26c063e3335788963
4
+ data.tar.gz: 646ad1cdabd82d2c94c4d4d5d1e4ab96f6a36890a9f50ea4cbbedac4c123a00e
5
5
  SHA512:
6
- metadata.gz: 0dc73ef73c3269adfb1cbf50ba22df0f06b5e9a0237f8bec8428e1b4f9445e45f20fb5ede5c88355e18f4562b2f561b0a4f089715ff44aabf52130a6915e4498
7
- data.tar.gz: f44f40e302ae841147d5bbd62ebc0fe716ee6b30e8776820efd4c39fd3f9c184b0919dc3752b30316c87e0cde19f5380a42ad6cb9290e319183b8440fef11be1
6
+ metadata.gz: 6d17badd3ed215171d47529092da1ea2a90e0acbdd9071237fc3637052d2b8fb72c422594dfd504a773dc504bcb8862c07d40123fdd97df207d07e07dee5a491
7
+ data.tar.gz: 9cbde75b86ba09ccb13161ab106ec24d3b10d93bab1b5996fdec72c14c429b227df3bbc965ab528369ac25e36a5650368b1339e89c17e632605c1e95566bae87
data/.gitignore CHANGED
@@ -14,26 +14,11 @@
14
14
  /tmp/
15
15
  /log/
16
16
  TODO
17
+ ext/**/skipped_reason.txt
17
18
 
18
19
  # Used by dotenv library to load environment variables.
19
20
  # .env
20
21
 
21
- ## Specific to RubyMotion:
22
- .dat*
23
- .repl_history
24
- build/
25
- *.bridgesupport
26
- build-iPhoneOS/
27
- build-iPhoneSimulator/
28
-
29
- ## Specific to RubyMotion (use of CocoaPods):
30
- #
31
- # We recommend against adding the Pods directory to your .gitignore. However
32
- # you should judge for yourself, the pros and cons are mentioned at:
33
- # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
34
- #
35
- # vendor/Pods/
36
-
37
22
  ## Documentation cache and generated files:
38
23
  /.yardoc/
39
24
  /_yardoc/
@@ -59,6 +44,9 @@ build-iPhoneSimulator/
59
44
  # lock files
60
45
  Gemfile.lock
61
46
 
47
+ # Appraisal gemfiles (they can always be regenerated by running `appraisal install`)
48
+ gemfiles/*.gemfile
49
+
62
50
  # bundle config
63
51
  gemfiles/.bundle
64
52
 
data/CHANGELOG.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.1.0] - 2022-05-25
6
+
7
+ ### Added
8
+
9
+ * [Application Security Monitoring](https://docs.datadoghq.com/security_platform/application_security/)
10
+ * Elasticsearch: v8.0 support ([#1985][])
11
+ * Sidekiq: Quantize args ([#1972][]) ([@dudo][])
12
+ * Profiling: Add libddprof dependency to power the new Ruby profiler ([#2028][])
13
+ * Helper to easily enable core dumps ([#2010][])
14
+
15
+ ### Changed
16
+
17
+ * Support spaces in environment variable DD_TAGS ([#2011][])
18
+
19
+ ### Fixed
20
+
21
+ * Fix "circular require considered harmful" warnings ([#1998][])
22
+ * Logging: Change ddsource to a scalar value ([#2022][])
23
+ * Improve exception logging ([#1992][])
24
+
5
25
  ## [1.0.0] - 2022-04-28
6
26
 
7
27
  Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v1.0.0
@@ -1987,7 +2007,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
1987
2007
 
1988
2008
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
1989
2009
 
1990
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.0.0...master
2010
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.1.0...master
2011
+ [1.1.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.0.0...v1.1.0
1991
2012
  [1.0.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.0.0.beta2...v1.0.0
1992
2013
  [1.0.0.beta2]: https://github.com/DataDog/dd-trace-rb/compare/v1.0.0.beta1...v1.0.0.beta2
1993
2014
  [1.0.0.beta1]: https://github.com/DataDog/dd-trace-rb/compare/v0.54.2...v1.0.0.beta1
@@ -2812,6 +2833,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
2812
2833
  [#1965]: https://github.com/DataDog/dd-trace-rb/issues/1965
2813
2834
  [#1968]: https://github.com/DataDog/dd-trace-rb/issues/1968
2814
2835
  [#1970]: https://github.com/DataDog/dd-trace-rb/issues/1970
2836
+ [#1972]: https://github.com/DataDog/dd-trace-rb/issues/1972
2815
2837
  [#1973]: https://github.com/DataDog/dd-trace-rb/issues/1973
2816
2838
  [#1974]: https://github.com/DataDog/dd-trace-rb/issues/1974
2817
2839
  [#1975]: https://github.com/DataDog/dd-trace-rb/issues/1975
@@ -2821,9 +2843,16 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
2821
2843
  [#1982]: https://github.com/DataDog/dd-trace-rb/issues/1982
2822
2844
  [#1983]: https://github.com/DataDog/dd-trace-rb/issues/1983
2823
2845
  [#1984]: https://github.com/DataDog/dd-trace-rb/issues/1984
2846
+ [#1985]: https://github.com/DataDog/dd-trace-rb/issues/1985
2824
2847
  [#1989]: https://github.com/DataDog/dd-trace-rb/issues/1989
2825
2848
  [#1990]: https://github.com/DataDog/dd-trace-rb/issues/1990
2826
2849
  [#1991]: https://github.com/DataDog/dd-trace-rb/issues/1991
2850
+ [#1992]: https://github.com/DataDog/dd-trace-rb/issues/1992
2851
+ [#1998]: https://github.com/DataDog/dd-trace-rb/issues/1998
2852
+ [#2010]: https://github.com/DataDog/dd-trace-rb/issues/2010
2853
+ [#2011]: https://github.com/DataDog/dd-trace-rb/issues/2011
2854
+ [#2022]: https://github.com/DataDog/dd-trace-rb/issues/2022
2855
+ [#2028]: https://github.com/DataDog/dd-trace-rb/issues/2028
2827
2856
  [@AdrianLC]: https://github.com/AdrianLC
2828
2857
  [@Azure7111]: https://github.com/Azure7111
2829
2858
  [@BabyGroot]: https://github.com/BabyGroot
@@ -2954,4 +2983,4 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
2954
2983
  [@vramaiah]: https://github.com/vramaiah
2955
2984
  [@walterking]: https://github.com/walterking
2956
2985
  [@y-yagi]: https://github.com/y-yagi
2957
- [@zachmccormick]: https://github.com/zachmccormick
2986
+ [@zachmccormick]: https://github.com/zachmccormick
data/LICENSE-3rdparty.csv CHANGED
@@ -1,3 +1,4 @@
1
1
  Component,Origin,License,Copyright
2
- datadog/core/vendor/multipart-post,https://github.com/socketry/multipart-post,MIT,"Copyright (c) 2007-2013 Nick Sieger."
3
- ddtrace/contrib/active_record/vendor,https://github.com/rails/rails/,MIT,"Copyright (c) 2005-2018 David Heinemeier Hansson"
2
+ lib/datadog/core/vendor/multipart-post,https://github.com/socketry/multipart-post,MIT,"Copyright (c) 2007-2013 Nick Sieger."
3
+ lib/datadog/tracing/contrib/active_record/vendor,https://github.com/rails/rails/,MIT,"Copyright (c) 2005-2018 David Heinemeier Hansson"
4
+ ext/ddtrace_profiling_native_extension/private_vm_api_access,https://github.com/ruby/ruby,BSD-2-Clause,"Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved."
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- ***Version 1.0.0 is in beta! Check out our [upgrade guide](https://github.com/DataDog/dd-trace-rb/blob/master/docs/UpgradeGuide.md#from-0x-to-10) for more details.***
1
+ ***Version 1.0.0 has recently been released. Check out our [upgrade guide](https://github.com/DataDog/dd-trace-rb/blob/master/docs/UpgradeGuide.md#from-0x-to-10) for more details.***
2
2
 
3
3
  # Datadog Trace Client
4
4
 
5
- ![Gem](https://img.shields.io/gem/v/ddtrace)
5
+ [![Gem](https://img.shields.io/gem/v/ddtrace)](https://rubygems.org/gems/ddtrace/)
6
6
  [![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)
7
7
  [![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)
8
8
  [![YARD documentation](https://img.shields.io/badge/YARD-documentation-blue)](https://www.rubydoc.info/gems/ddtrace/)
data/ddtrace.gemspec CHANGED
@@ -39,6 +39,12 @@ Gem::Specification.new do |spec|
39
39
  spec.executables = ['ddtracerb']
40
40
  spec.require_paths = ['lib']
41
41
 
42
+ # Important note: This `if` ONLY works for development. When packaging up the gem, Ruby runs this code, and hardcodes
43
+ # the output in the `.gem` file that gets uploaded to rubygems. So the decision here gets hardcoded, we don't actually
44
+ # pick a version depending on the Ruby customers are running, as it may appear.
45
+ # For more context, see the discussion in
46
+ # * https://github.com/DataDog/dd-trace-rb/pull/1739
47
+ # * https://github.com/DataDog/dd-trace-rb/pull/1336
42
48
  if RUBY_VERSION >= '2.2.0'
43
49
  spec.add_dependency 'msgpack'
44
50
  else
@@ -50,10 +56,13 @@ Gem::Specification.new do |spec|
50
56
  #
51
57
  # Because we only use this for older Rubies, and we consider it "feature-complete" for those older Rubies,
52
58
  # 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.15'
59
+ spec.add_dependency 'debase-ruby_core_source', '<= 0.10.16'
54
60
 
55
61
  # Used by appsec
56
- spec.add_dependency 'libddwaf', '~> 1.3.0.0.0.a'
62
+ spec.add_dependency 'libddwaf', '~> 1.3.0.2.0'
57
63
 
58
- spec.extensions = ['ext/ddtrace_profiling_native_extension/extconf.rb']
64
+ # Used by profiling
65
+ spec.add_dependency 'libddprof', '~> 0.6.0.1.0'
66
+
67
+ spec.extensions = ['ext/ddtrace_profiling_native_extension/extconf.rb', 'ext/ddtrace_profiling_loader/extconf.rb']
59
68
  end
@@ -1,4 +1,4 @@
1
- ***Version 1.0.0 is in beta! Check out our [upgrade guide](https://github.com/DataDog/dd-trace-rb/blob/master/docs/UpgradeGuide.md#from-0x-to-10) for more details.***
1
+ ***Version 1.0.0 has been released. Check out our [upgrade guide](https://github.com/DataDog/dd-trace-rb/blob/master/docs/UpgradeGuide.md#from-0x-to-10) for more details.***
2
2
 
3
3
  # Datadog Ruby Trace Client
4
4
 
@@ -105,6 +105,12 @@ To contribute, check out the [contribution guidelines][contribution docs] and [d
105
105
 
106
106
  ## Compatibility
107
107
 
108
+ <!--
109
+ Note: Please replicate any changes to this section also to
110
+ https://github.com/datadog/documentation/blob/master/content/en/tracing/setup_overview/compatibility_requirements/ruby.md
111
+ so that they remain in sync.
112
+ -->
113
+
108
114
  **Supported Ruby interpreters**:
109
115
 
110
116
  | Type | Documentation | Version | Support type | Gem version support |
@@ -121,7 +127,8 @@ To contribute, check out the [contribution guidelines][contribution docs] and [d
121
127
  | | | 2.0 | EOL since June 7th, 2021 | < 0.50.0 |
122
128
  | | | 1.9.3 | EOL since August 6th, 2020 | < 0.27.0 |
123
129
  | | | 1.9.1 | EOL since August 6th, 2020 | < 0.27.0 |
124
- | JRuby | https://www.jruby.org | 9.2 | Full | Latest |
130
+ | JRuby | https://www.jruby.org | 9.3 | Full | Latest |
131
+ | | | 9.2 | Full | Latest |
125
132
 
126
133
  **Supported web servers**:
127
134
 
@@ -455,6 +462,12 @@ end
455
462
 
456
463
  For a list of available integrations, and their configuration options, please refer to the following:
457
464
 
465
+ <!--
466
+ Note: Please replicate any changes to this section also to
467
+ https://github.com/datadog/documentation/blob/master/content/en/tracing/setup_overview/compatibility_requirements/ruby.md
468
+ so that they remain in sync.
469
+ -->
470
+
458
471
  | Name | Key | Versions Supported: MRI | Versions Supported: JRuby | How to configure | Gem source |
459
472
  | -------------------------- | -------------------------- | ------------------------ | --------------------------| ----------------------------------- | ------------------------------------------------------------------------------ |
460
473
  | Action Cable | `action_cable` | `>= 5.0` | `>= 5.0` | *[Link](#action-cable)* | *[Link](https://github.com/rails/rails/tree/master/actioncable)* |
@@ -869,6 +882,9 @@ end
869
882
  # Perform a query to Elasticsearch
870
883
  client = Elasticsearch::Client.new url: 'http://127.0.0.1:9200'
871
884
  response = client.perform_request 'GET', '_cluster/health'
885
+
886
+ # In case you want to override the global configuration for a certain client instance
887
+ Datadog.configure_onto(client.transport, **options)
872
888
  ```
873
889
 
874
890
  Where `options` is an optional `Hash` that accepts the following parameters:
@@ -1852,6 +1868,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1852
1868
  | --- | ----------- | ------- |
1853
1869
  | `tag_args` | Enable tagging of job arguments. `true` for on, `false` for off. | `false` |
1854
1870
  | `error_handler` | Custom error handler invoked when a job raises an error. Provided `span` and `error` as arguments. Sets error on the span by default. Useful for ignoring transient errors. | `proc { |span, error| span.set_error(error) unless span.nil? }` |
1871
+ | `quantize` | Hash containing options for quantization of job arguments. | `{}` |
1855
1872
 
1856
1873
  ### Sinatra
1857
1874
 
@@ -8,7 +8,7 @@ For a more practical view of getting started with development of `ddtrace`, see
8
8
 
9
9
  Components below live inside <../lib/datadog/profiling>:
10
10
 
11
- * `Collectors::Stack`: Collects stack trace samples from Ruby threads for both CPU-time (if available) and wall-clock.
11
+ * `Collectors::OldStack`: Collects stack trace samples from Ruby threads for both CPU-time (if available) and wall-clock.
12
12
  Runs on its own background thread.
13
13
  * `Collectors::CodeProvenance`: Collects library metadata to power grouping and categorization of stack traces (e.g. to help distinguish user code, from libraries, from the standard library, etc).
14
14
  * `Encoding::Profile`: Encodes gathered data into the pprof format.
@@ -25,7 +25,7 @@ Components below live inside <../lib/datadog/profiling>:
25
25
  * `Exporter`: Writes profiling data to a given transport.
26
26
  * `Flush`: Entity class used to represent metadata for a given profile.
27
27
  * `Profiler`: Profiling entry point, which coordinates collectors and a scheduler.
28
- * `Recorder`: Stores profiling events gathered by `Collector`s.
28
+ * `Recorder`: Stores profiling events gathered by the `Collector::OldStack`. (To be removed after migration to libddprof aggregation)
29
29
  * `Scheduler`: Periodically (every 1 minute) takes data from the `Recorder` and pushes them to all configured
30
30
  `Exporter`s. Runs on its own background thread.
31
31
 
@@ -52,9 +52,9 @@ flow:
52
52
  +---------+--+ +-+-------+-+
53
53
  | | |
54
54
  v | v
55
- +-----+-+ | +----+------+
56
- | Stack | | | Exporters |
57
- +-----+-+ | +-----------+
55
+ +--------+-+ | +----+------+
56
+ | OldStack | | | Exporters |
57
+ +--------+-+ | +-----------+
58
58
  | |
59
59
  v v
60
60
  +-+-------+-+
@@ -70,9 +70,9 @@ flow:
70
70
 
71
71
  ## Run-time execution
72
72
 
73
- During run-time, the `Scheduler` and the `Collectors::Stack` each execute on their own background thread.
73
+ During run-time, the `Scheduler` and the `Collectors::OldStack` each execute on their own background thread.
74
74
 
75
- The `Collectors::Stack` samples stack traces of threads, capturing both CPU-time (if available) and wall-clock, storing
75
+ The `Collectors::OldStack` samples stack traces of threads, capturing both CPU-time (if available) and wall-clock, storing
76
76
  them in the `Recorder`.
77
77
 
78
78
  The `Scheduler` wakes up every 1 minute to flush the results of the `Recorder` into one or more `exporter`s.
@@ -103,7 +103,7 @@ To further enable filtering of a profile to show only samples related to a given
103
103
  profiler is tagged with the `local root span id` and `span id` for the given trace/span.
104
104
 
105
105
  This is done using the `Datadog::Profiling::TraceIdentifiers::Helper` that retrieves a `root_span_id` and `span_id`, if
106
- available, from the supported tracers. This helper is called by the `Collectors::Stack` during sampling.
106
+ available, from the supported tracers. This helper is called by the `Collectors::OldStack` during sampling.
107
107
 
108
108
  Note that if a given trace executes too fast, it's possible that the profiler will not contain any samples for that
109
109
  specific trace. Nevertheless, the linking still works and is useful, as it allows users to explore what was going on their
data/docs/UpgradeGuide.md CHANGED
@@ -342,7 +342,7 @@ See the table below for most common mappings:
342
342
  | `Datadog.tracer.active_span` | `Datadog::Tracing.active_span` | See [trace state](#1.0-trace-api-trace-state) for details. |
343
343
  | `Datadog.tracer.call_context` | Removed | See [trace state](#1.0-trace-api-trace-state) for details. |
344
344
  | `Datadog.tracer.configure(options)` | `Datadog.configure { \|c\| ... }` | Use configuration API instead. |
345
- | `Datadog.tracer.provider.context = context` | `Datadog::Tracing.continue_from!(digest)` | See [distributed tracing](#1.0-trace-api-distributed) for details. |
345
+ | `Datadog.tracer.provider.context = context` | `Datadog::Tracing.continue_trace!(digest)` | See [distributed tracing](#1.0-trace-api-distributed) for details. |
346
346
  | `Datadog.tracer.set_tags(tags)` | `Datadog.configure { \|c\| c.tags = tags }` | |
347
347
  | `Datadog.tracer.shutdown!` | `Datadog::Tracing.shutdown!` | |
348
348
  | `Datadog.tracer.start_span` | `Datadog::Tracing.trace` | See [manual tracing](#1.0-trace-api-manual-tracing) for details. |
@@ -464,8 +464,8 @@ Datadog::Tracing.trace('my.job', continue_from: trace_digest) do |span, trace|
464
464
  trace.id == trace_digest.trace_id
465
465
  end
466
466
 
467
- # Continue a trace: explicit continuation (using #continue_from!)
468
- Datadog::Tracing.continue_from!(trace_digest) do
467
+ # Continue a trace: explicit continuation (using #continue_trace!)
468
+ Datadog::Tracing.continue_trace!(trace_digest) do
469
469
  # Traces implicitly continue within the block
470
470
  Datadog::Tracing.trace('my.job') do |span, trace|
471
471
  trace.id == trace_digest.trace_id
@@ -0,0 +1,118 @@
1
+ #include <stdbool.h>
2
+ #include <dlfcn.h>
3
+ #include <ruby.h>
4
+
5
+ // Why this exists:
6
+ //
7
+ // The Datadog::Profiling::Loader exists because when Ruby loads a native extension (using `require`), it uses
8
+ // `dlopen(..., RTLD_LAZY | RTLD_GLOBAL)` (https://github.com/ruby/ruby/blob/67950a4c0a884bdb78d9beb4405ebf7459229b21/dln.c#L362).
9
+ // This means that every symbol exposed directly or indirectly by that native extension becomes visible to every other
10
+ // extension in the Ruby process. This can cause issues, see https://github.com/rubyjs/mini_racer/pull/179.
11
+ //
12
+ // Instead of `RTLD_LAZY | RTLD_GLOBAL`, we want to call `dlopen` with `RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND` when
13
+ // loading the profiling native extension, to avoid leaking any unintended symbols (`RTLD_LOCAL`) and avoid picking
14
+ // up other's symbols (`RTLD_DEEPBIND`).
15
+ //
16
+ // But Ruby's extension loading mechanism is not configurable -- there's no way to tell it to use different flags when
17
+ // calling `dlopen`. To get around this, this file (ddtrace_profiling_loader.c) introduces another extension
18
+ // (profiling loader) which has only a single responsibility: mimic Ruby's extension loading mechanism, but when calling
19
+ // `dlopen` use a different set of flags.
20
+ // This idea was shamelessly stolen from @lloeki's work in https://github.com/rubyjs/mini_racer/pull/179, big thanks!
21
+ //
22
+ // Extra note: Currently (May 2022), that we know of, the profiling native extension only exposes one potentially
23
+ // problematic symbol: `rust_eh_personality` (coming from libddprof/libdatadog).
24
+ // Future versions of Rust have been patched not to expose this
25
+ // (see https://github.com/rust-lang/rust/pull/95604#issuecomment-1108563434) so we may want to revisit the need
26
+ // for this loader in the future, and perhaps delete it if we no longer require its services :)
27
+
28
+ #ifndef RTLD_DEEPBIND
29
+ #define RTLD_DEEPBIND 0
30
+ #endif
31
+
32
+ static VALUE ok_symbol = Qnil; // :ok in Ruby
33
+ static VALUE error_symbol = Qnil; // :error in Ruby
34
+
35
+ static VALUE _native_load(VALUE self, VALUE ruby_path, VALUE ruby_init_name);
36
+ static bool failed_to_load(void *handle, VALUE *failure_details);
37
+ static bool incompatible_library(void *handle, VALUE *failure_details);
38
+ static bool failed_to_initialize(void *handle, char *init_name, VALUE *failure_details);
39
+ static void set_failure_from_dlerror(VALUE *failure_details);
40
+ static void unload_failed_library(void *handle);
41
+
42
+ #define DDTRACE_EXPORT __attribute__ ((visibility ("default")))
43
+
44
+ void DDTRACE_EXPORT Init_ddtrace_profiling_loader() {
45
+ VALUE datadog_module = rb_define_module("Datadog");
46
+ VALUE profiling_module = rb_define_module_under(datadog_module, "Profiling");
47
+ VALUE loader_module = rb_define_module_under(profiling_module, "Loader");
48
+ rb_define_singleton_method(loader_module, "_native_load", _native_load, 2);
49
+
50
+ ok_symbol = ID2SYM(rb_intern_const("ok"));
51
+ error_symbol = ID2SYM(rb_intern_const("error"));
52
+ }
53
+
54
+ static VALUE _native_load(VALUE self, VALUE ruby_path, VALUE ruby_init_name) {
55
+ Check_Type(ruby_path, T_STRING);
56
+ Check_Type(ruby_init_name, T_STRING);
57
+
58
+ char *path = StringValueCStr(ruby_path);
59
+ char *init_name = StringValueCStr(ruby_init_name);
60
+
61
+ void *handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
62
+
63
+ VALUE failure_details = Qnil;
64
+
65
+ if (
66
+ failed_to_load(handle, &failure_details) ||
67
+ incompatible_library(handle, &failure_details) ||
68
+ failed_to_initialize(handle, init_name, &failure_details)
69
+ ) {
70
+ return rb_ary_new_from_args(2, error_symbol, failure_details);
71
+ }
72
+
73
+ return rb_ary_new_from_args(2, ok_symbol, Qnil);
74
+ }
75
+
76
+ static bool failed_to_load(void *handle, VALUE *failure_details) {
77
+ if (handle == NULL) {
78
+ set_failure_from_dlerror(failure_details);
79
+ return true;
80
+ } else {
81
+ return false;
82
+ }
83
+ }
84
+
85
+ static bool incompatible_library(void *handle, VALUE *failure_details) {
86
+ // The library being loaded may be linked to a different libruby than the current executing Ruby.
87
+ // We check if this is the case by checking if a well-known symbol resolves to a common address.
88
+ if (dlsym(handle, "ruby_xmalloc") != &ruby_xmalloc) {
89
+ *failure_details = rb_str_new_cstr("library was compiled and linked to a different Ruby version");
90
+ unload_failed_library(handle);
91
+ return true;
92
+ } else {
93
+ return false;
94
+ }
95
+ }
96
+
97
+ static bool failed_to_initialize(void *handle, char *init_name, VALUE *failure_details) {
98
+ void (*initialization_function)(void) = dlsym(handle, init_name);
99
+
100
+ if (initialization_function == NULL) {
101
+ set_failure_from_dlerror(failure_details);
102
+ unload_failed_library(handle);
103
+ return true;
104
+ } else {
105
+ (*initialization_function)();
106
+ return false;
107
+ }
108
+ }
109
+
110
+ static void set_failure_from_dlerror(VALUE *failure_details) {
111
+ char *failure = dlerror();
112
+ *failure_details = failure == NULL ? Qnil : rb_str_new_cstr(failure);
113
+ }
114
+
115
+ static void unload_failed_library(void *handle) {
116
+ // Note: According to the Ruby VM sources, this may fail with a segfault on really old versions of macOS (< 10.11)
117
+ dlclose(handle);
118
+ }
@@ -0,0 +1,53 @@
1
+ # typed: ignore
2
+ # rubocop:disable Style/StderrPuts
3
+ # rubocop:disable Style/GlobalVars
4
+
5
+ if RUBY_ENGINE != 'ruby' || Gem.win_platform?
6
+ $stderr.puts(
7
+ 'WARN: Skipping build of ddtrace profiling loader. See ddtrace profiling native extension note for details.'
8
+ )
9
+
10
+ File.write('Makefile', 'all install clean: # dummy makefile that does nothing')
11
+ exit
12
+ end
13
+
14
+ require 'mkmf'
15
+
16
+ # mkmf on modern Rubies actually has an append_cflags that does something similar
17
+ # (see https://github.com/ruby/ruby/pull/5760), but as usual we need a bit more boilerplate to deal with legacy Rubies
18
+ def add_compiler_flag(flag)
19
+ if try_cflags(flag)
20
+ $CFLAGS << ' ' << flag
21
+ else
22
+ $stderr.puts("WARNING: '#{flag}' not accepted by compiler, skipping it")
23
+ end
24
+ end
25
+
26
+ # Gets really noisy when we include the MJIT header, let's omit it
27
+ add_compiler_flag '-Wno-unused-function'
28
+
29
+ # Allow defining variables at any point in a function
30
+ add_compiler_flag '-Wno-declaration-after-statement'
31
+
32
+ # If we forget to include a Ruby header, the function call may still appear to work, but then
33
+ # cause a segfault later. Let's ensure that never happens.
34
+ add_compiler_flag '-Werror-implicit-function-declaration'
35
+
36
+ # The native extension is not intended to expose any symbols/functions for other native libraries to use;
37
+ # the sole exception being `Init_ddtrace_profiling_loader` which needs to be visible for Ruby to call it when
38
+ # it `dlopen`s the library.
39
+ #
40
+ # By setting this compiler flag, we tell it to assume that everything is private unless explicitly stated.
41
+ # For more details see https://gcc.gnu.org/wiki/Visibility
42
+ add_compiler_flag '-fvisibility=hidden'
43
+
44
+ # Tag the native extension library with the Ruby version and Ruby platform.
45
+ # This makes it easier for development (avoids "oops I forgot to rebuild when I switched my Ruby") and ensures that
46
+ # the wrong library is never loaded.
47
+ # When requiring, we need to use the exact same string, including the version and the platform.
48
+ EXTENSION_NAME = "ddtrace_profiling_loader.#{RUBY_VERSION}_#{RUBY_PLATFORM}".freeze
49
+
50
+ create_makefile(EXTENSION_NAME)
51
+
52
+ # rubocop:enable Style/GlobalVars
53
+ # rubocop:enable Style/StderrPuts
@@ -1,9 +1,11 @@
1
1
  # Profiling Native Extension Design
2
2
 
3
- The profiling native extension is used to implement features which are expensive (in terms of resources) or otherwise
4
- impossible to implement using Ruby code.
3
+ The profiling native extension is used to:
4
+ 1. Implement features which are expensive (in terms of resources) or otherwise impossible to implement using Ruby code.
5
+ 2. Bridge between Ruby-specific profiling features and [`libddprof`](https://github.com/DataDog/libddprof), a Rust-based
6
+ library with common profiling functionality.
5
7
 
6
- This extension is quite coupled with MRI Ruby ("C Ruby") internals, and is not intended to support other rubies such as
8
+ Due to (1), this extension is quite coupled with MRI Ruby ("C Ruby") internals, and is not intended to support other rubies such as
7
9
  JRuby or TruffleRuby. When below we say "Ruby", read it as "MRI Ruby".
8
10
 
9
11
  ## Disabling
@@ -16,17 +18,41 @@ the gem. Setting `DD_PROFILING_NO_EXTENSION` at installation time skips compilat
16
18
  Currently the profiler can still "limp along" when the native extension is disabled, but the plan is to require it
17
19
  in future releases -- e.g. disabling the extension will disable profiling entirely.
18
20
 
19
- ## Safety
21
+ ## Must not block or break users that cannot use it
20
22
 
21
23
  The profiling native extension is (and must always be) designed to **not cause failures** during gem installation, even
22
24
  if some features, Ruby versions, or operating systems are not supported.
23
25
 
24
- E.g. the extension must cleanly build on Ruby 2.1 (or the oldest Ruby version we support at the time) on Windows,
26
+ E.g. the extension must not break installation on Ruby 2.1 (or the oldest Ruby version we support at the time) on 64-bit ARM macOS,
25
27
  even if at run time it will effectively do nothing for such a setup.
26
28
 
27
29
  We have a CI setup to help validate this, but this is really important to keep in mind when adding to or changing the
28
30
  existing codebase.
29
31
 
32
+ ## Memory leaks and Interaction with Ruby VM APIs
33
+
34
+ When adding to or changing the native extension, we must always consider what API calls can lead to Ruby exceptions to
35
+ be raised, and whether there are is dynamically-allocated memory that can be leaked if that happens.
36
+
37
+ (When a Ruby exception is raised, the VM will use `setjmp` and `longjmp` to jump back in the stack and thus skip
38
+ our clean-up code, like in a Ruby-level exception.)
39
+
40
+ We avoid issues using a combination of:
41
+
42
+ * Avoiding dynamic allocation as much as possible
43
+ * Getting all needed data and doing all validations before doing any dynamic allocations
44
+ * Avoiding calling Ruby VM APIs after doing dynamic allocations
45
+ * Wrapping dynamic allocations into Ruby GC-managed objects (using `TypedData_Wrap_Struct`), so that Ruby will manage
46
+ their lifetime and call `free` when the GC-managed object is no longer being referenced
47
+
48
+ Non-exhaustive list of APIs that cause exceptions to be raised:
49
+
50
+ * `Check_TypedStruct`, `Check_Type`
51
+ * `rb_funcall`
52
+ * `rb_thread_call_without_gvl`, `rb_thread_call_without_gvl2`
53
+ * [Numeric conversion APIs, e.g. `NUM2LONG`, `NUM2INT`, etc.](https://silverhammermba.github.io/emberb/c/?utm_source=pocket_mylist#translation)
54
+ * Our `char_slice_from_ruby_string` helper
55
+
30
56
  ## Usage of private VM headers
31
57
 
32
58
  To implement some of the features below, we sometimes require access to private Ruby header files (that describe VM
@@ -9,15 +9,7 @@
9
9
  #include <errno.h>
10
10
 
11
11
  #include <ruby.h>
12
-
13
- #ifdef RUBY_2_1_WORKAROUND
14
- #include <thread_native.h>
15
- #else
16
- #include <ruby/thread_native.h>
17
- #endif
18
-
19
12
  #include "private_vm_api_access.h"
20
-
21
13
  #include "clock_id.h"
22
14
 
23
15
  // Validate that our home-cooked pthread_id_for() matches pthread_self() for the current thread