-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support relative path in DD_DOTNET_TRACER_HOME
#6434
Conversation
Datadog ReportBranch report: ✅ 0 Failed, 231435 Passed, 2094 Skipped, 18h 28m 43.63s Total Time |
tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs
Outdated
Show resolved
Hide resolved
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 (6434) - mean (69ms) : 65, 72
. : milestone, 69,
master - mean (69ms) : 65, 73
. : milestone, 69,
section CallTarget+Inlining+NGEN
This PR (6434) - mean (980ms) : 959, 1001
. : milestone, 980,
master - mean (980ms) : 953, 1007
. : milestone, 980,
gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6434) - mean (108ms) : 106, 111
. : milestone, 108,
master - mean (107ms) : 105, 109
. : milestone, 107,
section CallTarget+Inlining+NGEN
This PR (6434) - mean (677ms) : 662, 692
. : milestone, 677,
master - mean (678ms) : 661, 695
. : milestone, 678,
gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6434) - mean (91ms) : 89, 93
. : milestone, 91,
master - mean (92ms) : 89, 94
. : milestone, 92,
section CallTarget+Inlining+NGEN
This PR (6434) - mean (635ms) : 615, 654
. : milestone, 635,
master - mean (633ms) : 614, 653
. : milestone, 633,
gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.6.2)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6434) - mean (194ms) : 189, 199
. : milestone, 194,
master - mean (195ms) : 190, 199
. : milestone, 195,
section CallTarget+Inlining+NGEN
This PR (6434) - mean (1,105ms) : 1075, 1136
. : milestone, 1105,
master - mean (1,099ms) : 1071, 1126
. : milestone, 1099,
gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6434) - mean (280ms) : 274, 286
. : milestone, 280,
master - mean (278ms) : 274, 281
. : milestone, 278,
section CallTarget+Inlining+NGEN
This PR (6434) - mean (870ms) : 848, 892
. : milestone, 870,
master - mean (871ms) : 839, 903
. : milestone, 871,
gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Baseline
This PR (6434) - mean (266ms) : 262, 270
. : milestone, 266,
master - mean (267ms) : 262, 273
. : milestone, 267,
section CallTarget+Inlining+NGEN
This PR (6434) - mean (851ms) : 822, 880
. : milestone, 851,
master - mean (852ms) : 817, 887
. : milestone, 852,
|
🫢 I think it broke the installer smoke tests |
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 (6434) (11.053M) : 0, 11052996
master (11.099M) : 0, 11099434
benchmarks/2.9.0 (11.144M) : 0, 11143547
section Automatic
This PR (6434) (7.329M) : 0, 7328613
master (7.256M) : 0, 7256080
benchmarks/2.9.0 (7.982M) : 0, 7981525
section Trace stats
master (7.515M) : 0, 7515192
section Manual
master (11.082M) : 0, 11081778
section Manual + Automatic
This PR (6434) (6.806M) : 0, 6805809
master (6.731M) : 0, 6730853
section DD_TRACE_ENABLED=0
master (10.311M) : 0, 10310558
gantt
title Throughput Linux arm64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6434) (9.691M) : 0, 9690908
benchmarks/2.9.0 (9.621M) : 0, 9621397
section Automatic
This PR (6434) (6.297M) : 0, 6296599
section Manual + Automatic
This PR (6434) (6.003M) : 0, 6003168
gantt
title Throughput Windows x64 (Total requests)
dateFormat X
axisFormat %s
section Baseline
This PR (6434) (9.962M) : 0, 9961805
master (10.331M) : 0, 10331051
section Automatic
This PR (6434) (6.565M) : 0, 6564654
master (6.739M) : 0, 6739399
section Trace stats
master (7.175M) : 0, 7175131
section Manual
master (9.252M) : 0, 9251665
section Manual + Automatic
This PR (6434) (6.152M) : 0, 6152210
master (5.870M) : 0, 5869714
section DD_TRACE_ENABLED=0
master (8.916M) : 0, 8916147
|
Benchmarks Report for tracer 🐌Benchmarks for #6434 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 - Faster 🎉 Same allocations ✔️
|
Benchmark | base/diff | Base Median (ns) | Diff Median (ns) | Modality |
---|---|---|---|---|
Benchmarks.Trace.SpanBenchmark.StartFinishScope‑netcoreapp3.1 | 1.229 | 808.11 | 657.35 |
Raw results
Branch | Method | Toolchain | Mean | StdError | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
---|---|---|---|---|---|---|---|---|---|
master | StartFinishSpan |
net6.0 | 399ns | 0.229ns | 0.887ns | 0.00804 | 0 | 0 | 576 B |
master | StartFinishSpan |
netcoreapp3.1 | 610ns | 0.455ns | 1.7ns | 0.00768 | 0 | 0 | 576 B |
master | StartFinishSpan |
net472 | 742ns | 0.301ns | 1.17ns | 0.0915 | 0 | 0 | 578 B |
master | StartFinishScope |
net6.0 | 481ns | 0.279ns | 1.08ns | 0.00991 | 0 | 0 | 696 B |
master | StartFinishScope |
netcoreapp3.1 | 808ns | 0.536ns | 2.08ns | 0.00929 | 0 | 0 | 696 B |
master | StartFinishScope |
net472 | 961ns | 0.532ns | 2.06ns | 0.104 | 0 | 0 | 658 B |
#6434 | StartFinishSpan |
net6.0 | 397ns | 0.29ns | 1.12ns | 0.00801 | 0 | 0 | 576 B |
#6434 | StartFinishSpan |
netcoreapp3.1 | 625ns | 0.532ns | 2.06ns | 0.00773 | 0 | 0 | 576 B |
#6434 | StartFinishSpan |
net472 | 675ns | 0.549ns | 2.13ns | 0.0918 | 0 | 0 | 578 B |
#6434 | StartFinishScope |
net6.0 | 479ns | 0.188ns | 0.676ns | 0.00986 | 0 | 0 | 696 B |
#6434 | StartFinishScope |
netcoreapp3.1 | 657ns | 0.463ns | 1.79ns | 0.00936 | 0 | 0 | 696 B |
#6434 | StartFinishScope |
net472 | 872ns | 0.558ns | 2.16ns | 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 | 588ns | 0.358ns | 1.38ns | 0.00986 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
netcoreapp3.1 | 858ns | 0.299ns | 1.12ns | 0.00947 | 0 | 0 | 696 B |
master | RunOnMethodBegin |
net472 | 1.14μs | 0.509ns | 1.97ns | 0.104 | 0 | 0 | 658 B |
#6434 | RunOnMethodBegin |
net6.0 | 646ns | 0.557ns | 2.16ns | 0.00976 | 0 | 0 | 696 B |
#6434 | RunOnMethodBegin |
netcoreapp3.1 | 951ns | 2.56ns | 9.91ns | 0.00968 | 0 | 0 | 696 B |
#6434 | RunOnMethodBegin |
net472 | 1.1μs | 0.735ns | 2.85ns | 0.104 | 0 | 0 | 658 B |
(force-pushed to before the change to |
Personally I would rather we remove the variable entirely. It's mostly unnecessary I think, given that :
The downside is that you can't point them at different places, but I think it's very unlikely anyone does that anyway, we can still respect it if it is provided, plus it seems "safer" as there's the fundamental question of "relative to what", right? |
I like it
hmm, relative to the location of the executable, but I guess that can eventually get confusing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still undecided whether we should support this, but if we do, we should add a simple integration test to confirm this works with a relative path (and that it breaks without the fix)
tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs
Outdated
Show resolved
Hide resolved
tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs
Outdated
Show resolved
Hide resolved
tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs
Outdated
Show resolved
Hide resolved
tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs
Outdated
Show resolved
Hide resolved
DD_DOTNET_TRACER_HOME
…tCore.cs Co-authored-by: Andrew Lock <[email protected]>
…tFramework.cs Co-authored-by: Andrew Lock <[email protected]>
…entationTests.cs Co-authored-by: Andrew Lock <[email protected]>
…managed loader for debugging purposes
0c7c2ce
to
6f6e684
Compare
tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs
Outdated
Show resolved
Hide resolved
path = Path.GetFullPath(path); | ||
|
||
// Need to check if the roots are different- if they are we need to return the "to" path. | ||
if (!AreRootsEqual(relativeTo, path, comparisonType)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this redundant with the check below on common length ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, I didn't look to hard, I just copied from the .NET Core implementation 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok, I thought it was a lot of work just for a test ^^
Maybe worth a comment at the top to say where it's copy/pasted from ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+ // based on https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs#L843
😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yeah right, it's just that function, not the whole file.
Summary of changes
Resolve the path read from
DD_DOTNET_TRACER_HOME
to an absolute path before trying to load an assembly from there.Reason for change
When writing a sample app and adding
Datadog.Trace.Bundle
as a dependency, it can be natural to set those variables to something like this :CORECLR_PROFILER_PATH=./datadog/osx/Datadog.Trace.ClrProfiler.Native.dylib
DD_DOTNET_TRACER_HOME=./datadog
In recent versions of .NET,
CORECLR_PROFILER_PATH
supports a relative path, butDD_DOTNET_TRACER_HOME
doesn't and never has, and throws anArgumentException
as documented when you try this with v3 of the packages.However, in v2 of the library, if you referenced
Datadog.Trace.Bundle
orDatadog.Trace
, the value ofDD_DOTNET_TRACER_HOME
was never actually used. That meant that it appeared as though relative paths worked.In actual fact, what was happening is that referencing one of these NuGet packages caused the
Datadog.Trace.dll
file to be copied to thebin
/publish
output folder. As this dll was always next to the.exe
, it was loaded automatically by the runtime, and never invoked theAssemblyResolve
event code in the managed loader to load from monitoring home.In v3, we no longer ship
Datadog.Trace.dll
in the NuGet packages, instead shippingDatadog.Trace.Manual.dll
. That means that theDD_DOTNET_TRACER_HOME
variable is used with v3, even when you reference the bundle, and gives the appearance that "relative paths are broken". To work around that, this PR adds support for relative paths.To be clear, we still don't recommend using relative paths for these variables in general. The difficulty in understanding what the path is relative to, means that it will be often be more hassle than it's worth. That said, it can make sense in the bundle scenario described above, hence this PR.
Implementation details
Call
GetFullPath()
on the value provided inDD_DOTNET_TRACER_HOME
. This uses a native call (e.g.Interop.Sys.GetCwd() on linux, GetFullPathNameW()
on Windows) to determine the full path given a (potentially) relative path.Test coverage
Path.GetRelativePath()
for .NET Framework based on the .NET Core implementation.Other details
Interestingly, getting the correct relative path in the integration tests is a massive pain. The problem is that the relative path you need is not the path relative to the executable, it's relative to "the current directory", which could be anywhere, depending on how you run the application. In the integration tests, for example, the current directory is the directory containing the integration test executable 💀