ddtrace 1.18.0 → 1.20.0
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 +4 -4
- data/CHANGELOG.md +82 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +96 -66
- data/ext/ddtrace_profiling_native_extension/collectors_discrete_dynamic_sampler.c +349 -0
- data/ext/ddtrace_profiling_native_extension/collectors_discrete_dynamic_sampler.h +89 -0
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.c +22 -14
- data/ext/ddtrace_profiling_native_extension/collectors_dynamic_sampling_rate.h +4 -0
- data/ext/ddtrace_profiling_native_extension/collectors_gc_profiling_helper.c +156 -0
- data/ext/ddtrace_profiling_native_extension/collectors_gc_profiling_helper.h +5 -0
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +43 -102
- data/ext/ddtrace_profiling_native_extension/collectors_stack.h +10 -3
- data/ext/ddtrace_profiling_native_extension/collectors_thread_context.c +159 -124
- data/ext/ddtrace_profiling_native_extension/collectors_thread_context.h +2 -1
- data/ext/ddtrace_profiling_native_extension/extconf.rb +19 -0
- data/ext/ddtrace_profiling_native_extension/heap_recorder.c +970 -0
- data/ext/ddtrace_profiling_native_extension/heap_recorder.h +155 -0
- data/ext/ddtrace_profiling_native_extension/helpers.h +6 -0
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.c +20 -0
- data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +11 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +5 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +17 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +147 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +28 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +329 -10
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +3 -0
- data/ext/ddtrace_profiling_native_extension/time_helpers.h +2 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -1
- data/lib/datadog/core/configuration/settings.rb +153 -21
- data/lib/datadog/core/environment/class_count.rb +6 -6
- data/lib/datadog/core/remote/component.rb +25 -12
- data/lib/datadog/core/remote/ext.rb +1 -0
- data/lib/datadog/core/remote/tie/tracing.rb +39 -0
- data/lib/datadog/core/remote/tie.rb +27 -0
- data/lib/datadog/core/telemetry/collector.rb +10 -0
- data/lib/datadog/core/telemetry/event.rb +2 -1
- data/lib/datadog/core/telemetry/ext.rb +3 -0
- data/lib/datadog/core/telemetry/v1/app_event.rb +8 -1
- data/lib/datadog/core/telemetry/v1/install_signature.rb +38 -0
- data/lib/datadog/opentelemetry/sdk/propagator.rb +3 -2
- data/lib/datadog/opentelemetry.rb +3 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -12
- data/lib/datadog/profiling/component.rb +183 -13
- data/lib/datadog/profiling/scheduler.rb +4 -6
- data/lib/datadog/profiling/stack_recorder.rb +13 -2
- data/lib/datadog/tracing/configuration/ext.rb +0 -1
- data/lib/datadog/tracing/configuration/settings.rb +2 -1
- data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_cable/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_mailer/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_pack/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/action_view/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_job/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_record/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/active_support/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/analytics.rb +0 -1
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/delayed_job/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +7 -0
- data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -1
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/grape/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +2 -2
- data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/kafka/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +5 -0
- data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -1
- data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/qless/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/racecar/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +9 -2
- data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +0 -2
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rake/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/patcher.rb +34 -21
- data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/resque/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sequel/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/shoryuken/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/stripe/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +58 -0
- data/lib/datadog/tracing/contrib/trilogy/ext.rb +27 -0
- data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +94 -0
- data/lib/datadog/tracing/contrib/trilogy/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/trilogy/patcher.rb +31 -0
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing.rb +8 -2
- data/lib/ddtrace/version.rb +1 -1
- metadata +20 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1baa733b2ad3335ab214de620e849f1eab598effb15d24f336aa20147e6e34be
|
|
4
|
+
data.tar.gz: 684bbf501475346f6e2a32b5a9284d59e193344e23d63b912624de77ac8bbbad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a10dcafb4ff9e9655e06e149ae83a872a0b614f44d69db15ed120f6aa6990f858bb94897d7b8fe30c1b41fe74dc71f054bdf7f0387ded0c0b66058d0d9a15492
|
|
7
|
+
data.tar.gz: 87be0dc85c2fc044a0f95096d147dbc79dda101babad85bfdfd29a37c42cd9cb70180fdedae00ff95321fe6eec0e4d61a6aaab852c9c6d3f10fc39ff7f06d87c
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.20.0] - 2024-02-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
* Tracing: Add `Trilogy` instrumentation ([#3274][])
|
|
10
|
+
* Rack: Add remote configuration boot tags ([#3315][])
|
|
11
|
+
* Faraday: Add `on_error` option ([#3431][])
|
|
12
|
+
* Profiling: Add dynamic allocation sampling ([#3395][])
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
* Bump `datadog-ci` dependency to 0.7.0 ([#3408][])
|
|
17
|
+
* Improve performance of gathering ClassCount metric ([#3386][])
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
* OpenTelemetry: Fix internal loading ([#3400][])
|
|
22
|
+
* Core: Fix logger deadlock ([#3426][])
|
|
23
|
+
* Rack: Fix missing active trace ([#3420][])
|
|
24
|
+
* Redis: Fix instance configuration ([#3278][])
|
|
25
|
+
|
|
26
|
+
## [1.19.0] - 2024-01-10
|
|
27
|
+
|
|
28
|
+
### Highlights
|
|
29
|
+
Alpha support for memory profiling has been added. For more details, check the [release notes](https://github.com/DataDog/dd-trace-rb/releases/tag/v1.19.0)
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
* Tracing: Add `on_error` settings for `mysql2` ([#3316][])
|
|
33
|
+
* Core: Add install_signature to app-started telemetry event ([#3349][])
|
|
34
|
+
* Profiling: Heap Profiling ([#3281][]) ([#3287][]) ([#3328][]) ([#3329][]) ([#3333][]) ([#3360][])
|
|
35
|
+
* Profiling: Redesign GC profiling to add timeline support and reduce overhead ([#3313][])
|
|
36
|
+
* Core: Use Ruby 3.3 stable for CI testing ([#3354][])
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
* Core: Bump `datadog-ci` dependency to 0.6.0 ([#3361][])
|
|
40
|
+
* Core: Bump debase-ruby_core_source dependency to 3.3.1 ([#3373][])
|
|
41
|
+
* Docs: Backport "List Ruby 3.3 as supported in the docs" to master branch ([#3374][])
|
|
42
|
+
* Profiling: Import upstream `rb_profile_frames` fix ([#3352][])
|
|
43
|
+
* Profiling: Allow the dynamic sampling rate overhead target to be set ([#3310][])
|
|
44
|
+
* Profiling: Split profiling tests into ractor and non-ractor suites. ([#3320][])
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
* Docs: Fix `pg` doc markdown format ([#3317][])
|
|
48
|
+
* Tracing: Fix recursive `require` in Railtie ([#3365][])
|
|
49
|
+
* Profiling: Fix issues stemming from rb_gc_force_recycle ([#3366][])
|
|
50
|
+
* Profiling: Fix Ruby 3.3 CI being broken in master due to profiler ([#3356][])
|
|
51
|
+
* Profiling: Fix "no signals" workaround detection when mariadb is in use ([#3362][])
|
|
52
|
+
|
|
5
53
|
## [1.18.0] - 2023-12-07
|
|
6
54
|
|
|
7
55
|
### Added
|
|
@@ -2680,7 +2728,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
|
|
|
2680
2728
|
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2681
2729
|
|
|
2682
2730
|
|
|
2683
|
-
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.
|
|
2731
|
+
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.20.0...master
|
|
2732
|
+
[1.20.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.19.0...v1.20.0
|
|
2733
|
+
[1.19.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.18.0...v1.19.0
|
|
2684
2734
|
[1.18.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.17.0...v1.18.0
|
|
2685
2735
|
[1.17.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.16.2...v1.17.0
|
|
2686
2736
|
[1.16.2]: https://github.com/DataDog/dd-trace-rb/compare/v1.16.1...v1.16.2
|
|
@@ -3908,14 +3958,45 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
|
3908
3958
|
[#3270]: https://github.com/DataDog/dd-trace-rb/issues/3270
|
|
3909
3959
|
[#3271]: https://github.com/DataDog/dd-trace-rb/issues/3271
|
|
3910
3960
|
[#3273]: https://github.com/DataDog/dd-trace-rb/issues/3273
|
|
3961
|
+
[#3274]: https://github.com/DataDog/dd-trace-rb/issues/3274
|
|
3962
|
+
[#3278]: https://github.com/DataDog/dd-trace-rb/issues/3278
|
|
3911
3963
|
[#3279]: https://github.com/DataDog/dd-trace-rb/issues/3279
|
|
3912
3964
|
[#3280]: https://github.com/DataDog/dd-trace-rb/issues/3280
|
|
3965
|
+
[#3281]: https://github.com/DataDog/dd-trace-rb/issues/3281
|
|
3913
3966
|
[#3284]: https://github.com/DataDog/dd-trace-rb/issues/3284
|
|
3914
3967
|
[#3286]: https://github.com/DataDog/dd-trace-rb/issues/3286
|
|
3968
|
+
[#3287]: https://github.com/DataDog/dd-trace-rb/issues/3287
|
|
3915
3969
|
[#3289]: https://github.com/DataDog/dd-trace-rb/issues/3289
|
|
3916
3970
|
[#3303]: https://github.com/DataDog/dd-trace-rb/issues/3303
|
|
3917
3971
|
[#3307]: https://github.com/DataDog/dd-trace-rb/issues/3307
|
|
3918
3972
|
[#3308]: https://github.com/DataDog/dd-trace-rb/issues/3308
|
|
3973
|
+
[#3310]: https://github.com/DataDog/dd-trace-rb/issues/3310
|
|
3974
|
+
[#3313]: https://github.com/DataDog/dd-trace-rb/issues/3313
|
|
3975
|
+
[#3315]: https://github.com/DataDog/dd-trace-rb/issues/3315
|
|
3976
|
+
[#3316]: https://github.com/DataDog/dd-trace-rb/issues/3316
|
|
3977
|
+
[#3317]: https://github.com/DataDog/dd-trace-rb/issues/3317
|
|
3978
|
+
[#3320]: https://github.com/DataDog/dd-trace-rb/issues/3320
|
|
3979
|
+
[#3328]: https://github.com/DataDog/dd-trace-rb/issues/3328
|
|
3980
|
+
[#3329]: https://github.com/DataDog/dd-trace-rb/issues/3329
|
|
3981
|
+
[#3333]: https://github.com/DataDog/dd-trace-rb/issues/3333
|
|
3982
|
+
[#3349]: https://github.com/DataDog/dd-trace-rb/issues/3349
|
|
3983
|
+
[#3352]: https://github.com/DataDog/dd-trace-rb/issues/3352
|
|
3984
|
+
[#3354]: https://github.com/DataDog/dd-trace-rb/issues/3354
|
|
3985
|
+
[#3356]: https://github.com/DataDog/dd-trace-rb/issues/3356
|
|
3986
|
+
[#3360]: https://github.com/DataDog/dd-trace-rb/issues/3360
|
|
3987
|
+
[#3361]: https://github.com/DataDog/dd-trace-rb/issues/3361
|
|
3988
|
+
[#3362]: https://github.com/DataDog/dd-trace-rb/issues/3362
|
|
3989
|
+
[#3365]: https://github.com/DataDog/dd-trace-rb/issues/3365
|
|
3990
|
+
[#3366]: https://github.com/DataDog/dd-trace-rb/issues/3366
|
|
3991
|
+
[#3373]: https://github.com/DataDog/dd-trace-rb/issues/3373
|
|
3992
|
+
[#3374]: https://github.com/DataDog/dd-trace-rb/issues/3374
|
|
3993
|
+
[#3386]: https://github.com/DataDog/dd-trace-rb/issues/3386
|
|
3994
|
+
[#3395]: https://github.com/DataDog/dd-trace-rb/issues/3395
|
|
3995
|
+
[#3400]: https://github.com/DataDog/dd-trace-rb/issues/3400
|
|
3996
|
+
[#3408]: https://github.com/DataDog/dd-trace-rb/issues/3408
|
|
3997
|
+
[#3420]: https://github.com/DataDog/dd-trace-rb/issues/3420
|
|
3998
|
+
[#3426]: https://github.com/DataDog/dd-trace-rb/issues/3426
|
|
3999
|
+
[#3431]: https://github.com/DataDog/dd-trace-rb/issues/3431
|
|
3919
4000
|
[@AdrianLC]: https://github.com/AdrianLC
|
|
3920
4001
|
[@Azure7111]: https://github.com/Azure7111
|
|
3921
4002
|
[@BabyGroot]: https://github.com/BabyGroot
|
|
@@ -12,10 +12,14 @@
|
|
|
12
12
|
#include "collectors_thread_context.h"
|
|
13
13
|
#include "collectors_dynamic_sampling_rate.h"
|
|
14
14
|
#include "collectors_idle_sampling_helper.h"
|
|
15
|
+
#include "collectors_discrete_dynamic_sampler.h"
|
|
15
16
|
#include "private_vm_api_access.h"
|
|
16
17
|
#include "setup_signal_handler.h"
|
|
17
18
|
#include "time_helpers.h"
|
|
18
19
|
|
|
20
|
+
// Maximum allowed value for an allocation weight. Attempts to use higher values will result in clamping.
|
|
21
|
+
unsigned int MAX_ALLOC_WEIGHT = 65535;
|
|
22
|
+
|
|
19
23
|
// Used to trigger the execution of Collectors::ThreadState, which implements all of the sampling logic
|
|
20
24
|
// itself; this class only implements the "when to do it" part.
|
|
21
25
|
//
|
|
@@ -75,20 +79,27 @@
|
|
|
75
79
|
//
|
|
76
80
|
// ---
|
|
77
81
|
|
|
82
|
+
#ifndef NO_POSTPONED_TRIGGER
|
|
83
|
+
// Used to call the rb_postponed_job_trigger from Ruby 3.3+. These get initialized in
|
|
84
|
+
// `collectors_cpu_and_wall_time_worker_init` below and always get reused after that.
|
|
85
|
+
static rb_postponed_job_handle_t sample_from_postponed_job_handle;
|
|
86
|
+
static rb_postponed_job_handle_t after_gc_from_postponed_job_handle;
|
|
87
|
+
#endif
|
|
88
|
+
|
|
78
89
|
// Contains state for a single CpuAndWallTimeWorker instance
|
|
79
90
|
struct cpu_and_wall_time_worker_state {
|
|
80
91
|
// These are immutable after initialization
|
|
81
92
|
|
|
82
93
|
bool gc_profiling_enabled;
|
|
83
|
-
bool allocation_counting_enabled;
|
|
84
94
|
bool no_signals_workaround_enabled;
|
|
85
95
|
bool dynamic_sampling_rate_enabled;
|
|
86
|
-
|
|
96
|
+
bool allocation_profiling_enabled;
|
|
87
97
|
VALUE self_instance;
|
|
88
98
|
VALUE thread_context_collector_instance;
|
|
89
99
|
VALUE idle_sampling_helper_instance;
|
|
90
100
|
VALUE owner_thread;
|
|
91
|
-
dynamic_sampling_rate_state
|
|
101
|
+
dynamic_sampling_rate_state cpu_dynamic_sampling_rate;
|
|
102
|
+
discrete_dynamic_sampler allocation_sampler;
|
|
92
103
|
VALUE gc_tracepoint; // Used to get gc start/finish information
|
|
93
104
|
VALUE object_allocation_tracepoint; // Used to get allocation counts and allocation profiling
|
|
94
105
|
|
|
@@ -149,10 +160,10 @@ static VALUE _native_initialize(
|
|
|
149
160
|
VALUE thread_context_collector_instance,
|
|
150
161
|
VALUE gc_profiling_enabled,
|
|
151
162
|
VALUE idle_sampling_helper_instance,
|
|
152
|
-
VALUE allocation_counting_enabled,
|
|
153
163
|
VALUE no_signals_workaround_enabled,
|
|
154
164
|
VALUE dynamic_sampling_rate_enabled,
|
|
155
|
-
VALUE
|
|
165
|
+
VALUE dynamic_sampling_rate_overhead_target_percentage,
|
|
166
|
+
VALUE allocation_profiling_enabled
|
|
156
167
|
);
|
|
157
168
|
static void cpu_and_wall_time_worker_typed_data_mark(void *state_ptr);
|
|
158
169
|
static VALUE _native_sampling_loop(VALUE self, VALUE instance);
|
|
@@ -211,6 +222,16 @@ __thread uint64_t allocation_count = 0;
|
|
|
211
222
|
void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module) {
|
|
212
223
|
rb_global_variable(&active_sampler_instance);
|
|
213
224
|
|
|
225
|
+
#ifndef NO_POSTPONED_TRIGGER
|
|
226
|
+
int unused_flags = 0;
|
|
227
|
+
sample_from_postponed_job_handle = rb_postponed_job_preregister(unused_flags, sample_from_postponed_job, NULL);
|
|
228
|
+
after_gc_from_postponed_job_handle = rb_postponed_job_preregister(unused_flags, after_gc_from_postponed_job, NULL);
|
|
229
|
+
|
|
230
|
+
if (sample_from_postponed_job_handle == POSTPONED_JOB_HANDLE_INVALID || after_gc_from_postponed_job_handle == POSTPONED_JOB_HANDLE_INVALID) {
|
|
231
|
+
rb_raise(rb_eRuntimeError, "Failed to register profiler postponed jobs (got POSTPONED_JOB_HANDLE_INVALID)");
|
|
232
|
+
}
|
|
233
|
+
#endif
|
|
234
|
+
|
|
214
235
|
VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
|
|
215
236
|
VALUE collectors_cpu_and_wall_time_worker_class = rb_define_class_under(collectors_module, "CpuAndWallTimeWorker", rb_cObject);
|
|
216
237
|
// Hosts methods used for testing the native code using RSpec
|
|
@@ -264,14 +285,14 @@ static VALUE _native_new(VALUE klass) {
|
|
|
264
285
|
// being leaked.
|
|
265
286
|
|
|
266
287
|
state->gc_profiling_enabled = false;
|
|
267
|
-
state->allocation_counting_enabled = false;
|
|
268
288
|
state->no_signals_workaround_enabled = false;
|
|
269
289
|
state->dynamic_sampling_rate_enabled = true;
|
|
270
|
-
state->
|
|
290
|
+
state->allocation_profiling_enabled = false;
|
|
271
291
|
state->thread_context_collector_instance = Qnil;
|
|
272
292
|
state->idle_sampling_helper_instance = Qnil;
|
|
273
293
|
state->owner_thread = Qnil;
|
|
274
|
-
dynamic_sampling_rate_init(&state->
|
|
294
|
+
dynamic_sampling_rate_init(&state->cpu_dynamic_sampling_rate);
|
|
295
|
+
discrete_dynamic_sampler_init(&state->allocation_sampler, "allocation");
|
|
275
296
|
state->gc_tracepoint = Qnil;
|
|
276
297
|
state->object_allocation_tracepoint = Qnil;
|
|
277
298
|
|
|
@@ -292,28 +313,33 @@ static VALUE _native_initialize(
|
|
|
292
313
|
VALUE thread_context_collector_instance,
|
|
293
314
|
VALUE gc_profiling_enabled,
|
|
294
315
|
VALUE idle_sampling_helper_instance,
|
|
295
|
-
VALUE allocation_counting_enabled,
|
|
296
316
|
VALUE no_signals_workaround_enabled,
|
|
297
317
|
VALUE dynamic_sampling_rate_enabled,
|
|
298
|
-
VALUE
|
|
318
|
+
VALUE dynamic_sampling_rate_overhead_target_percentage,
|
|
319
|
+
VALUE allocation_profiling_enabled
|
|
299
320
|
) {
|
|
300
321
|
ENFORCE_BOOLEAN(gc_profiling_enabled);
|
|
301
|
-
ENFORCE_BOOLEAN(allocation_counting_enabled);
|
|
302
322
|
ENFORCE_BOOLEAN(no_signals_workaround_enabled);
|
|
303
323
|
ENFORCE_BOOLEAN(dynamic_sampling_rate_enabled);
|
|
304
|
-
ENFORCE_TYPE(
|
|
324
|
+
ENFORCE_TYPE(dynamic_sampling_rate_overhead_target_percentage, T_FLOAT);
|
|
325
|
+
ENFORCE_BOOLEAN(allocation_profiling_enabled);
|
|
305
326
|
|
|
306
327
|
struct cpu_and_wall_time_worker_state *state;
|
|
307
328
|
TypedData_Get_Struct(self_instance, struct cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
|
|
308
329
|
|
|
309
330
|
state->gc_profiling_enabled = (gc_profiling_enabled == Qtrue);
|
|
310
|
-
state->allocation_counting_enabled = (allocation_counting_enabled == Qtrue);
|
|
311
331
|
state->no_signals_workaround_enabled = (no_signals_workaround_enabled == Qtrue);
|
|
312
332
|
state->dynamic_sampling_rate_enabled = (dynamic_sampling_rate_enabled == Qtrue);
|
|
313
|
-
state->
|
|
333
|
+
state->allocation_profiling_enabled = (allocation_profiling_enabled == Qtrue);
|
|
314
334
|
|
|
315
|
-
|
|
316
|
-
|
|
335
|
+
double total_overhead_target_percentage = NUM2DBL(dynamic_sampling_rate_overhead_target_percentage);
|
|
336
|
+
if (!state->allocation_profiling_enabled) {
|
|
337
|
+
dynamic_sampling_rate_set_overhead_target_percentage(&state->cpu_dynamic_sampling_rate, total_overhead_target_percentage);
|
|
338
|
+
} else {
|
|
339
|
+
// TODO: May be nice to offer customization here? Distribute available "overhead" margin with a bias towards one or the other
|
|
340
|
+
// sampler.
|
|
341
|
+
dynamic_sampling_rate_set_overhead_target_percentage(&state->cpu_dynamic_sampling_rate, total_overhead_target_percentage / 2);
|
|
342
|
+
discrete_dynamic_sampler_set_overhead_target_percentage(&state->allocation_sampler, total_overhead_target_percentage / 2);
|
|
317
343
|
}
|
|
318
344
|
|
|
319
345
|
state->thread_context_collector_instance = enforce_thread_context_collector_instance(thread_context_collector_instance);
|
|
@@ -366,7 +392,8 @@ static VALUE _native_sampling_loop(DDTRACE_UNUSED VALUE _self, VALUE instance) {
|
|
|
366
392
|
if (state->stop_thread == rb_thread_current()) return Qnil;
|
|
367
393
|
|
|
368
394
|
// Reset the dynamic sampling rate state, if any (reminder: the monotonic clock reference may change after a fork)
|
|
369
|
-
dynamic_sampling_rate_reset(&state->
|
|
395
|
+
dynamic_sampling_rate_reset(&state->cpu_dynamic_sampling_rate);
|
|
396
|
+
discrete_dynamic_sampler_reset(&state->allocation_sampler);
|
|
370
397
|
|
|
371
398
|
// This write to a global is thread-safe BECAUSE we're still holding on to the global VM lock at this point
|
|
372
399
|
active_sampler_instance_state = state;
|
|
@@ -472,20 +499,25 @@ static void handle_sampling_signal(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED si
|
|
|
472
499
|
|
|
473
500
|
// Note: If we ever want to get rid of rb_postponed_job_register_one, remember not to clobber Ruby exceptions, as
|
|
474
501
|
// this function does this helpful job for us now -- https://github.com/ruby/ruby/commit/a98e343d39c4d7bf1e2190b076720f32d9f298b3.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
502
|
+
#ifndef NO_POSTPONED_TRIGGER // Ruby 3.3+
|
|
503
|
+
rb_postponed_job_trigger(sample_from_postponed_job_handle);
|
|
504
|
+
state->stats.postponed_job_success++; // Always succeeds
|
|
505
|
+
#else
|
|
506
|
+
int result = rb_postponed_job_register_one(0, sample_from_postponed_job, NULL);
|
|
507
|
+
|
|
508
|
+
// Officially, the result of rb_postponed_job_register_one is documented as being opaque, but in practice it does not
|
|
509
|
+
// seem to have changed between Ruby 2.3 and 3.2, and so we track it as a debugging mechanism
|
|
510
|
+
switch (result) {
|
|
511
|
+
case 0:
|
|
512
|
+
state->stats.postponed_job_full++; break;
|
|
513
|
+
case 1:
|
|
514
|
+
state->stats.postponed_job_success++; break;
|
|
515
|
+
case 2:
|
|
516
|
+
state->stats.postponed_job_skipped_already_existed++; break;
|
|
517
|
+
default:
|
|
518
|
+
state->stats.postponed_job_unknown_result++;
|
|
519
|
+
}
|
|
520
|
+
#endif
|
|
489
521
|
}
|
|
490
522
|
|
|
491
523
|
// The actual sampling trigger loop always runs **without** the global vm lock.
|
|
@@ -534,7 +566,7 @@ static void *run_sampling_trigger_loop(void *state_ptr) {
|
|
|
534
566
|
// Note that we deliberately should NOT combine this sleep_for with the one above because the result of
|
|
535
567
|
// `dynamic_sampling_rate_get_sleep` may have changed while the above sleep was ongoing.
|
|
536
568
|
uint64_t extra_sleep =
|
|
537
|
-
dynamic_sampling_rate_get_sleep(&state->
|
|
569
|
+
dynamic_sampling_rate_get_sleep(&state->cpu_dynamic_sampling_rate, monotonic_wall_time_now_ns(DO_NOT_RAISE_ON_FAILURE));
|
|
538
570
|
if (state->dynamic_sampling_rate_enabled && extra_sleep > 0) sleep_for(extra_sleep);
|
|
539
571
|
}
|
|
540
572
|
|
|
@@ -574,7 +606,7 @@ static VALUE rescued_sample_from_postponed_job(VALUE self_instance) {
|
|
|
574
606
|
|
|
575
607
|
long wall_time_ns_before_sample = monotonic_wall_time_now_ns(RAISE_ON_FAILURE);
|
|
576
608
|
|
|
577
|
-
if (state->dynamic_sampling_rate_enabled && !dynamic_sampling_rate_should_sample(&state->
|
|
609
|
+
if (state->dynamic_sampling_rate_enabled && !dynamic_sampling_rate_should_sample(&state->cpu_dynamic_sampling_rate, wall_time_ns_before_sample)) {
|
|
578
610
|
state->stats.skipped_sample_because_of_dynamic_sampling_rate++;
|
|
579
611
|
return Qnil;
|
|
580
612
|
}
|
|
@@ -594,7 +626,7 @@ static VALUE rescued_sample_from_postponed_job(VALUE self_instance) {
|
|
|
594
626
|
state->stats.sampling_time_ns_max = uint64_max_of(sampling_time_ns, state->stats.sampling_time_ns_max);
|
|
595
627
|
state->stats.sampling_time_ns_total += sampling_time_ns;
|
|
596
628
|
|
|
597
|
-
dynamic_sampling_rate_after_sample(&state->
|
|
629
|
+
dynamic_sampling_rate_after_sample(&state->cpu_dynamic_sampling_rate, wall_time_ns_after_sample, sampling_time_ns);
|
|
598
630
|
|
|
599
631
|
// Return a dummy VALUE because we're called from rb_rescue2 which requires it
|
|
600
632
|
return Qnil;
|
|
@@ -632,7 +664,7 @@ static VALUE release_gvl_and_run_sampling_trigger_loop(VALUE instance) {
|
|
|
632
664
|
// because they may raise exceptions.
|
|
633
665
|
install_sigprof_signal_handler(handle_sampling_signal, "handle_sampling_signal");
|
|
634
666
|
if (state->gc_profiling_enabled) rb_tracepoint_enable(state->gc_tracepoint);
|
|
635
|
-
if (state->
|
|
667
|
+
if (state->allocation_profiling_enabled) rb_tracepoint_enable(state->object_allocation_tracepoint);
|
|
636
668
|
|
|
637
669
|
rb_thread_call_without_gvl(run_sampling_trigger_loop, state, interrupt_sampling_trigger_loop, state);
|
|
638
670
|
|
|
@@ -714,28 +746,17 @@ static void on_gc_event(VALUE tracepoint_data, DDTRACE_UNUSED void *unused) {
|
|
|
714
746
|
if (event == RUBY_INTERNAL_EVENT_GC_ENTER) {
|
|
715
747
|
thread_context_collector_on_gc_start(state->thread_context_collector_instance);
|
|
716
748
|
} else if (event == RUBY_INTERNAL_EVENT_GC_EXIT) {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
//
|
|
720
|
-
//
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
// making the sampling process allocation-safe (very hard); or separate stack sampling from sample recording,
|
|
729
|
-
// e.g. enabling us to capture the stack in thread_context_collector_on_gc_finish and do the rest later
|
|
730
|
-
// (medium hard).
|
|
731
|
-
|
|
732
|
-
thread_context_collector_on_gc_finish(state->thread_context_collector_instance);
|
|
733
|
-
// We use rb_postponed_job_register_one to ask Ruby to run thread_context_collector_sample_after_gc after if
|
|
734
|
-
// fully finishes the garbage collection, so that one is allowed to do allocations and throw exceptions as usual.
|
|
735
|
-
//
|
|
736
|
-
// Note: If we ever want to get rid of rb_postponed_job_register_one, remember not to clobber Ruby exceptions, as
|
|
737
|
-
// this function does this helpful job for us now -- https://github.com/ruby/ruby/commit/a98e343d39c4d7bf1e2190b076720f32d9f298b3.
|
|
738
|
-
rb_postponed_job_register_one(0, after_gc_from_postponed_job, NULL);
|
|
749
|
+
bool should_flush = thread_context_collector_on_gc_finish(state->thread_context_collector_instance);
|
|
750
|
+
|
|
751
|
+
// We use rb_postponed_job_register_one to ask Ruby to run thread_context_collector_sample_after_gc when the
|
|
752
|
+
// thread collector flags it's time to flush.
|
|
753
|
+
if (should_flush) {
|
|
754
|
+
#ifndef NO_POSTPONED_TRIGGER // Ruby 3.3+
|
|
755
|
+
rb_postponed_job_trigger(after_gc_from_postponed_job_handle);
|
|
756
|
+
#else
|
|
757
|
+
rb_postponed_job_register_one(0, after_gc_from_postponed_job, NULL);
|
|
758
|
+
#endif
|
|
759
|
+
}
|
|
739
760
|
}
|
|
740
761
|
}
|
|
741
762
|
|
|
@@ -888,9 +909,9 @@ static void sleep_for(uint64_t time_ns) {
|
|
|
888
909
|
}
|
|
889
910
|
|
|
890
911
|
static VALUE _native_allocation_count(DDTRACE_UNUSED VALUE self) {
|
|
891
|
-
bool
|
|
912
|
+
bool are_allocations_being_tracked = active_sampler_instance_state != NULL && active_sampler_instance_state->allocation_profiling_enabled;
|
|
892
913
|
|
|
893
|
-
return
|
|
914
|
+
return are_allocations_being_tracked ? ULL2NUM(allocation_count) : Qnil;
|
|
894
915
|
}
|
|
895
916
|
|
|
896
917
|
// Implements memory-related profiling events. This function is called by Ruby via the `object_allocation_tracepoint`
|
|
@@ -916,18 +937,20 @@ static void on_newobj_event(VALUE tracepoint_data, DDTRACE_UNUSED void *unused)
|
|
|
916
937
|
return;
|
|
917
938
|
}
|
|
918
939
|
|
|
940
|
+
if (state->dynamic_sampling_rate_enabled && !discrete_dynamic_sampler_should_sample(&state->allocation_sampler)) {
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
|
|
919
944
|
// @ivoanjo: Strictly speaking, this is not needed because Ruby should not call the same tracepoint while a previous
|
|
920
945
|
// invocation is still pending, (e.g. it wouldn't call `on_newobj_event` while it's already running), but I decided
|
|
921
946
|
// to keep this here for consistency -- every call to the thread context (other than the special gc calls which are
|
|
922
947
|
// defined as not being able to allocate) sets this.
|
|
923
948
|
state->during_sample = true;
|
|
924
949
|
|
|
925
|
-
//
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
safely_call(rescued_sample_allocation, tracepoint_data, state->self_instance);
|
|
930
|
-
}
|
|
950
|
+
// Rescue against any exceptions that happen during sampling
|
|
951
|
+
safely_call(rescued_sample_allocation, tracepoint_data, state->self_instance);
|
|
952
|
+
|
|
953
|
+
discrete_dynamic_sampler_after_sample(&state->allocation_sampler);
|
|
931
954
|
|
|
932
955
|
state->during_sample = false;
|
|
933
956
|
}
|
|
@@ -959,7 +982,14 @@ static VALUE rescued_sample_allocation(VALUE tracepoint_data) {
|
|
|
959
982
|
rb_trace_arg_t *data = rb_tracearg_from_tracepoint(tracepoint_data);
|
|
960
983
|
VALUE new_object = rb_tracearg_object(data);
|
|
961
984
|
|
|
962
|
-
|
|
985
|
+
unsigned long allocations_since_last_sample = state->dynamic_sampling_rate_enabled ?
|
|
986
|
+
// if we're doing dynamic sampling, ask the sampler how many events since last sample
|
|
987
|
+
discrete_dynamic_sampler_events_since_last_sample(&state->allocation_sampler) :
|
|
988
|
+
// if we aren't, then we're sampling every event
|
|
989
|
+
1;
|
|
990
|
+
// TODO: Signal in the profile that clamping happened?
|
|
991
|
+
unsigned int weight = allocations_since_last_sample > MAX_ALLOC_WEIGHT ? MAX_ALLOC_WEIGHT : (unsigned int) allocations_since_last_sample;
|
|
992
|
+
thread_context_collector_sample_allocation(state->thread_context_collector_instance, weight, new_object);
|
|
963
993
|
|
|
964
994
|
// Return a dummy VALUE because we're called from rb_rescue2 which requires it
|
|
965
995
|
return Qnil;
|