Opt Datadog.Trace.Manual out of NGEN#6168
Conversation
Snapshots difference summaryThe following differences have been observed in committed snapshots. It is meant to help the reviewer. 1 occurrences of : + Name: initial,
+ Resource: initial,
+ Service: Samples.ManualInstrumentation,
+ Tags: {
+ env: integration_tests,
+ language: dotnet,
+ runtime-id: Guid_1
+ },
+ Metrics: {
+ process_id: 0,
+ _dd.top_level: 1.0,
+ _dd.tracer_kr: 1.0,
+ _sampling_priority_v1: 1.0
+ }
+ },
+ {
+ TraceId: Id_3,
+ SpanId: Id_4,
1 occurrences of : - TraceId: Id_1,
- SpanId: Id_3,
+ TraceId: Id_3,
+ SpanId: Id_5,
[...]
- ParentId: Id_2,
+ ParentId: Id_4,
[...]
- TraceId: Id_1,
- SpanId: Id_4,
+ TraceId: Id_3,
+ SpanId: Id_6,
[...]
- ParentId: Id_3,
+ ParentId: Id_5,
1 occurrences of : - TraceId: Id_5,
- SpanId: Id_6,
+ TraceId: Id_7,
+ SpanId: Id_8,
1 occurrences of : - TraceId: Id_7,
- SpanId: Id_8,
+ TraceId: Id_9,
+ SpanId: Id_10,
1 occurrences of : - TraceId: Id_7,
- SpanId: Id_9,
+ TraceId: Id_9,
+ SpanId: Id_11,
[...]
- ParentId: Id_8,
+ ParentId: Id_10,
1 occurrences of : - TraceId: Id_7,
- SpanId: Id_10,
+ TraceId: Id_9,
+ SpanId: Id_12,
[...]
- ParentId: Id_9,
+ ParentId: Id_11,
1 occurrences of : - TraceId: Id_11,
- SpanId: Id_12,
+ TraceId: Id_13,
+ SpanId: Id_14,
1 occurrences of : - TraceId: Id_13,
- SpanId: Id_14,
+ TraceId: Id_15,
+ SpanId: Id_16,
1 occurrences of : - TraceId: Id_13,
- SpanId: Id_15,
+ TraceId: Id_15,
+ SpanId: Id_17,
[...]
- ParentId: Id_14,
+ ParentId: Id_16,
[...]
- TraceId: Id_16,
- SpanId: Id_17,
+ TraceId: Id_18,
+ SpanId: Id_19,
1 occurrences of : - TraceId: Id_18,
- SpanId: Id_19,
+ TraceId: Id_20,
+ SpanId: Id_21,
1 occurrences of : - TraceId: Id_18,
- SpanId: Id_20,
+ TraceId: Id_20,
+ SpanId: Id_22,
[...]
- ParentId: Id_19,
+ ParentId: Id_21,
[...]
- TraceId: Id_18,
- SpanId: Id_21,
+ TraceId: Id_20,
+ SpanId: Id_23,
[...]
- ParentId: Id_20,
+ ParentId: Id_22,
1 occurrences of : - TraceId: Id_22,
- SpanId: Id_23,
+ TraceId: Id_24,
+ SpanId: Id_25,
1 occurrences of : - TraceId: Id_24,
- SpanId: Id_25,
+ TraceId: Id_26,
+ SpanId: Id_27,
1 occurrences of : - TraceId: Id_26,
- SpanId: Id_27,
+ TraceId: Id_28,
+ SpanId: Id_29,
1 occurrences of : - TraceId: Id_26,
- SpanId: Id_28,
+ TraceId: Id_28,
+ SpanId: Id_30,
[...]
- ParentId: Id_27,
+ ParentId: Id_29,
1 occurrences of : - TraceId: Id_26,
- SpanId: Id_29,
+ TraceId: Id_28,
+ SpanId: Id_31,
[...]
- ParentId: Id_28,
+ ParentId: Id_30,
[...]
- TraceId: Id_26,
- SpanId: Id_30,
+ TraceId: Id_28,
+ SpanId: Id_32,
[...]
- ParentId: Id_29,
+ ParentId: Id_31,
1 occurrences of : - TraceId: Id_31,
- SpanId: Id_32,
+ TraceId: Id_33,
+ SpanId: Id_34,
1 occurrences of : - TraceId: Id_31,
- SpanId: Id_33,
+ TraceId: Id_33,
+ SpanId: Id_35,
[...]
- ParentId: Id_32,
+ ParentId: Id_34,
[...]
- TraceId: Id_31,
- SpanId: Id_34,
+ TraceId: Id_33,
+ SpanId: Id_36,
[...]
- ParentId: Id_33,
+ ParentId: Id_35,
[...]
- TraceId: Id_31,
- SpanId: Id_35,
+ TraceId: Id_33,
+ SpanId: Id_37,
[...]
- ParentId: Id_34,
+ ParentId: Id_36,
1 occurrences of : - TraceId: Id_36,
- SpanId: Id_37,
+ TraceId: Id_38,
+ SpanId: Id_39,
1 occurrences of : - TraceId: Id_38,
- SpanId: Id_39,
+ TraceId: Id_40,
+ SpanId: Id_41,
1 occurrences of : - TraceId: Id_38,
- SpanId: Id_40,
+ TraceId: Id_40,
+ SpanId: Id_42,
[...]
- ParentId: Id_39,
+ ParentId: Id_41,
[...]
- TraceId: Id_38,
- SpanId: Id_41,
+ TraceId: Id_40,
+ SpanId: Id_43,
[...]
- ParentId: Id_40,
+ ParentId: Id_42,
[...]
- TraceId: Id_38,
- SpanId: Id_42,
+ TraceId: Id_40,
+ SpanId: Id_44,
[...]
- ParentId: Id_41,
+ ParentId: Id_43,
1 occurrences of : - TraceId: Id_43,
- SpanId: Id_44,
+ TraceId: Id_45,
+ SpanId: Id_46,
1 occurrences of : - TraceId: Id_45,
- SpanId: Id_46,
+ TraceId: Id_47,
+ SpanId: Id_48,
1 occurrences of : - TraceId: Id_45,
- SpanId: Id_47,
+ TraceId: Id_47,
+ SpanId: Id_49,
[...]
- ParentId: Id_46,
+ ParentId: Id_48,
[...]
- TraceId: Id_45,
- SpanId: Id_48,
+ TraceId: Id_47,
+ SpanId: Id_50,
[...]
- ParentId: Id_47,
+ ParentId: Id_49,
[...]
- TraceId: Id_45,
- SpanId: Id_49,
+ TraceId: Id_47,
+ SpanId: Id_51,
[...]
- ParentId: Id_48,
+ ParentId: Id_50,
1 occurrences of : - TraceId: Id_50,
- SpanId: Id_51,
+ TraceId: Id_52,
+ SpanId: Id_53,
1 occurrences of : - TraceId: Id_52,
- SpanId: Id_53,
+ TraceId: Id_54,
+ SpanId: Id_55,
|
tonyredondo
left a comment
There was a problem hiding this comment.
LGTM as a temporal fix of the issue. We need to keep digging and work on a general solution.
Datadog ReportBranch report: ✅ 0 Failed, 371620 Passed, 2742 Skipped, 26h 10m 3.46s Total Time New Flaky Tests (2)
|
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing the following branches/commits: Execution-time benchmarks measure the whole time it takes to execute a program. And are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are shown in red. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6168) - mean (72ms) : 67, 78
. : milestone, 72,
master - mean (71ms) : 68, 75
. : milestone, 71,
section CallTarget+Inlining+NGEN
This PR (6168) - mean (1,118ms) : 1097, 1139
. : milestone, 1118,
master - mean (1,120ms) : 1092, 1149
. : milestone, 1120,
gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6168) - mean (110ms) : 106, 114
. : milestone, 110,
master - mean (109ms) : 107, 112
. : milestone, 109,
section CallTarget+Inlining+NGEN
This PR (6168) - mean (777ms) : 763, 792
. : milestone, 777,
master - mean (776ms) : 757, 795
. : milestone, 776,
gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6168) - mean (93ms) : 90, 96
. : milestone, 93,
master - mean (93ms) : 89, 97
. : milestone, 93,
section CallTarget+Inlining+NGEN
This PR (6168) - mean (734ms) : 712, 755
. : milestone, 734,
master - mean (728ms) : 710, 746
. : milestone, 728,
gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6168) - mean (190ms) : 187, 192
. : milestone, 190,
master - mean (190ms) : 187, 193
. : milestone, 190,
section CallTarget+Inlining+NGEN
This PR (6168) - mean (1,201ms) : 1180, 1222
. : milestone, 1201,
master - mean (1,193ms) : 1168, 1218
. : milestone, 1193,
gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6168) - mean (275ms) : 271, 279
. : milestone, 275,
master - mean (275ms) : 270, 279
. : milestone, 275,
section CallTarget+Inlining+NGEN
This PR (6168) - mean (948ms) : 932, 965
. : milestone, 948,
master - mean (943ms) : 924, 961
. : milestone, 943,
gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6168) - mean (264ms) : 260, 268
. : milestone, 264,
master - mean (264ms) : 260, 268
. : milestone, 264,
section CallTarget+Inlining+NGEN
This PR (6168) - mean (928ms) : 907, 948
. : milestone, 928,
master - mean (923ms) : 907, 938
. : milestone, 923,
|
| { | ||
| TraceId: Id_1, | ||
| SpanId: Id_2, | ||
| Name: initial, |
There was a problem hiding this comment.
This is the only actual change in the snapshot, the rest are just bumping of IDs
| public async Task ManualAndAutomatic() | ||
| { | ||
| const int expectedSpans = 36; | ||
| const int expectedSpans = 37; |
There was a problem hiding this comment.
Not a fan of this test re-using the sample and duplicating this - I'd rather just move the extra assertions to ManualInstrumentationTests - will do that in a separate PR
Benchmarks Report for tracer 🐌Benchmarks for #6168 compared to master:
The following thresholds were used for comparing the benchmark speeds:
Allocation changes below 0.5% are ignored. Benchmark detailsBenchmarks.Trace.ActivityBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️Raw results
Benchmarks.Trace.SpanBenchmark - Slower
|
| Benchmark | diff/base | Base Median (ns) | Diff Median (ns) | Modality |
|---|---|---|---|---|
| Benchmarks.Trace.SpanBenchmark.StartFinishSpan‑net472 | 1.114 | 701.48 | 781.75 |
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | StartFinishSpan |
net6.0 | 399ns | 0.157ns | 0.586ns | 0.008 | 0 | 0 | 576 B |
| master | StartFinishSpan |
netcoreapp3.1 | 621ns | 3.35ns | 18.1ns | 0.00757 | 0 | 0 | 576 B |
| master | StartFinishSpan |
net472 | 699ns | 1.14ns | 4.4ns | 0.0918 | 0 | 0 | 578 B |
| master | StartFinishScope |
net6.0 | 486ns | 0.18ns | 0.698ns | 0.00964 | 0 | 0 | 696 B |
| master | StartFinishScope |
netcoreapp3.1 | 703ns | 0.374ns | 1.4ns | 0.00913 | 0 | 0 | 696 B |
| master | StartFinishScope |
net472 | 968ns | 0.287ns | 1.04ns | 0.104 | 0 | 0 | 658 B |
| #6168 | StartFinishSpan |
net6.0 | 440ns | 0.265ns | 1.03ns | 0.00817 | 0 | 0 | 576 B |
| #6168 | StartFinishSpan |
netcoreapp3.1 | 552ns | 0.268ns | 1ns | 0.00777 | 0 | 0 | 576 B |
| #6168 | StartFinishSpan |
net472 | 783ns | 0.825ns | 3.19ns | 0.0917 | 0 | 0 | 578 B |
| #6168 | StartFinishScope |
net6.0 | 535ns | 0.311ns | 1.2ns | 0.00967 | 0 | 0 | 696 B |
| #6168 | StartFinishScope |
netcoreapp3.1 | 743ns | 0.88ns | 3.41ns | 0.00955 | 0 | 0 | 696 B |
| #6168 | StartFinishScope |
net472 | 877ns | 0.571ns | 2.21ns | 0.104 | 0 | 0 | 658 B |
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️
Raw results
| Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|---|---|---|---|---|---|---|---|---|---|
| master | RunOnMethodBegin |
net6.0 | 652ns | 0.414ns | 1.6ns | 0.00985 | 0 | 0 | 696 B |
| master | RunOnMethodBegin |
netcoreapp3.1 | 906ns | 0.628ns | 2.35ns | 0.00949 | 0 | 0 | 696 B |
| master | RunOnMethodBegin |
net472 | 1.14μs | 0.206ns | 0.744ns | 0.105 | 0 | 0 | 658 B |
| #6168 | RunOnMethodBegin |
net6.0 | 687ns | 0.235ns | 0.909ns | 0.01 | 0 | 0 | 696 B |
| #6168 | RunOnMethodBegin |
netcoreapp3.1 | 907ns | 0.506ns | 1.89ns | 0.00925 | 0 | 0 | 696 B |
| #6168 | RunOnMethodBegin |
net472 | 1.13μs | 0.384ns | 1.49ns | 0.105 | 0 | 0 | 658 B |
Throughput/Crank Report ⚡Throughput results for AspNetCoreSimpleController comparing the following branches/commits: Cases where throughput results for the PR are worse than latest master (5% drop or greater), results are shown in red. Note that these results are based on a single point-in-time result for each branch. For full results, see one of the many, many dashboards! gantt
title Throughput Linux x64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6168) (11.097M) : 0, 11097394
master (11.202M) : 0, 11201555
benchmarks/2.9.0 (11.081M) : 0, 11080577
section Automatic
This PR (6168) (7.422M) : 0, 7421987
master (7.284M) : 0, 7284215
benchmarks/2.9.0 (7.732M) : 0, 7732233
section Trace stats
master (7.733M) : 0, 7732535
section Manual
master (11.196M) : 0, 11195858
section Manual + Automatic
This PR (6168) (6.819M) : 0, 6819252
master (6.748M) : 0, 6748246
section DD_TRACE_ENABLED=0
master (10.333M) : 0, 10333224
gantt
title Throughput Linux arm64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6168) (9.521M) : 0, 9520888
master (9.643M) : 0, 9643431
benchmarks/2.9.0 (9.798M) : 0, 9798067
section Automatic
This PR (6168) (6.642M) : 0, 6641734
master (6.577M) : 0, 6577390
section Trace stats
master (6.845M) : 0, 6845170
section Manual
master (9.511M) : 0, 9511409
section Manual + Automatic
This PR (6168) (6.056M) : 0, 6055972
master (6.185M) : 0, 6185194
section DD_TRACE_ENABLED=0
master (8.810M) : 0, 8810462
gantt
title Throughput Windows x64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6168) (9.714M) : 0, 9714474
benchmarks/2.9.0 (10.067M) : 0, 10067315
section Automatic
This PR (6168) (6.365M) : 0, 6365092
benchmarks/2.9.0 (7.552M) : 0, 7552193
section Manual + Automatic
This PR (6168) (6.111M) : 0, 6111426
|
4905268 to
5ca53ec
Compare
a645a7a to
cfcc9ff
Compare
This currently fails
This reverts commit c62c192.
cfcc9ff to
cc03595
Compare
bouwkast
left a comment
There was a problem hiding this comment.
Looks good to me!
One question, do we know if the Ready to Run stuff impacts Serverless folks?
…ation (#6169) ## Summary of changes Check `instance.AutomaticTracer` for `null` before using it instead of casting ## Reason for change In #6124, we were seeing null reference exceptions. This was indicative of a separate (major) issue related to r2r (see #6168), but we still shouldn't have been throwing null refs in this case. ## Implementation details - Mark the property as nullable - Stop casting directly with `(Datadog.Trace.Tracer)instance.AutomaticTracer` - Use pattern matching to check for `null` - Log an error in `StartActiveImplementationIntegration` if we can't match, so that we still have visibility that _something_ went wrong on the managed side. ## Test coverage Tested locally to confirm it fixes the error in the tests introduced in #6168, but as those fix the root cause anyway, we won't be able to easily test for this invalid scenario ## Other details Relates to #6124
|
Superseded by #6184 |
Summary of changes
Reason for change
In #6124 we have narrowed down the root cause of a failure to get manual instrumentation to an interaction with r2r images. In this scenario, some of the methods in Datadog.Trace.Manual (
GetAutomaticTracer()specifically) do not get rejitted, even though a rejit is requested and we request rejitting of the inliner (Tracer.Instance). This causes manual instrumenation in v3 to break in this scenario).It's still not clear exactly why this is happening. It only happens in some scenarios. For example the following Program.cs (compiled with r2r for any platform) reproduces the issue
Omitting the
Task.Yield()means the problem does not reproduce. Adding additional methods at the end of this also can cause the method to not reproduce.Additionally, we rewrite some methods directly (rather than using calltarget rewriting) in
TryRejitModule(we rewriteIsManualInstrumentationOnly()). However, the rewritten method is not used. This is likely becauseJITCachedFunctionSearchStartedruns after this, and we returnuseCachedMethod=truefor the method, so the rewritten method is never used.Implementation details
We have explored various approaches (@tonyredondo is actively exploring in #6165), but the simplest is to simply disable NGEN for the Datadog.Trace.Manual module. The vast majority of this assembly is rewritten anyway (for v3 manual instrumentation) so the perf impact will be low, and it solves all of the reproduction cases.
We're pretty sure there's a more generic problem/solution here, but as it's not clear exactly what that is, this is the simplest solution to the immediate issue.
Test coverage
Added a new test that uses an r2r version of Samples.ManualInstrumentation. Prior to this fix, the test fails. With the fix, the test passes.
Other details
Fixes #6124
We briefly looked into reenabling
RequestReJITWithInlinersas in here (which was removed due to a crashing bug dotnet/runtime#77973), as this has been fixed in .NET 7+, however that simple change didn't resolve the problem + the problem exists on earlier runtimes anyway, so we need a fix that works everywhere.