* remove use of RuntimeInformation in NativeMethods and ContainerInfo
* add new FrameworkDescription class
* use new FrameworkDescription class from Api class to set http headers
* clean up xml-doc comments
* add "OS" to Resharper's spell-check abbreviations
* change Resharper's editor style: don't _always_ chop a ternary expression into multiple lines
* revert change to nuget package reference
* refactor code into GetVersionFromAssemblyAttributes()
* make nuget reference private and add comment
* remove unnecessary call to GetTypeInfo()
* coalesce more null values to "unknown"
* add comment
* move the "try/catch" inside the "if" instead of the other way around
* remove try/catch, update comment
* update log messages
* simplify ToString()
High-Level Summary of Changes:
- 32-bit Installer: Minimal changes. This is the installer we recommend for 32-bit machines.
- 64-bit Installer: Install both the 32-bit Profiler and 64-bit Profiler in the one Installer. This is the installer we recommend for 64-bit machines, regardless of the target application's bitness.
Detailed changes:
- For 64-bit installer builds, make sure to build the 32-bit Profiler before building the MSI, place the 32-bit Profiler on-disk in "Program Files (x86)", and register the 32-bit Profiler as a COM component.
- Change the `Description` of the COM component from `Datadog .NET Tracer <bitness>-bit` to `Datadog .NET Tracer`.
- Edit `Datadog.Trace.proj` so all of the MSI dependencies are built when invoking the `Msi` target. This simplifies the packages Azure DevOps pipeline and developer building steps.
In recent changes, we realized we needed to re-install the net45 files in the GAC to allow IIS automatic instrumentation to succeed so we made the change. However, as a result, the net45 files were not placed on-disk in a subdirectory of `DD_DOTNET_TRACER_HOME`. This change fixes that by installing the files twice: once into the GAC and once on-disk.
- Edit tests project, sample projects, and reproduction projects to additionally run against `netcoreapp3.0`
- Edit unit tests using the `TargetFrameworkVersionsFact` to run against `netcoreapp3.0` if they already run against `netcoreapp2.1`
- Use the `UseDotNet@2` task to install the .NET Core SDK's in all of our test pipelines. Also, install the .NET Core 3.0 SDK in all of our pipelines.
- Split the Linux integration-tests into two separate runs: `netcoreapp2.1` and `netcoreapp3.0`
- Edit the `GeneratePackageVersions` tool to allow specifying only one `TargetFramework` for a sample app to run against (needed for `Samples.AspNetCoreMvc2`), and filter the sample apps to publish by `TargetFramework`
Product changes:
- Introduce new map data structures in the profiler to keep track of which app domain's the profiler has been loaded into and which ones have run the startup IL code, and use them to determine if it is safe to instrument a caller method based on its AppDomain.
- Edit MSI to install net45 assets into GAC. This is necessary because we still run into "security grant" issue when the assembly to instrument is domain-neutral and our profiler assembly is not.
Testing changes:
- Refactor AppDomain.Instance program to easily run subprograms to test how integrations are instrumented while run in different AppDomain's. The original subprogram is `SqlServerNestedProgram`. Add a new `ElasticsearchNestedProgram` subprogram with wrapper sample `Samples.Elasticsearch.MultipleAppDomains`, but it is not running in CI because we haven't figured out how to run Elasticsearch in Windows CI on Azure DevOps
Notes:
- As noted with the MSI, we still must have the profiler in the GAC in order to load as a domain-neutral assembly and avoid the "security grant" issue.
Product changes:
- In `Datadog.Trace.ClrProfiler.Managed.Loader` add the `AppDomain.AssemblyResolve` event handler to load managed profiler dependencies from disk where the profiler is installed. This would remove the need to install files into the GAC or add the `Datadog.Trace.ClrProfiler.Managed` NuGet package to receive auto-instrumentation.
- Stop adding assembly references to the managed profiler code in `ModuleLoadFinished` and instead do that operation in `JITCompilationStarted`. Because of this delayed reference, the runtime will not be able to resolve the assembly reference automatically (perhaps avoiding the SecurityGrant exceptions we have seen in the past!) and will rely on the newly implemented `AppDomain.AssemblyResolve` event to find the managed profiler code.
- Build `Datadog.Trace.ClrProfiler.Managed.Loader` for `netcoreapp2.0` and `net45` because reading environment variables (to obtain profiler file path) is only supported on `netstandard1.3` and higher.
Build changes:
- Combine common settings in `Directory.Build.props` for reproductions, reproduction-dependencies, and samples into `./Test.Common.props`
- For Windows-ready xUnit integration tests, add the `RunOnWindows=True` trait
- Produce managed profiler assets by running `dotnet publish Datadog.Trace.ClrProfiler.Managed` for each target framework
- Stop building `Datadog.Trace.ClrProfiler.Managed.Loader.csproj` inside `Datadog.Trace.proj`'s `BuildCpp` target and instead build it separately whenever we build `Datadog.Trace.ClrProfiler.Native`
* use tertiary operator
* add null argument checks
* replace uses of IDictionary.Get<T>() with IDictionary.GetValueOrDefault<T>()
* remove unused extension method
* rename IDictionary.TryGetValueOrDefaultAs() to TryGetValue() and refactor it
* add IDictionary.GetValueOrDefault<TValue>() extension method
* allow more time to flaky test
Fix Linux packaging build by building managed components before building the Profiler. The Profiler now needs to embed Datadog.Trace.ClrProfiler.Managed.Loader which means it must be built first.
* Add sample program EntityFramework6x.MdTokenLookupFailure
* Add configuration keys for DD_TRACE_DEBUG_LOOKUP_MDTOKEN and DD_TRACE_DEBUG_LOOKUP_FALLBACK to force MethodBuilder behaviors. This is not yet used but can be enabled later.
* Modify the build to build .NET Framework apps and restore all packages.config projects before running the Windows integration tests
* parse /proc/self/cgroup to extract container id
* unit tests for parsing /proc/self/cgroup
* add new Agent http header for container id
* add the container id http header if available
* add comments
* rename methods and variables for clarity, add xml-doc comments
* make class members public (the class itself remains internal)
* cache the container id
* remove pod regex
* merge into single regex
* add MockTracerAgent.RequestReceived event
* add internal Tracer.FlushAsync() for testing purposes
* add test that checks for container id
* run tests in Datadog.Trace.IntegrationTests and Datadog.Trace.OpenTracing.IntegrationTests
* rename test method
* remove unused "using" directive
* skip running some tests in CI, will fix in upcoming PR
* move logic to split lines into test assembly
* handle exceptions, add logging
* rename test method
* skip running some tests in CI, will fix in upcoming PR
* use MethodBuilder in AspNetMvcIntegration
* use MethodBuilder in AspNetWebApi2Integration
* use MethodBuilder in WcfIntegration
* add object.GetInstrumentedInterface() extension method
* replace uses of WithConcreteTypeName() to WithConcreteType()
* replace more uses of WithConcreteTypeName() to WithConcreteType()
* remove unused MethodBuilder.WithConcreteTypeName()
* clean up code
* rename fields for clarity
* add more type name constants
* stop using "dynamic" keyword
* use object.GetInstrumentedType()
* remove unused static Type fields
* use object.GetInstrumentedType()
* add more type name constants, remove unused static Type fields
* stop using "dynamic" keyword
* use GetInstrumentedInterface() instead of GetInstrumentedType()
The main mechanism for loading the managed profiler code was introduced in #462 (commit 4ce932f).
This PR turns on the feature for Linux. The main components are embedding the resources into the shared library, retrieving the embedded resources in the native profiler, and adding the correct PInvoke from the injected assembly load.
Fix InvalidOperationException bug when simultaneously flushing traces to the agent and appending additional spans to that list. This happens because the TraceContext can write to the same List object that was sent to the AgentWriter (which is later enumerated and invalidated if it is simultaneously being edited).
* improve logging
* merge LINQ methods
* fix signature size checks
* add new "long moduleVersionPtr" parameter to all integration wrapper methods
* pass the module_version_id pointer to every integration wrapper method
* update integrations json file
* add a check for required wrapper parameters
* add MethodBuiler overload that takes long moduleVersionPtr
* replace uses of GetCallingAssembly() with moduleVersionPtr
* remove unused MethodBuilder.Start(Assembly, ...) delegate
* rename variable for clarity
* revert whitespace changes
* re-add comment
* rename pointer variable, clean up code
* no need to materialize a new array
* fix unit tests and their comments
* fix unit test comments, redux
* Extend SmokeTestBase to allow for an override method to customize the ProcessResult assert logic.
* Revert "Extend SmokeTestBase to allow for an override method to customize the ProcessResult assert logic."
This reverts commit e16d2dac829bc446be77c1077ba052390c3f1121.
* Change dotnet.dockerfile to use the Ubuntu image instead of Alpine
* Remove ubuntu suffix from docker image
* Remove apk commands from dotnet.dockerfile
* update base docker image
Scenario: Some time after the first span is activated, we have set the
logging context properties dd.trace_id=0 and dd.span_id=0. Application
code then sets their own logging context properties. Then, a new span is
created and previously-set properties no longer exist in the logging context.
Problem: Our OnSpanActivated event immediately disposes the previously-set
correlation identifier properties before re-adding the new values.
Serilog has a strict correctness guarantee that requires properties be
modified in stack order. Since we remove properties further down the stack,
we end up losing properties.
Fix: For Serilog, do not add efault values of TraceId=0 and SpanId=0. Also,
add and remove the two properties on SpanOpened and on SpanClosed.
This ensures that properties only get added to/removed from the stack once.
* remove <RuntimeIdentifiers> and <RuntimeIdentifier> from all projects, not needed with dotnet SDK 2.1+
* update dotnet sdk version
* installer dotnet sdk earlier
* remove RIDs from sample app paths
Implementation Changes (Enabled only on Windows for now):
* Creates a new library called Datadog.Trace.ClrProfiler.Managed.Loader that is embedded in the native profiler image. When the type is loaded, it has a static constructor to call Assembly.Load on our managed profiler code in a try-catch block.
* On first JITCompilationStarted, dynamically emit IL to load the Datadog.Trace.ClrProfiler.Managed.Loader assembly and attempt to load the managed profiler code.
* Change the native profiler so no edits are made in the JITCompilationStarted event unless the managed profiler code is already loaded.
* Keep track of the app domain of mscorlib, the managed profiler assembly, and the method caller's assembly and do not edit the IL of a method if referencing the managed profiler assembly would invalidate the caller's domain-neutral assembly reference closure.
Tests and Results:
* Enable a subset of integration tests on Windows. Smoke tests and the E2E HttpClientTests are now run on Windows.
* Fixes System.IO.FileNotFoundException when trying to load (Assembly.Load) the managed profiler but it cannot be found. Adds a smoke test called AssemblyLoad.FileNotFoundException to verify the behavior (Windows-only for now).
* Fixes System.IO.FileLoadException: Loading this assembly would produce a different grant set from other instances. Adds a smoke test called SecurityGrant.FileNotFoundException to verify the behavior (only runs on .NET Framework).
* add constant for http header "Datadog-Meta-Lang-Version"
* split framework description into interpreter and version
* place managed assembly version into a local variable
* save tracer version and framework name and version into static readonly variables
* no need to keep the strings around in static vars since the HttpClient (and its headers) are kept around forever