ddtrace 0.53.0 → 0.54.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -11
- data/ddtrace.gemspec +5 -2
- data/docs/GettingStarted.md +40 -3
- data/docs/ProfilingDevelopment.md +2 -2
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +86 -0
- data/ext/ddtrace_profiling_native_extension/clock_id.h +4 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +52 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +14 -0
- data/ext/ddtrace_profiling_native_extension/extconf.rb +144 -6
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +35 -0
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +6 -1
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +1 -0
- data/lib/datadog/ci/contrib/rspec/example.rb +1 -0
- data/lib/datadog/ci/ext/environment.rb +26 -21
- data/lib/datadog/ci/ext/test.rb +1 -0
- data/lib/datadog/ci/test.rb +5 -1
- data/lib/ddtrace/buffer.rb +28 -16
- data/lib/ddtrace/configuration/agent_settings_resolver.rb +27 -16
- data/lib/ddtrace/context.rb +10 -2
- data/lib/ddtrace/contrib/delayed_job/plugin.rb +2 -2
- data/lib/ddtrace/contrib/mongodb/instrumentation.rb +1 -1
- data/lib/ddtrace/contrib/mongodb/integration.rb +5 -0
- data/lib/ddtrace/contrib/rails/configuration/settings.rb +7 -0
- data/lib/ddtrace/contrib/rails/framework.rb +3 -2
- data/lib/ddtrace/contrib/redis/instrumentation.rb +90 -0
- data/lib/ddtrace/contrib/redis/patcher.rb +2 -84
- data/lib/ddtrace/contrib/resque/integration.rb +1 -5
- data/lib/ddtrace/ext/priority.rb +6 -4
- data/lib/ddtrace/ext/profiling.rb +1 -1
- data/lib/ddtrace/metrics.rb +2 -2
- data/lib/ddtrace/profiling/collectors/stack.rb +45 -45
- data/lib/ddtrace/profiling/encoding/profile.rb +1 -1
- data/lib/ddtrace/profiling/events/stack.rb +8 -8
- data/lib/ddtrace/profiling/native_extension.rb +23 -1
- data/lib/ddtrace/profiling/pprof/builder.rb +8 -2
- data/lib/ddtrace/profiling/pprof/stack_sample.rb +13 -16
- data/lib/ddtrace/profiling/pprof/template.rb +2 -2
- data/lib/ddtrace/profiling/tasks/setup.rb +21 -12
- data/lib/ddtrace/profiling/trace_identifiers/ddtrace.rb +9 -8
- data/lib/ddtrace/profiling/trace_identifiers/helper.rb +2 -2
- data/lib/ddtrace/profiling.rb +0 -2
- data/lib/ddtrace/sampler.rb +18 -8
- data/lib/ddtrace/sampling/rule_sampler.rb +13 -1
- data/lib/ddtrace/utils/time.rb +6 -0
- data/lib/ddtrace/version.rb +2 -2
- metadata +14 -9
- data/lib/ddtrace/profiling/ext/cpu.rb +0 -67
- data/lib/ddtrace/profiling/ext/cthread.rb +0 -156
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bef2da14245890c8187ebffd9cce972da89a177a806c6991f2e3050e1de62bc3
|
4
|
+
data.tar.gz: d37dcaf645e16177c6f7a3dd77628f2e5a4920c45fca8e3f78665c34a4d76db2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c59d7c5b2f363eb96f78ad602489ccbd0ed94ae9d6e856c70272ddb21ba467255179814db1831518789b7c32e9ab5d0f13421dd67ea585d0b39fe78849bcfe81
|
7
|
+
data.tar.gz: 97dcba8ee6eda7c3cafdb39946863d337ef67843ac7f071890ce6253786b9d9a26ca8a9f181a8c0dad44c01a3ffab53c146ea4848b6497552d26558f9f1278ce
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,53 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [0.54.1] - 2021-11-30
|
6
|
+
|
7
|
+
Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.54.1
|
8
|
+
|
9
|
+
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.54.0...v0.54.1
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
- Skip building profiling native extension when Ruby has been compiled without JIT ([#1774][], [#1776][])
|
14
|
+
|
15
|
+
## [0.54.0] - 2021-11-17
|
16
|
+
|
17
|
+
Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.54.0
|
18
|
+
|
19
|
+
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.53.0...v0.54.0
|
20
|
+
|
21
|
+
### Added
|
22
|
+
|
23
|
+
- MongoDB service name resolver when using multi cluster ([#1423][]) ([@skcc321][])
|
24
|
+
- Service name override for ActiveJob in Rails configuration ([#1703][], [#1770][]) ([@hatstand][])
|
25
|
+
- Profiler: Expose profile duration and start to the UI ([#1709][])
|
26
|
+
- Profiler: Gather CPU time without monkey patching Thread ([#1735][], [#1740][])
|
27
|
+
- Profiler: Link profiler samples to individual web requests ([#1688][])
|
28
|
+
- Profiler: Capture threads with empty backtrace ([#1719][])
|
29
|
+
- CI-App: Memoize environment tags to improve performance ([#1762][])
|
30
|
+
- CI-App: `test.framework_version` tag for rspec and cucumber ([#1713][])
|
31
|
+
|
32
|
+
### Changed
|
33
|
+
|
34
|
+
- Set minimum version of dogstatsd-ruby 5 series to 5.3 ([#1717][])
|
35
|
+
- Use USER_KEEP/USER_REJECT for RuleSampler decisions ([#1769][])
|
36
|
+
|
37
|
+
### Fixed
|
38
|
+
|
39
|
+
- "private method `ruby2_keywords' called" errors ([#1712][], [#1714][])
|
40
|
+
- Configuration warning when Agent port is a String ([#1720][])
|
41
|
+
- Ensure internal trace buffer respects its maximum size ([#1715][])
|
42
|
+
- Remove erroneous maximum resque version support ([#1761][])
|
43
|
+
- CI-App: Environment variables parsing precedence ([#1745][], [#1763][])
|
44
|
+
- CI-App: GitHub Metadata Extraction ([#1771][])
|
45
|
+
- Profiler: Missing thread id for natively created threads ([#1718][])
|
46
|
+
- Docs: Active Job integration example code ([#1721][]) ([@y-yagi][])
|
47
|
+
|
48
|
+
### Refactored
|
49
|
+
|
50
|
+
- Redis client patch to use prepend ([#1743][]) ([@justinhoward][])
|
51
|
+
|
5
52
|
## [0.53.0] - 2021-10-06
|
6
53
|
|
7
54
|
Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.53.0
|
@@ -17,6 +64,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.52.0...v0.53.0
|
|
17
64
|
- Runtime Metrics: Global VM cache statistics ([#1680][])
|
18
65
|
- Automatically send traces to agent Unix socket if present ([#1700][])
|
19
66
|
- CI-App: User Provided Git Metadata ([#1662][])
|
67
|
+
- ActionMailer integration ([#1280][])
|
20
68
|
|
21
69
|
### Changed
|
22
70
|
|
@@ -475,26 +523,26 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.39.0...v0.40.0
|
|
475
523
|
### Fixed
|
476
524
|
|
477
525
|
- Sinatra nested modular applications possibly leaking spans ([#1035][], [#1145][])
|
478
|
-
|
526
|
+
|
479
527
|
* **BREAKING** for nested modular Sinatra applications only:
|
480
528
|
```ruby
|
481
529
|
class Nested < Sinatra::Base
|
482
530
|
end
|
483
|
-
|
531
|
+
|
484
532
|
class TopLevel < Sinatra::Base
|
485
533
|
use Nested # Nesting happens here
|
486
534
|
end
|
487
535
|
```
|
488
536
|
* Non-breaking for classic applications nor modular non-nested applications.
|
489
|
-
|
537
|
+
|
490
538
|
Fixes issues introduced by [#1015][] (in 0.35.0), when we first introduced Sinatra support for modular applications.
|
491
|
-
|
539
|
+
|
492
540
|
The main issue we had to solve for modular support is how to handle nested applications, as only one application is actually responsible for handling the route. A naive implementation would cause the creation of nested `sinatra.request` spans, even for applications that did not handle the request. This is technically correct, as Sinatra is traversing that middleware, accruing overhead, but that does not aligned with our existing behavior of having a single `sinatra.request` span.
|
493
|
-
|
541
|
+
|
494
542
|
While trying to achieve backwards-compatibility, we had to resort to a solution that turned out brittle: `sinatra.request` spans had to start in one middleware level and finished it in another. This allowed us to only capture the `sinatra.request` for the matching route, and skip the non-matching one. This caused unexpected issues on some user setups, specially around Sinatra middleware that created spans in between the initialization and closure of `sinatra.request` spans.
|
495
|
-
|
543
|
+
|
496
544
|
This change now address these implementation issues by creating multiple `sinatra.request`, one for each traversed Sinatra application, even non-matching ones. This instrumentation is more correct, but at the cost of being a breaking change for nested modular applications.
|
497
|
-
|
545
|
+
|
498
546
|
Please see [#1145][] for more information, and example screenshots on how traces for affected applications will look like.
|
499
547
|
|
500
548
|
- Rack/Rails span error propagation with `rescue_from` ([#1155][], [#1162][])
|
@@ -1350,7 +1398,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.14.1...v0.14.2
|
|
1350
1398
|
|
1351
1399
|
### Fixed
|
1352
1400
|
|
1353
|
-
- Sampling priority from request headers not being used ([#521][])
|
1401
|
+
- Sampling priority from request headers not being used ([#521][])
|
1354
1402
|
|
1355
1403
|
## [0.14.1] - 2018-08-21
|
1356
1404
|
|
@@ -1496,9 +1544,9 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.12.1...v0.13.0
|
|
1496
1544
|
- Hash quantization into core library ([#410][])
|
1497
1545
|
- MongoDB integration to use Hash quantization library ([#463][])
|
1498
1546
|
|
1499
|
-
### Changed
|
1547
|
+
### Changed
|
1500
1548
|
|
1501
|
-
- Hash quantization truncates arrays with nested objects ([#463][])
|
1549
|
+
- Hash quantization truncates arrays with nested objects ([#463][])
|
1502
1550
|
|
1503
1551
|
## [0.13.0.beta1] - 2018-05-09
|
1504
1552
|
|
@@ -1847,7 +1895,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
|
|
1847
1895
|
|
1848
1896
|
Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
1849
1897
|
|
1850
|
-
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v0.
|
1898
|
+
[Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v0.54.0...master
|
1899
|
+
[0.54.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.53.0...v0.54.0
|
1851
1900
|
[0.53.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.52.0...v0.53.0
|
1852
1901
|
[0.52.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.51.1...v0.52.0
|
1853
1902
|
[0.51.1]: https://github.com/DataDog/dd-trace-rb/compare/v0.51.0...v0.51.1
|
@@ -2439,6 +2488,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2439
2488
|
[#1277]: https://github.com/DataDog/dd-trace-rb/issues/1277
|
2440
2489
|
[#1278]: https://github.com/DataDog/dd-trace-rb/issues/1278
|
2441
2490
|
[#1279]: https://github.com/DataDog/dd-trace-rb/issues/1279
|
2491
|
+
[#1280]: https://github.com/DataDog/dd-trace-rb/issues/1280
|
2442
2492
|
[#1281]: https://github.com/DataDog/dd-trace-rb/issues/1281
|
2443
2493
|
[#1283]: https://github.com/DataDog/dd-trace-rb/issues/1283
|
2444
2494
|
[#1284]: https://github.com/DataDog/dd-trace-rb/issues/1284
|
@@ -2516,6 +2566,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2516
2566
|
[#1420]: https://github.com/DataDog/dd-trace-rb/issues/1420
|
2517
2567
|
[#1421]: https://github.com/DataDog/dd-trace-rb/issues/1421
|
2518
2568
|
[#1422]: https://github.com/DataDog/dd-trace-rb/issues/1422
|
2569
|
+
[#1423]: https://github.com/DataDog/dd-trace-rb/issues/1423
|
2519
2570
|
[#1426]: https://github.com/DataDog/dd-trace-rb/issues/1426
|
2520
2571
|
[#1427]: https://github.com/DataDog/dd-trace-rb/issues/1427
|
2521
2572
|
[#1428]: https://github.com/DataDog/dd-trace-rb/issues/1428
|
@@ -2601,12 +2652,36 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2601
2652
|
[#1684]: https://github.com/DataDog/dd-trace-rb/issues/1684
|
2602
2653
|
[#1685]: https://github.com/DataDog/dd-trace-rb/issues/1685
|
2603
2654
|
[#1687]: https://github.com/DataDog/dd-trace-rb/issues/1687
|
2655
|
+
[#1688]: https://github.com/DataDog/dd-trace-rb/issues/1688
|
2604
2656
|
[#1694]: https://github.com/DataDog/dd-trace-rb/issues/1694
|
2605
2657
|
[#1695]: https://github.com/DataDog/dd-trace-rb/issues/1695
|
2606
2658
|
[#1699]: https://github.com/DataDog/dd-trace-rb/issues/1699
|
2607
2659
|
[#1700]: https://github.com/DataDog/dd-trace-rb/issues/1700
|
2608
2660
|
[#1702]: https://github.com/DataDog/dd-trace-rb/issues/1702
|
2661
|
+
[#1703]: https://github.com/DataDog/dd-trace-rb/issues/1703
|
2609
2662
|
[#1706]: https://github.com/DataDog/dd-trace-rb/issues/1706
|
2663
|
+
[#1709]: https://github.com/DataDog/dd-trace-rb/issues/1709
|
2664
|
+
[#1712]: https://github.com/DataDog/dd-trace-rb/issues/1712
|
2665
|
+
[#1713]: https://github.com/DataDog/dd-trace-rb/issues/1713
|
2666
|
+
[#1714]: https://github.com/DataDog/dd-trace-rb/issues/1714
|
2667
|
+
[#1715]: https://github.com/DataDog/dd-trace-rb/issues/1715
|
2668
|
+
[#1717]: https://github.com/DataDog/dd-trace-rb/issues/1717
|
2669
|
+
[#1718]: https://github.com/DataDog/dd-trace-rb/issues/1718
|
2670
|
+
[#1719]: https://github.com/DataDog/dd-trace-rb/issues/1719
|
2671
|
+
[#1720]: https://github.com/DataDog/dd-trace-rb/issues/1720
|
2672
|
+
[#1721]: https://github.com/DataDog/dd-trace-rb/issues/1721
|
2673
|
+
[#1735]: https://github.com/DataDog/dd-trace-rb/issues/1735
|
2674
|
+
[#1740]: https://github.com/DataDog/dd-trace-rb/issues/1740
|
2675
|
+
[#1743]: https://github.com/DataDog/dd-trace-rb/issues/1743
|
2676
|
+
[#1745]: https://github.com/DataDog/dd-trace-rb/issues/1745
|
2677
|
+
[#1761]: https://github.com/DataDog/dd-trace-rb/issues/1761
|
2678
|
+
[#1762]: https://github.com/DataDog/dd-trace-rb/issues/1762
|
2679
|
+
[#1763]: https://github.com/DataDog/dd-trace-rb/issues/1763
|
2680
|
+
[#1769]: https://github.com/DataDog/dd-trace-rb/issues/1769
|
2681
|
+
[#1770]: https://github.com/DataDog/dd-trace-rb/issues/1770
|
2682
|
+
[#1771]: https://github.com/DataDog/dd-trace-rb/issues/1771
|
2683
|
+
[#1774]: https://github.com/DataDog/dd-trace-rb/issues/1774
|
2684
|
+
[#1776]: https://github.com/DataDog/dd-trace-rb/issues/1776
|
2610
2685
|
[@AdrianLC]: https://github.com/AdrianLC
|
2611
2686
|
[@Azure7111]: https://github.com/Azure7111
|
2612
2687
|
[@BabyGroot]: https://github.com/BabyGroot
|
@@ -2669,6 +2744,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2669
2744
|
[@gkampjes]: https://github.com/gkampjes
|
2670
2745
|
[@gottfrois]: https://github.com/gottfrois
|
2671
2746
|
[@guizmaii]: https://github.com/guizmaii
|
2747
|
+
[@hatstand]: https://github.com/hatstand
|
2672
2748
|
[@hawknewton]: https://github.com/hawknewton
|
2673
2749
|
[@hs-bguven]: https://github.com/hs-bguven
|
2674
2750
|
[@illdelph]: https://github.com/illdelph
|
@@ -2678,6 +2754,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2678
2754
|
[@jfrancoist]: https://github.com/jfrancoist
|
2679
2755
|
[@joeyAghion]: https://github.com/joeyAghion
|
2680
2756
|
[@jpaulgs]: https://github.com/jpaulgs
|
2757
|
+
[@justinhoward]: https://github.com/justinhoward
|
2681
2758
|
[@jvalanen]: https://github.com/jvalanen
|
2682
2759
|
[@kelvin-acosta]: https://github.com/kelvin-acosta
|
2683
2760
|
[@kexoth]: https://github.com/kexoth
|
@@ -2715,6 +2792,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
|
|
2715
2792
|
[@senny]: https://github.com/senny
|
2716
2793
|
[@shayonj]: https://github.com/shayonj
|
2717
2794
|
[@sinsoku]: https://github.com/sinsoku
|
2795
|
+
[@skcc321]: https://github.com/skcc321
|
2718
2796
|
[@soulcutter]: https://github.com/soulcutter
|
2719
2797
|
[@stefanahman]: https://github.com/stefanahman
|
2720
2798
|
[@steveh]: https://github.com/steveh
|
data/ddtrace.gemspec
CHANGED
@@ -46,8 +46,11 @@ Gem::Specification.new do |spec|
|
|
46
46
|
spec.add_dependency 'msgpack', '< 1.4'
|
47
47
|
end
|
48
48
|
|
49
|
-
# Used by the profiler
|
50
|
-
|
49
|
+
# Used by the profiler native extension to support older Rubies (see NativeExtensionDesign.md for notes)
|
50
|
+
#
|
51
|
+
# Because we only use this for older Rubies, and we consider it "feature-complete" for those older Rubies,
|
52
|
+
# we're pinning it at the latest available version and will manually bump the dependency as needed.
|
53
|
+
spec.add_dependency 'debase-ruby_core_source', '= 0.10.12'
|
51
54
|
|
52
55
|
spec.extensions = ['ext/ddtrace_profiling_native_extension/extconf.rb']
|
53
56
|
end
|
data/docs/GettingStarted.md
CHANGED
@@ -135,13 +135,18 @@ To contribute, check out the [contribution guidelines][contribution docs] and [d
|
|
135
135
|
|
136
136
|
*EOL* indicates support is no longer provided.
|
137
137
|
|
138
|
+
### Microsoft Windows support
|
139
|
+
|
140
|
+
Using `ddtrace ` on Microsoft Windows is currently unsupported. We'll still accept community contributions and issues,
|
141
|
+
but will consider them as having low priority.
|
142
|
+
|
138
143
|
## Installation
|
139
144
|
|
140
145
|
The following steps will help you quickly start tracing your Ruby application.
|
141
146
|
|
142
147
|
### Configure the Datadog Agent for APM
|
143
148
|
|
144
|
-
Before downloading tracing on your application, install the Datadog Agent. The Ruby APM tracer sends trace data through the Datadog Agent.
|
149
|
+
Before downloading tracing on your application, [install the Datadog Agent on the host](https://docs.datadoghq.com/agent/). The Ruby APM tracer sends trace data through the Datadog Agent.
|
145
150
|
|
146
151
|
Install and configure the Datadog Agent to receive traces from your now instrumented application. By default the Datadog Agent is enabled in your `datadog.yaml` file under `apm_enabled: true` and listens for trace traffic at `localhost:8126`. For containerized environments, follow the steps below to enable trace collection within the Datadog Agent.
|
147
152
|
|
@@ -540,7 +545,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
|
|
540
545
|
Most of the time, Active Job is set up as part of Rails, but it can be activated separately:
|
541
546
|
|
542
547
|
```ruby
|
543
|
-
require '
|
548
|
+
require 'active_job'
|
544
549
|
require 'ddtrace'
|
545
550
|
|
546
551
|
Datadog.configure do |c|
|
@@ -1217,6 +1222,37 @@ Where `options` is an optional `Hash` that accepts the following parameters:
|
|
1217
1222
|
| `quantize` | Hash containing options for quantization. May include `:show` with an Array of keys to not quantize (or `:all` to skip quantization), or `:exclude` with Array of keys to exclude entirely. | `{ show: [:collection, :database, :operation] }` |
|
1218
1223
|
| `service_name` | Service name used for `mongo` instrumentation | `'mongodb'` |
|
1219
1224
|
|
1225
|
+
**Configuring trace settings per connection**
|
1226
|
+
|
1227
|
+
You can configure trace settings per connection by using the `describes` option:
|
1228
|
+
|
1229
|
+
```ruby
|
1230
|
+
# Provide a `:describes` option with a connection key.
|
1231
|
+
# Any of the following keys are acceptable and equivalent to one another.
|
1232
|
+
# If a block is provided, it yields a Settings object that
|
1233
|
+
# accepts any of the configuration options listed above.
|
1234
|
+
|
1235
|
+
Datadog.configure do |c|
|
1236
|
+
# Network connection string
|
1237
|
+
c.use :mongo, describes: '127.0.0.1:27017', service_name: 'mongo-primary'
|
1238
|
+
|
1239
|
+
# Network connection regular expression
|
1240
|
+
c.use :mongo, describes: /localhost.*/, service_name: 'mongo-secondary'
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'artists')
|
1244
|
+
collection = client[:people]
|
1245
|
+
collection.insert_one({ name: 'Steve' })
|
1246
|
+
# Traced call will belong to `mongo-primary` service
|
1247
|
+
|
1248
|
+
client = Mongo::Client.new([ 'localhost:27017' ], :database => 'artists')
|
1249
|
+
collection = client[:people]
|
1250
|
+
collection.insert_one({ name: 'Steve' })
|
1251
|
+
# Traced call will belong to `mongo-secondary` service
|
1252
|
+
```
|
1253
|
+
|
1254
|
+
When multiple `describes` configurations match a connection, the latest configured rule that matches will be applied.
|
1255
|
+
|
1220
1256
|
### MySQL2
|
1221
1257
|
|
1222
1258
|
The MySQL2 integration traces any SQL command sent through `mysql2` gem.
|
@@ -1471,6 +1507,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
|
|
1471
1507
|
| `database_service` | Database service name used when tracing database activity | `'<app_name>-<adapter_name>'` |
|
1472
1508
|
| `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) so that this service trace is connected with a trace of another service if tracing headers are received | `true` |
|
1473
1509
|
| `exception_controller` | Class or Module which identifies a custom exception controller class. Tracer provides improved error behavior when it can identify custom exception controllers. By default, without this option, it 'guesses' what a custom exception controller looks like. Providing this option aids this identification. | `nil` |
|
1510
|
+
| `job_service` | Service name used when tracing ActiveJob activity. | `<app_name>-active_job` |
|
1474
1511
|
| `middleware` | Add the trace middleware to the Rails application. Set to `false` if you don't want the middleware to load. | `true` |
|
1475
1512
|
| `middleware_names` | Enables any short-circuited middleware requests to display the middleware name as a resource for the trace. | `false` |
|
1476
1513
|
| `service_name` | Service name used when tracing application requests (on the `rack` level) | `'<app_name>'` (inferred from your Rails application namespace) |
|
@@ -2461,7 +2498,7 @@ The tracer and its integrations can produce some additional metrics that can pro
|
|
2461
2498
|
To configure your application for metrics collection:
|
2462
2499
|
|
2463
2500
|
1. [Configure your Datadog agent for StatsD](https://docs.datadoghq.com/developers/dogstatsd/#setup)
|
2464
|
-
2. Add `gem 'dogstatsd-ruby', '~> 5.
|
2501
|
+
2. Add `gem 'dogstatsd-ruby', '~> 5.3'` to your Gemfile
|
2465
2502
|
|
2466
2503
|
#### For application runtime
|
2467
2504
|
|
@@ -97,9 +97,9 @@ The profiler backend links a trace covering a given time interval to the profile
|
|
97
97
|
whenever they share the same `runtime-id`.
|
98
98
|
|
99
99
|
To further enable filtering of a profile to show only samples related to a given trace/span, each sample taken by the
|
100
|
-
profiler is tagged with the
|
100
|
+
profiler is tagged with the `local root span id` and `span id` for the given trace/span.
|
101
101
|
|
102
|
-
This is done using the `Datadog::Profiling::TraceIdentifiers::Helper` that retrieves a
|
102
|
+
This is done using the `Datadog::Profiling::TraceIdentifiers::Helper` that retrieves a `root_span_id` and `span_id`, if
|
103
103
|
available, from the supported tracers. This helper is called by the `Collectors::Stack` during sampling.
|
104
104
|
|
105
105
|
Note that if a given trace executes too fast, it's possible that the profiler will not contain any samples for that
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Profiling Native Extension Design
|
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.
|
5
|
+
|
6
|
+
This extension is quite coupled with MRI Ruby ("C Ruby") internals, and is not intended to support other rubies such as
|
7
|
+
JRuby or TruffleRuby. When below we say "Ruby", read it as "MRI Ruby".
|
8
|
+
|
9
|
+
## Disabling
|
10
|
+
|
11
|
+
The profiling native extension can be disabled by setting `DD_PROFILING_NO_EXTENSION=true` when installing or running
|
12
|
+
the gem. Setting `DD_PROFILING_NO_EXTENSION` at installation time skips compilation of the extension entirely.
|
13
|
+
|
14
|
+
(If you're a customer and needed to use this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>.)
|
15
|
+
|
16
|
+
Currently the profiler can still "limp along" when the native extension is disabled, but the plan is to require it
|
17
|
+
in future releases -- e.g. disabling the extension will disable profiling entirely.
|
18
|
+
|
19
|
+
## Safety
|
20
|
+
|
21
|
+
The profiling native extension is (and must always be) designed to **not cause failures** during gem installation, even
|
22
|
+
if some features, Ruby versions, or operating systems are not supported.
|
23
|
+
|
24
|
+
E.g. the extension must cleanly build on Ruby 2.1 (or the oldest Ruby version we support at the time) on Windows,
|
25
|
+
even if at run time it will effectively do nothing for such a setup.
|
26
|
+
|
27
|
+
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
|
+
existing codebase.
|
29
|
+
|
30
|
+
## Usage of private VM headers
|
31
|
+
|
32
|
+
To implement some of the features below, we sometimes require access to private Ruby header files (that describe VM
|
33
|
+
internal types, structures and functions).
|
34
|
+
|
35
|
+
Because these private header files are not included in regular Ruby installations, we have two different workarounds:
|
36
|
+
|
37
|
+
1. for Ruby versions >= 2.6 we make use use the Ruby private MJIT header
|
38
|
+
2. for Ruby versions < 2.6 (legacy Rubies) we make use of the `debase-ruby_core_source` gem
|
39
|
+
|
40
|
+
Functions which make use of these headers are defined in the <private_vm_api_acccess.c> file.
|
41
|
+
|
42
|
+
**Important Note**: Our medium/long-term plan is to stop relying on all private Ruby headers, and instead request and
|
43
|
+
contribute upstream changes so that they become official public VM APIs.
|
44
|
+
|
45
|
+
### Approach 1: Using the Ruby private MJIT header
|
46
|
+
|
47
|
+
Ruby versions >= 2.6 introduced a JIT compiler called MJIT. This compiler does not directly generate machine code;
|
48
|
+
instead it generates C code and uses the system C compiler to turn it into machine code.
|
49
|
+
|
50
|
+
The generated C code `#include`s a private header -- which we reference as "the MJIT header" everywhere.
|
51
|
+
The MJIT header gets shipped with all MJIT-enabled Rubies and includes the layout of many internal VM structures;
|
52
|
+
and of course the intention is that it is only used by the Ruby MJIT compiler.
|
53
|
+
|
54
|
+
This header is placed inside the `include/` directory in a Ruby installation, and is named for that specific Ruby
|
55
|
+
version. e.g. `rb_mjit_min_header-2.7.4.h`.
|
56
|
+
|
57
|
+
### Approach 2: Using the `debase-ruby_core_source` gem
|
58
|
+
|
59
|
+
The [`debase-ruby_core_source`](https://github.com/ruby-debug/debase-ruby_core_source) contains almost no code;
|
60
|
+
instead, it just contains per-Ruby-version folders with the private VM headers (`.h`) files for that version.
|
61
|
+
|
62
|
+
Thus, even though a regular Ruby installation does not include these files, we can access the copy inside this gem.
|
63
|
+
|
64
|
+
## Feature: Getting thread CPU-time clock_ids
|
65
|
+
|
66
|
+
* **OS support**: Linux
|
67
|
+
* **Ruby support**: 2.6+
|
68
|
+
|
69
|
+
To enable CPU-time profiling, we use the `pthread_getcpuclockid(pthread_t thread, clockid_t *clockid)` C function to
|
70
|
+
obtain a `clockid_t` that can then be used with the `Process.clock_gettime` method (or directly with the
|
71
|
+
`clock_gettime()` C function).
|
72
|
+
|
73
|
+
The challenge with using `pthread_getcpuclockid()` is that we need to get the `pthread_t` for a given Ruby `Thread`
|
74
|
+
object. We previously did this with a weird combination of monkey patching and `pthread_self()` (effectively patching
|
75
|
+
every `Thread` to run `pthread_self()` at initialization time and stash that value somewhere), but this had a number
|
76
|
+
of downsides.
|
77
|
+
|
78
|
+
The approach we use in the profiling native extension is to reach inside the internal structure of the `Thread` object,
|
79
|
+
and extract the `pthread_t` that Ruby itself keeps, but does not expose. This is implemented in the `pthread_id_for()`
|
80
|
+
function in `private_vm_api_acccess.c`. Thus, using this trick we can at any point in execution go from a `Thread`
|
81
|
+
object into the `clockid_t` that we need.
|
82
|
+
|
83
|
+
Note that `pthread_getcpuclockid()` is not available on macOS (nor, obviously, on Windows), and hence this feature
|
84
|
+
is currently Linux-specific. Thus, in the <clock_id_from_pthread.c> file we implement the feature for supported Ruby
|
85
|
+
setups but if something is missing we instead compile in <clock_id_noop.c> that includes a no-op implementation of the
|
86
|
+
feature.
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#include "extconf.h"
|
2
|
+
|
3
|
+
// This file is only compiled on systems where pthread_getcpuclockid() is available;
|
4
|
+
// Otherwise we compile clock_id_noop.c
|
5
|
+
#ifdef HAVE_PTHREAD_GETCPUCLOCKID
|
6
|
+
|
7
|
+
#include <pthread.h>
|
8
|
+
#include <time.h>
|
9
|
+
#include <errno.h>
|
10
|
+
|
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
|
+
#include "private_vm_api_access.h"
|
20
|
+
|
21
|
+
#include "clock_id.h"
|
22
|
+
|
23
|
+
// Validate that our home-cooked pthread_id_for() matches pthread_self() for the current thread
|
24
|
+
void self_test_clock_id() {
|
25
|
+
rb_nativethread_id_t expected_pthread_id = pthread_self();
|
26
|
+
rb_nativethread_id_t actual_pthread_id = pthread_id_for(rb_thread_current());
|
27
|
+
|
28
|
+
if (expected_pthread_id != actual_pthread_id) rb_raise(rb_eRuntimeError, "pthread_id_for() self-test failed");
|
29
|
+
}
|
30
|
+
|
31
|
+
VALUE clock_id_for(VALUE self, VALUE thread) {
|
32
|
+
rb_nativethread_id_t thread_id = pthread_id_for(thread);
|
33
|
+
|
34
|
+
clockid_t clock_id;
|
35
|
+
int error = pthread_getcpuclockid(thread_id, &clock_id);
|
36
|
+
|
37
|
+
if (error == 0) {
|
38
|
+
return CLOCKID2NUM(clock_id);
|
39
|
+
} else {
|
40
|
+
switch(error) {
|
41
|
+
// The more specific error messages are based on the pthread_getcpuclockid(3) man page
|
42
|
+
case ENOENT:
|
43
|
+
rb_exc_raise(rb_syserr_new(error, "Failed to get clock_id for given thread: Per-thread CPU time clocks are not supported by the system."));
|
44
|
+
case ESRCH:
|
45
|
+
rb_exc_raise(rb_syserr_new(error, "Failed to get clock_id for given thread: No thread could be found."));
|
46
|
+
default:
|
47
|
+
rb_exc_raise(rb_syserr_new(error, "Failed to get clock_id for given thread"));
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
#endif
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "extconf.h"
|
2
|
+
|
3
|
+
// This file is the dual of clock_id_from_pthread.c for systems where that info
|
4
|
+
// is not available.
|
5
|
+
#ifndef HAVE_PTHREAD_GETCPUCLOCKID
|
6
|
+
|
7
|
+
#include <ruby.h>
|
8
|
+
|
9
|
+
#include "clock_id.h"
|
10
|
+
|
11
|
+
void self_test_clock_id() { } // Nothing to check
|
12
|
+
VALUE clock_id_for(VALUE self, VALUE thread) { return Qnil; } // Nothing to return
|
13
|
+
|
14
|
+
#endif
|
@@ -1,28 +1,166 @@
|
|
1
|
-
# typed:
|
2
|
-
|
1
|
+
# typed: ignore
|
2
|
+
|
3
|
+
# Older Rubies don't have the MJIT header, used by the JIT compiler, so we need to use a different approach
|
4
|
+
CAN_USE_MJIT_HEADER = RUBY_VERSION >= '2.6'
|
5
|
+
|
6
|
+
def on_jruby?
|
3
7
|
# We don't support JRuby for profiling, and JRuby doesn't support native extensions, so let's just skip this entire
|
4
8
|
# thing so that JRuby users of dd-trace-rb aren't impacted.
|
5
|
-
|
9
|
+
RUBY_ENGINE == 'jruby'
|
10
|
+
end
|
11
|
+
|
12
|
+
def on_truffleruby?
|
13
|
+
# We don't officially support TruffleRuby for dd-trace-rb at all BUT let's not break adventurous customers that
|
14
|
+
# want to give it a try.
|
15
|
+
RUBY_ENGINE == 'truffleruby'
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_windows?
|
19
|
+
# Microsoft Windows is unsupported, so let's not build the extension there.
|
20
|
+
Gem.win_platform?
|
21
|
+
end
|
22
|
+
|
23
|
+
def expected_to_use_mjit_but_mjit_is_disabled?
|
24
|
+
# On some Rubies, we require the mjit header to be present. If Ruby was installed without MJIT support, we also skip
|
25
|
+
# building the extension.
|
26
|
+
mjit_disabled = CAN_USE_MJIT_HEADER && RbConfig::CONFIG['MJIT_SUPPORT'] != 'yes'
|
6
27
|
|
28
|
+
if mjit_disabled
|
29
|
+
# rubocop:disable Style/StderrPuts
|
30
|
+
$stderr.puts(%(
|
31
|
+
+------------------------------------------------------------------------------+
|
32
|
+
| Your Ruby has been compiled without JIT support (--disable-jit-support). |
|
33
|
+
| The profiling native extension requires a Ruby compiled with JIT support, |
|
34
|
+
| even if the JIT is not in use by the application itself. |
|
35
|
+
| |
|
36
|
+
| WARNING: Without the profiling native extension, some profiling features |
|
37
|
+
| will not be available. |
|
38
|
+
+------------------------------------------------------------------------------+
|
39
|
+
|
40
|
+
))
|
41
|
+
end
|
42
|
+
|
43
|
+
mjit_disabled
|
44
|
+
end
|
45
|
+
|
46
|
+
def disabled_via_env?
|
7
47
|
# Experimental toggle to disable building the extension.
|
8
48
|
# Disabling the extension will lead to the profiler not working in future releases.
|
9
49
|
# If you needed to use this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>.
|
10
|
-
|
50
|
+
ENV['DD_PROFILING_NO_EXTENSION'].to_s.downcase == 'true'
|
51
|
+
end
|
11
52
|
|
12
|
-
|
53
|
+
def skip_building_extension?
|
54
|
+
disabled_via_env? || on_jruby? || on_truffleruby? || on_windows? || expected_to_use_mjit_but_mjit_is_disabled?
|
55
|
+
end
|
56
|
+
|
57
|
+
# IMPORTANT: When adding flags, remember that our customers compile with a wide range of gcc/clang versions, so
|
58
|
+
# doublecheck that what you're adding can be reasonably expected to exist on their systems.
|
59
|
+
def add_compiler_flag(flag)
|
60
|
+
$CFLAGS << ' ' << flag
|
13
61
|
end
|
14
62
|
|
15
63
|
if skip_building_extension?
|
64
|
+
$stderr.puts(%(
|
65
|
+
+------------------------------------------------------------------------------+
|
66
|
+
| Skipping build of profiling native extension and replacing it with a no-op |
|
67
|
+
| Makefile |
|
68
|
+
+------------------------------------------------------------------------------+
|
69
|
+
|
70
|
+
))
|
71
|
+
|
16
72
|
File.write('Makefile', 'all install clean: # dummy makefile that does nothing')
|
17
73
|
return
|
18
74
|
end
|
19
75
|
|
76
|
+
$stderr.puts(%(
|
77
|
+
+------------------------------------------------------------------------------+
|
78
|
+
| **Preparing to build the ddtrace native extension...** |
|
79
|
+
| |
|
80
|
+
| If you run into any failures during this step, you can set the |
|
81
|
+
| `DD_PROFILING_NO_EXTENSION` environment variable to `true` e.g. |
|
82
|
+
| `$ DD_PROFILING_NO_EXTENSION=true bundle install` to skip this step. |
|
83
|
+
| |
|
84
|
+
| Disabling the extension will lead to the ddtrace profiling features not |
|
85
|
+
| working in future releases. |
|
86
|
+
| If you needed to use this, please tell us why on |
|
87
|
+
| <https://github.com/DataDog/dd-trace-rb/issues/new> so we can fix it :\) |
|
88
|
+
| |
|
89
|
+
| Thanks for using ddtrace! You rock! |
|
90
|
+
+------------------------------------------------------------------------------+
|
91
|
+
|
92
|
+
))
|
93
|
+
# rubocop:enable Style/StderrPuts
|
94
|
+
|
20
95
|
# NOTE: we MUST NOT require 'mkmf' before we check the #skip_building_extension? because the require triggers checks
|
21
96
|
# that may fail on an environment not properly setup for building Ruby extensions.
|
22
97
|
require 'mkmf'
|
23
98
|
|
99
|
+
# Gets really noisy when we include the MJIT header, let's omit it
|
100
|
+
add_compiler_flag '-Wno-unused-function'
|
101
|
+
|
102
|
+
# Allow defining variables at any point in a function
|
103
|
+
add_compiler_flag '-Wno-declaration-after-statement'
|
104
|
+
|
105
|
+
# If we forget to include a Ruby header, the function call may still appear to work, but then
|
106
|
+
# cause a segfault later. Let's ensure that never happens.
|
107
|
+
add_compiler_flag '-Werror-implicit-function-declaration'
|
108
|
+
|
109
|
+
if RUBY_PLATFORM.include?('linux')
|
110
|
+
# Supposedly, the correct way to do this is
|
111
|
+
# ```
|
112
|
+
# have_library 'pthread'
|
113
|
+
# have_func 'pthread_getcpuclockid'
|
114
|
+
# ```
|
115
|
+
# but it broke the build on Windows and on older Ruby versions (2.1 and 2.2)
|
116
|
+
# so instead we just assume that we have the function we need on Linux, and nowhere else
|
117
|
+
$defs << '-DHAVE_PTHREAD_GETCPUCLOCKID'
|
118
|
+
end
|
119
|
+
|
24
120
|
# Tag the native extension library with the Ruby version and Ruby platform.
|
25
121
|
# This makes it easier for development (avoids "oops I forgot to rebuild when I switched my Ruby") and ensures that
|
26
122
|
# the wrong library is never loaded.
|
27
123
|
# When requiring, we need to use the exact same string, including the version and the platform.
|
28
|
-
|
124
|
+
EXTENSION_NAME = "ddtrace_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}".freeze
|
125
|
+
|
126
|
+
if CAN_USE_MJIT_HEADER
|
127
|
+
$defs << '-DUSE_MJIT_HEADER'
|
128
|
+
|
129
|
+
# NOTE: This needs to come after all changes to $defs
|
130
|
+
create_header
|
131
|
+
|
132
|
+
# The MJIT header is always (afaik?) suffixed with the exact Ruby VM version,
|
133
|
+
# including patch (e.g. 2.7.2). Thus, we add to the header file a definition
|
134
|
+
# containing the exact file, so that it can be used in a #include in the C code.
|
135
|
+
header_contents =
|
136
|
+
File.read($extconf_h)
|
137
|
+
.sub('#endif',
|
138
|
+
<<-EXTCONF_H.strip
|
139
|
+
#define RUBY_MJIT_HEADER "rb_mjit_min_header-#{RUBY_VERSION}.h"
|
140
|
+
|
141
|
+
#endif
|
142
|
+
EXTCONF_H
|
143
|
+
)
|
144
|
+
File.open($extconf_h, 'w') { |file| file.puts(header_contents) }
|
145
|
+
|
146
|
+
create_makefile EXTENSION_NAME
|
147
|
+
else
|
148
|
+
# On older Rubies, we use the debase-ruby_core_source gem to get access to private VM headers.
|
149
|
+
# This gem ships source code copies of these VM headers for the different Ruby VM versions;
|
150
|
+
# see https://github.com/ruby-debug/debase-ruby_core_source for details
|
151
|
+
|
152
|
+
thread_native_for_ruby_2_1 = proc { true }
|
153
|
+
if RUBY_VERSION < '2.2'
|
154
|
+
# This header became public in Ruby 2.2, but we need to pull it from the private headers folder for 2.1
|
155
|
+
thread_native_for_ruby_2_1 = proc { have_header('thread_native.h') }
|
156
|
+
$defs << '-DRUBY_2_1_WORKAROUND'
|
157
|
+
end
|
158
|
+
|
159
|
+
create_header
|
160
|
+
|
161
|
+
require 'debase/ruby_core_source'
|
162
|
+
dir_config('ruby') # allow user to pass in non-standard core include directory
|
163
|
+
|
164
|
+
Debase::RubyCoreSource
|
165
|
+
.create_makefile_with_core(proc { have_header('vm_core.h') && thread_native_for_ruby_2_1.call }, EXTENSION_NAME)
|
166
|
+
end
|