Add markdownlint (#556)

This commit is contained in:
Piotr Kiełkowicz 2022-04-20 10:50:20 +02:00 committed by GitHub
parent e21270d242
commit 8e8bda8d7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 888 additions and 199 deletions

View File

@ -7,6 +7,12 @@ updates:
interval: "daily"
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'daily'
- package-ecosystem: nuget
directory: /build/nuke
schedule:

26
.github/workflows/markdownlint.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: markdownlint
on:
push:
branches: [ main ]
paths:
- '**.md'
- 'package-lock.json'
- 'package.json'
pull_request:
branches: [ main ]
paths:
- '**.md'
- 'package-lock.json'
- 'package.json'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.0.1
- run: npm install
- run: npm run markdownlint

3
.gitignore vendored
View File

@ -261,7 +261,8 @@ __pycache__/
*.pyc
# vscode
.vscode/
.vscode/*
!.vscode/extensions.json
.devcontainer/
# Benchmark results

7
.markdownlint.yaml Normal file
View File

@ -0,0 +1,7 @@
# Default state for all rules
default: true
# allow long lines for tables and code blocks
MD013:
code_blocks: false
tables: false

5
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"davidanson.vscode-markdownlint",
]
}

View File

@ -10,7 +10,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
The is an initial, official beta release,
built on top of [OpenTelemetry .NET](https://github.com/open-telemetry/opentelemetry-dotnet):
- [Core components](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#core-components): [`1.2.0`](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.2.0)
- [Core components](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#core-components):
[`1.2.0`](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.2.0)
- Non-core components: [`1.0.0-rc9.2`](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/1.0.0-rc9.2)
- `System.Diagnostics.DiagnosticSource`: [`6.0.0`](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/6.0.0)

View File

@ -10,6 +10,7 @@ using Nuke.Common.ProjectModel;
using Nuke.Common.Tooling;
using Nuke.Common.Tools.DotNet;
using Nuke.Common.Tools.MSBuild;
using Nuke.Common.Tools.Npm;
using Nuke.Common.Tools.NuGet;
using Nuke.Common.Utilities.Collections;
using Serilog;
@ -353,6 +354,29 @@ partial class Build
});
});
Target InstallMarkdownLint => _ => _
.Description("Installs markdownlint-cli locally. npm is required")
.Executes(() =>
{
NpmTasks.NpmInstall();
});
Target MarkdownLint => _ => _
.Description("Executes MarkdownLint")
.After(InstallMarkdownLint)
.Executes(() =>
{
NpmTasks.NpmRun(s => s.SetCommand(@"markdownlint"));
});
Target MarkdownLintFix => _ => _
.Description("Trying to fix MarkdownLint issues")
.After(InstallMarkdownLint)
.Executes(() =>
{
NpmTasks.NpmRun(s => s.SetCommand(@"markdownlint-fix"));
});
private AbsolutePath GetResultsDirectory(Project proj) => BuildDataDirectory / "results" / proj.Name;
/// <summary>

View File

@ -4,7 +4,8 @@
We'd love your help!
Please join our weekly [SIG meeting](https://github.com/open-telemetry/community#special-interest-groups) or get in touch on [Slack](https://cloud-native.slack.com/archives/C01NR1YLSE7).
Please join our weekly [SIG meeting](https://github.com/open-telemetry/community#special-interest-groups)
or get in touch on [Slack](https://cloud-native.slack.com/archives/C01NR1YLSE7).
Meeting notes are available as a public [Google
doc](https://docs.google.com/document/d/1XedN2D8_PH4YLej-maT8sp4RKogfuhFpccRi3QpUcoI/edit?usp=sharing).
@ -22,7 +23,7 @@ Reporting bugs is an important contribution. Please make sure to include:
If you would like to work on something that is not listed as an issue
(e.g. a new feature or enhancement) please first read our [DESIGN.md](DESIGN.md)
to make sure your proposal aligns with the goals of the
project, then create an issue and describe your proposal.
project, then create an issue and describe your proposal.
## How to contribute
@ -40,8 +41,9 @@ clarify anything related to it.
If you would like to work on something that is not listed as an issue,
please [request a feature](#request-a-feature) first.
It is best to do this in advance so that maintainers can decide if the proposal is a good fit for
this repository. This will help avoid situations when you spend significant time
It is best to do this in advance so that maintainers can decide if the proposal
is a good fit for this repository.
This will help avoid situations when you spend significant time
on something that maintainers may decide this repo is not the right place for.
See [developing.md](developing.md) to learn more about

View File

@ -7,11 +7,13 @@ to .NET applications without having to modify their source code.
OpenTelemetry .NET Automatic Instrumentation is built on top of [OpenTelemetry .NET](https://github.com/open-telemetry/opentelemetry-dotnet):
- [Core components](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#core-components): [`1.2.0`](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.2.0)
- [Core components](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#core-components):
[`1.2.0`](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.2.0)
- Non-core components: [`1.0.0-rc9.2`](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/1.0.0-rc9.2)
- `System.Diagnostics.DiagnosticSource`: [`6.0.0`](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/6.0.0)
To automatically instrument applications, the OpenTelemetry .NET Automatic Instrumentation does the following:
To automatically instrument applications, the OpenTelemetry .NET Automatic
Instrumentation does the following:
1. Injects and configures the [OpenTelemetry .NET SDK](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/README.md#opentelemetry-net-sdk)
into the application.

View File

@ -9,7 +9,6 @@
| `OTEL_DOTNET_AUTO_INCLUDE_PROCESSES` | Names of the executable files that the profiler can instrument. Supports multiple comma-separated values, for example: `MyApp.exe,dotnet.exe`. If unset, the profiler attaches to all processes by default. | |
| `OTEL_DOTNET_AUTO_EXCLUDE_PROCESSES` | Names of the executable files that the profiler cannot instrument. Supports multiple comma-separated values, for example: `ReservedProcess.exe,powershell.exe`. The list is processed after `OTEL_DOTNET_AUTO_INCLUDE_PROCESSES`. If unset, the profiler attaches to all processes by default. | |
| `OTEL_DOTNET_AUTO_AZURE_APP_SERVICES` | Set to indicate that the profiler is running in the context of Azure App Services. | `false` |
## Resources
@ -49,7 +48,8 @@ for more details.
ASP.NET instrumentation on .NET Framework requires to install the
[`OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/)
NuGet package in the instrumented project.
See [the WebConfig section](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.AspNet#step-2-modify-webconfig) for more information.
See [the WebConfig section](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.AspNet#step-2-modify-webconfig)
for more information.
## Logging
@ -59,7 +59,8 @@ The default log directory paths are:
- Linux: `/var/log/opentelemetry/dotnet`
If the default log directories can't be created,
the instrumentation uses the path of the current user's [temporary folder](https://docs.microsoft.com/en-us/dotnet/api/System.IO.Path.GetTempPath?view=net-6.0) instead.
the instrumentation uses the path of the current user's [temporary folder](https://docs.microsoft.com/en-us/dotnet/api/System.IO.Path.GetTempPath?view=net-6.0)
instead.
| Environment variable | Description | Default |
|-|-|-|
@ -89,8 +90,9 @@ Exporters output the telemetry.
**[1]**: Considerations on the `OTEL_EXPORTER_OTLP_PROTOCOL`:
- On .NET 5 and higher, the application must reference [`Grpc.Net.Client`](https://www.nuget.org/packages/Grpc.Net.Client/)
to use the `grpc` OTLP exporter protocol. For example, by adding
`<PackageReference Include="Grpc.Net.Client" Version="2.32.0" />` to the `.csproj` file.
to use the `grpc` OTLP exporter protocol. For example, by adding
`<PackageReference Include="Grpc.Net.Client" Version="2.32.0" />` to the `.csproj`
file.
- On .NET Framework, the `grpc` OTLP exporter protocol is not supported.
## Batch span processor
@ -114,7 +116,6 @@ The batch span processor batches finished spans before sending them through the
| `OTEL_DOTNET_AUTO_FLUSH_ON_UNHANDLEDEXCEPTION` | Controls whether the telemetry data is flushed when an [AppDomain.UnhandledException](https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception) event is raised. Set to `true` when you suspect that you are experiencing a problem with missing telemetry data and also experiencing unhandled exceptions. | `false` |
| `OTEL_DOTNET_AUTO_INSTRUMENTATION_PLUGINS` | Colon-separated list of OTel SDK instrumentation plugins represented by `System.Type.AssemblyQualifiedName`. | |
You can use `OTEL_DOTNET_AUTO_INSTRUMENTATION_PLUGINS` to extend the
configuration of the OpenTelemetry .NET SDK Tracer. A plugin must be a
non-static, non-abstract class which has a default constructor and a method
@ -131,7 +132,7 @@ OpenTelemetry .NET Automatic Instrumentation.
To perform bytecode instrumentation, configure the OpenTelemetry .NET
Automatic Instrumentation as a .NET CLR Profiler. The CLR uses the following
environment variables to set up the profiler.
environment variables to set up the profiler.
> Notice that .NET Framework uses the `COR_` prefix instead of `CORECLR_`.
@ -143,9 +144,11 @@ environment variables to set up the profiler.
| `CORECLR_PROFILER_PATH_32` | Path to the 32-bit profiler. Bitness-specific paths take precedence over generic paths. | `%InstallationLocation%/win-x86/OpenTelemetry.AutoInstrumentation.Native.dll` for Windows |
| `CORECLR_PROFILER_PATH_64` | Path to the 64-bit profiler. Bitness-specific paths take precedence over generic paths. | `%InstallationLocation%/win-x64/OpenTelemetry.AutoInstrumentation.Native.dll` for Windows |
The `*_PROFILER_PATH_*` environment variable is not needed on Windows if the DLL file is already registered.
The `*_PROFILER_PATH_*` environment variable is not needed on Windows if the DLL
file is already registered.
See [.NET Runtime Profiler Loading](https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/profiling/Profiler%20Loading.md) for more information.
See [.NET Runtime Profiler Loading](https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/profiling/Profiler%20Loading.md)
for more information.
## .NET Runtime additional dependencies and package store

View File

@ -2,43 +2,52 @@
## Vision
The following are the goals that define the long-term vision for the project. The vision guides daily activities, design, and feature acceptance.
The following are the goals that define the long-term vision for the project.
The vision guides daily activities, design, and feature acceptance.
- **High performance**: Automatic instrumentation performance impact should not be a concern for users.
- **Reliability**: Stable and performant under different loads. Well-behaved under extreme load, with low, predictable resource consumption.
- **Visibility**: Users should be able to generate telemetry that provides deep and detailed visibility into their applications. Such telemetry must allow users to identify and solve application-related issues in production.
- **Useful by default**: After installations users should be able to get telemetry from targeted libraries with none or minimal configuration, thanks to a good selection of default settings.
- **High performance**: Automatic instrumentation performance impact
should not be a concern for users.
- **Reliability**: Stable and performant under different loads. Well-behaved
under extreme load, with low, predictable resource consumption.
- **Visibility**: Users should be able to generate telemetry that provides deep
and detailed visibility into their applications. Such telemetry must allow users
to identify and solve application-related issues in production.
- **Useful by default**: After installations users should be able to get telemetry
from targeted libraries with none or minimal configuration,
thanks to a good selection of default settings.
- **Extensible**: Users can choose key components through configuration and plugins.
## Supported and unsupported scenarios
### Supported scenarios
- **Zero-touch source code instrumentation**: Users can instrument applications without changing
the source. Build changes may be required through the addition of specific NuGet packages.
- **Custom SDK support**: The instrumentation can initialize the OpenTelemetry .NET SDK, though
what OpenTelemetry SDK implementation is used and its initialization can also be delegated
to the application code.
- **Zero-touch source code instrumentation**: Users can instrument applications
without changing the source. Build changes may be required through the addition
of specific NuGet packages.
- **Custom SDK support**: The instrumentation can initialize
the OpenTelemetry .NET SDK, though what OpenTelemetry SDK implementation is used
and its initialization can also be delegated to the application code.
### Unsupported scenarios:
### Unsupported scenarios
- **Applications using Ahead-of-Time (AOT) compilation**: The current implementation relies on the
[CLR Profiler APIs](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/)
- **Applications using Ahead-of-Time (AOT) compilation**:
The current implementation relies on the [CLR Profiler APIs](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/)
and doesn't support AOT.
- **Side-by-side usage with other CLR Profiler based tools**: Various tools for .NET
are also implemented using a CLR Profiler. However, only a single CLR Profiler can be used when running
the application.
are also implemented using a CLR Profiler. However, only a single CLR Profiler
can be used when running the application.
## Error handling
Initialization errors, usually caused by invalid configuration, are logged and crash the application.
Initialization errors, usually caused by invalid configuration,
are logged and crash the application.
Errors occurring at application runtime are logged and should never crash the application.
## Architecture
To instrument a .NET application without requiring source code changes, the OpenTelemetry .NET Instrumentation uses the
[CLR Profiler APIs](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/)
To instrument a .NET application without requiring source code changes,
the OpenTelemetry .NET Instrumentation uses the [CLR Profiler APIs](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/)
to bootstrap the [OpenTelemetry .NET SDK](https://github.com/open-telemetry/opentelemetry-dotnet#readme)
and inject the selected instrumentations into the targeted application.
@ -46,14 +55,15 @@ The main components of the project are:
- [**CLR Profiler DLL**](../src/OpenTelemetry.AutoInstrumentation.Native):
Native component that implements a CLR Profiler. The CLR Profiler is used to
modify the application [intermediate language](https://en.wikipedia.org/wiki/Common_Intermediate_Language) (IL),
including the IL of packages used by the application, to add and collect observability data.
modify the application [intermediate language](https://en.wikipedia.org/wiki/Common_Intermediate_Language)
(IL), including the IL of packages used by the application, to add and collect
observability data.
- [**Loader**](../src/OpenTelemetry.AutoInstrumentation.Loader):
Managed library shipped as a resource of the native CLR Profiler.
It loads the bootstrap code into the targeted application and extends the assembly
load paths to include the folders with the OpenTelemetry .NET SDK and the instrumentations to be
injected into the application.
load paths to include the folders with the OpenTelemetry .NET SDK
and the instrumentations to be injected into the application.
- [**Managed Profiler**](../src/OpenTelemetry.AutoInstrumentation):
Contains the code to set up the OpenTelemetry .NET SDK and configured instrumentations,
@ -61,17 +71,19 @@ as well as support code to run and implement bytecode instrumentations. Set the
`OTEL_DOTNET_AUTO_LOAD_AT_STARTUP` environment variable to `false` when the
application initializes the OpenTelemetry .NET SDK Tracer on its own.
- **Source Instrumentations**: Instrumentations created on top of API hooks or callbacks provided
directly by the library or framework being instrumented. This type of instrumentation depends on the
OpenTelemetry API and the specific library or framework that they instrument. Some examples include:
- **Source Instrumentations**: Instrumentations created on top of API hooks
or callbacks provided directly by the library or framework being instrumented.
This type of instrumentation depends on the OpenTelemetry API and the specific
library or framework that they instrument. Some examples include:
- [ASP.NET Core Instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.AspNetCore)
- [gRPC Client Instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.GrpcNetClient)
- [HttpClient and HttpWebRequest Instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.Http)
- **Bytecode Instrumentations**: Instrumentations created for libraries or frameworks that lack proper
hooks or callbacks to allow the collection of observability data. These instrumentations must be
implemented following the proper attribute annotation so that the native CLR Profiler implementation
- **Bytecode Instrumentations**: Instrumentations created for libraries
or frameworks that lack proper hooks or callbacks to allow the collection
of observability data. These instrumentations must be implemented following
the proper attribute annotation so that the native CLR Profiler implementation
can inject them at runtime. Some examples include:
- [GraphQL](../src/OpenTelemetry.AutoInstrumentation/Instrumentations/GraphQL)
@ -80,49 +92,58 @@ can inject them at runtime. Some examples include:
### Injecting the OpenTelemetry .NET SDK and instrumentations
The OpenTelemetry .NET SDK and selected source instrumentations are injected into the target process
through a series of steps started by the CLR Profiler DLL:
The OpenTelemetry .NET SDK and selected source instrumentations are injected
into the target process through a series of steps started by the CLR Profiler DLL:
1. On the [CorProfiler::ModuleLoadFinished](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-moduleloadfinished-method)
callback, the CLR Profiler DLL takes the following actions:
- If the loaded module is in the set of modules for which there is bytecode instrumentation,
or if it's the first non-corelib module or not in one of the special cases, the profiler adds
the module to a map of modules to be instrumented.
- If there is bytecode instrumentation for the module, the profiler requests a JIT recompilation using
[ICorProfilerInfo::RequestReJIT](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilerinfo4-requestrejit-method)
for the methods targeted by the bytecode instrumentation.
- If the loaded module is in the set of modules for which there is bytecode instrumentation,
or if it's the first non-corelib module or not in one of the special cases,
the profiler adds the module to a map of modules to be instrumented.
- If there is bytecode instrumentation for the module, the profiler requests
a JIT recompilation using
[ICorProfilerInfo::RequestReJIT](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilerinfo4-requestrejit-method)
for the methods targeted by the bytecode instrumentation.
2. On the [CorProfiler::JITCompilationStarted](https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilercallback-jitcompilationstarted-method)
callback, the CLR Profiler DLL takes the following actions:
- If instrumenting he first module in the current AppDomain, the profiler injects the IL calling the
Loader `Startup` type constructor. This type of constructor:
* Adds an event handler to the
[`AssemblyResolve`](https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.assemblyresolve?view=net-5.0),
so that it can add any assembly needed by the SDK itself or by any instrumentation.
* Runs, through reflection, the `Initialization` method from the Managed Profiler assembly.
- The `Initialization` code bootstraps the OpenTelemetry .NET SDK, adding configured processors, exporters,
and so on, and initializes any configured source instrumentations.
- If the first method observed by JITCompilationStarted is IIS startup code, the profiler invokes
`AppDomain.CurrentDomain.SetData("OpenTelemetry_IISPreInitStart", true)`, so that automatic instrumentation
- If instrumenting he first module in the current AppDomain,
the profiler injects the IL calling the Loader `Startup` type constructor.
This type of constructor:
- Adds an event handler to the
[`AssemblyResolve`](https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.assemblyresolve?view=net-5.0),
so that it can add any assembly needed by the SDK itself or by any instrumentation.
- Runs, through reflection, the `Initialization` method from
the Managed Profiler assembly.
- The `Initialization` code bootstraps the OpenTelemetry .NET SDK,
adding configured processors, exporters, and so on,
and initializes any configured source instrumentations.
- If the first method observed by JITCompilationStarted is IIS startup code,
the profiler invokes
`AppDomain.CurrentDomain.SetData("OpenTelemetry_IISPreInitStart", true)`,
so that automatic instrumentation
correctly handles IIS startup scenarios.
### Bytecode instrumentations
The bytecode instrumentation, called "call target" in this repo, relies on the JIT recompilation
capability of the CLR to rewrite the IL for instrumented methods. This adds logic at
the beginning and end of the instrumented methods to invoke instrumentation written in this repo, and
wraps the calls with try-catch blocks to prevent instrumentation errors from affecting the normal operation
The bytecode instrumentation, called "call target" in this repo, relies on
the JIT recompilation capability of the CLR to rewrite the IL for instrumented
methods. This adds logic at the beginning and end of the instrumented methods
to invoke instrumentation written in this repo, and wraps the calls with
try-catch blocks to prevent instrumentation errors from affecting the normal operation
of the application.
Bytecode instrumentation methods should not have direct dependencies with the libraries that they instrument.
This way, they can work with multiple versions of the assemblies targeted for instrumentation
and reduce the number of shipped files.
Bytecode instrumentation methods should not have direct dependencies with
the libraries that they instrument. This way, they can work with multiple
versions of the assemblies targeted for instrumentation and reduce the number
of shipped files.
When operating with parameters and return values of the targeted methods, the instrumentation methods must use
[DuckTyping](../src/OpenTelemetry.AutoInstrumentation.Managed/DuckTyping/README.md) or
[reflection](https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection)
When operating with parameters and return values of the targeted methods,
the instrumentation methods must use [DuckTyping](../src/OpenTelemetry.AutoInstrumentation.Managed/DuckTyping/README.md)
or [reflection](https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection)
to access objects from the APIs being instrumented.
### Assembly conflict resolution
@ -132,37 +153,44 @@ the risk of assembly version conflicts. This issue is more likely with the
[NuGet package System.Diagnostic.DiagnosticSource](https://www.nuget.org/packages/System.Diagnostics.DiagnosticSource/)
and its dependencies, because it contains the [Activity type](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.activity?view=net-5.0)
used by the OpenTelemetry .NET API to represent a span. This package, previously
released by Microsoft, is already used by various applications.
released by Microsoft, is already used by various applications.
Two issues might arise from incorrect versioning:
1. Version required by the OpenTelemetry .NET SDK or the instrumentations is not met.
2. Multiple versions of the assembly in the same process, as the runtime treats them independently.
1. Version required by the OpenTelemetry .NET SDK or the instrumentations
is not met.
2. Multiple versions of the assembly in the same process,
as the runtime treats them independently.
#### Configuration resolution
.NET Core [Framework-dependent deployment](https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli#framework-dependent-deployment) applications might use
[DOTNET_ADDITIONAL_DEPS](https://github.com/dotnet/runtime/blob/main/docs/design/features/additional-deps.md) and
[DOTNET_SHARED_STORE](https://docs.microsoft.com/en-us/dotnet/core/deploying/runtime-store) from
OpenTelemetry .NET Automatic Instrumentation installation location to resolve assembly conflicts.
.NET Core [Framework-dependent deployment](https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli#framework-dependent-deployment)
applications might use [DOTNET_ADDITIONAL_DEPS](https://github.com/dotnet/runtime/blob/main/docs/design/features/additional-deps.md)
and [DOTNET_SHARED_STORE](https://docs.microsoft.com/en-us/dotnet/core/deploying/runtime-store)
from OpenTelemetry .NET Automatic Instrumentation installation location
to resolve assembly conflicts.
#### Build time resolution
Currently, the path to resolving such conflicts is to add or update any package reference used by
the application to the versions required by the OpenTelemetry .NET SDK and the instrumentations.
Even if the application itself doesn't directly reference a conflicting dependency, this might still
be necessary due to conflicts created by any indirect dependency.
Currently, the path to resolving such conflicts is to add or update any package
reference used by the application to the versions required by
the OpenTelemetry .NET SDK and the instrumentations.
Even if the application itself doesn't directly reference a conflicting
dependency, this might still be necessary due to conflicts created by
any indirect dependency.
Adding or updating package references works because of the way
Adding or updating package references works because of the way
[NuGet Package Dependency Resolution](https://docs.microsoft.com/en-us/nuget/concepts/dependency-resolution)
is implemented. Conflicts are resolved by having explicit package references to the correct package versions.
is implemented. Conflicts are resolved by having explicit package references
to the correct package versions.
To simplify this process, we plan to create a NuGet package that installs the CLR Profiler and its managed dependencies.
To simplify this process, we plan to create a NuGet package that installs
the CLR Profiler and its managed dependencies.
#### Runtime time resolution
If you can't change the application build to add or update the necessary package versions,
you can still address conflicts using the methods described in
If you can't change the application build to add or update the necessary package
versions, you can still address conflicts using the methods described in
[Handling of Assembly version Conflicts](./troubleshooting.md#handling-of-assembly-version-conflicts).
## Further reading

View File

@ -36,7 +36,7 @@ follow these steps to set `omnisharp.useGlobalMono` to `never`:
2. Change `Omnisharp: Use Global Mono` to `never`.
3. Restart OmniSharp by pressing `F1` and selecting `OmniSharp: Restart OmniSharp`.
If you get errors due to projects targeting .NET Framework, use
If you get errors due to projects targeting .NET Framework, use
`OmniSharp: Select Project` in Visual Studio Code to load a subset of projects
which work without any issues. You can also try building the projects which throw
errors.
@ -47,12 +47,13 @@ This repository uses [Nuke](https://nuke.build/) for build automation.
Support plugins are available for:
- JetBrains ReSharper https://nuke.build/resharper
- JetBrains Rider https://nuke.build/rider
- Microsoft VisualStudio https://nuke.build/visualstudio
- Microsoft VSCode https://nuke.build/vscode
- JetBrains ReSharper <https://nuke.build/resharper>
- JetBrains Rider <https://nuke.build/rider>
- Microsoft VisualStudio <https://nuke.build/visualstudio>
- Microsoft VSCode <https://nuke.build/vscode>
Restore dotnet tools to prepare build tools for solution. This installs the dotnet `nuke` tool locally.
Restore dotnet tools to prepare build tools for solution.
This installs the dotnet `nuke` tool locally.
```cmd
dotnet tool restore
@ -78,6 +79,23 @@ Clean your repository by running:
git clean -fXd
```
### Documentation lint
If you made changes to the Markdown documents (`*.md` files), ensure that lint
tool passed without any issues by executing:
```cmd
nuke InstallMarkdownLint MarkdownLint
```
Some issues can be automatically fixed by:
```cmd
nuke MarkdownLintFix
```
All MarkdownLint tasks require [Node.js](https://nodejs.org/) installed locally.
## Manual testing
### Test environment
@ -110,8 +128,8 @@ For example:
./dev/instrument.sh OTEL_DOTNET_AUTO_ENABLED_INSTRUMENTATIONS=HttpClient dotnet run -f netcoreapp3.1 --project ./examples/ConsoleApp/Examples.ConsoleApp.csproj
```
You can use [`dev/envvars.sh`](../dev/envvars.sh) to export profiler environmental variables to your
current shell session.
You can use [`dev/envvars.sh`](../dev/envvars.sh) to export profiler
environmental variables to your current shell session.
You must run `dev/envvars.sh` from the root of this repository. For example:
@ -124,7 +142,8 @@ export OTEL_DOTNET_AUTO_ENABLED_INSTRUMENTATIONS=HttpClient
### Running the examples
You can use the example applications to see the local changes in action. See
[`examples/README.md`](../examples/README.md) for instructions on how to run the examples.
[`examples/README.md`](../examples/README.md) for instructions on
how to run the examples.
## Release process

View File

@ -2,7 +2,8 @@
The automatic instrumentation provides a base you can build on by adding your own
manual instrumentation. By using both automatic and manual instrumentation, you can
better instrument the logic and functionality of your applications, clients, and frameworks.
better instrument the logic and functionality of your applications, clients,
and frameworks.
To create your custom traces manually, follow these steps:

View File

@ -3,20 +3,20 @@
## Handling of assembly version conflicts
OpenTelemetry SDK NuGet packages are deployed with the OpenTelemetry .NET Instrumentation.
To handle conflicts in assemblies referenced by "source instrumentations", update the project
references to ensure that they are on the same versions as the ones used by the instrumentation.
To handle conflicts in assemblies referenced by "source instrumentations",
update the project references to ensure that they are on the same versions
as the ones used by the instrumentation.
Previous workarounds only work at build time. When a rebuild is not possible, use one of the
following suggestions to force the application to use the assembly versions shipped with the
instrumentation.
Previous workarounds only work at build time. When a rebuild is not possible,
use one of the following suggestions to force the application to use
the assembly versions shipped with the instrumentation.
For .NET Framework applications, the workaround is to use binding redirects. For .NET Core
[Framework-dependent deployment](https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-vs?tabs=vs156#framework-dependent-deployment)
applications,
[Additional-deps](https://github.com/dotnet/runtime/blob/main/docs/design/features/additional-deps.md),
For .NET Framework applications, the workaround is to use binding redirects.
For .NET Core [Framework-dependent deployment](https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-vs?tabs=vs156#framework-dependent-deployment)
applications, [Additional-deps](https://github.com/dotnet/runtime/blob/main/docs/design/features/additional-deps.md),
and [runtime package store](https://docs.microsoft.com/en-us/dotnet/core/deploying/runtime-store)
from OpenTelemetry .NET, use the automatic instrumentation installation path. For other .NET Core
deployment models, edit the `deps.json` file.
from OpenTelemetry .NET, use the automatic instrumentation installation path.
For other .NET Core deployment models, edit the `deps.json` file.
### .NET Framework binding redirects
@ -28,15 +28,16 @@ that is not available at build time.
### .NET Core dependency file
To fix assembly version conflicts in .NET Core, edit the default `<application>.deps.json` file
generated at build for .NET Core applications. Build a .NET Core app with package
references using the required version, and use the respective `deps.json` file to see what changes
are needed.
To fix assembly version conflicts in .NET Core, edit the default
`<application>.deps.json` file generated at build for .NET Core applications.
Build a .NET Core app with package references using the required version,
and use the respective `deps.json` file to see what changes are needed.
To test your edits to the `deps.json` file, add a reference to the required version of the OpenTelemetry
package to the [examples/CoreAppOldReference](./../examples/CoreAppOldReference/) example and rebuild the
application. Save the generated `deps.json` file, remove the package reference, and rebuild the
example app. Compare the files to explore the changes.
To test your edits to the `deps.json` file, add a reference to the required
version of the OpenTelemetry package to the [examples/CoreAppOldReference](./../examples/CoreAppOldReference/)
example and rebuild the application. Save the generated `deps.json` file,
remove the package reference, and rebuild the example app.
Compare the files to explore the changes.
## No proper relationship between spans
@ -44,11 +45,14 @@ On .NET Framework, strong name signing can force the loading of multiple version
of the same assembly on the same process. This causes a separate hierarchy of
Activity objects. If you are referencing packages in your application that use a
version of the `System.Diagnostics.DiagnosticSource` different than the `OpenTelemetry.Api`
version used by the OpenTelemetry .NET Automatic Instrumentation, reference the correct version of the `System.Diagnostics.DiagnosticSource` package in your application.
version used by the OpenTelemetry .NET Automatic Instrumentation, reference
the correct version of the `System.Diagnostics.DiagnosticSource` package
in your application.
This causes automatic binding redirection to solve the issue.
If automatic binding redirection is [disabled](https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/how-to-enable-and-disable-automatic-binding-redirection)
you can also manually add binding redirection to the [`App.config`](../examples/BindingRedirect/App.config) file.
you can also manually add binding redirection to the [`App.config`](../examples/BindingRedirect/App.config)
file.
## High CPU usage

View File

@ -9,10 +9,14 @@ The example script instruments two .NET processes. These processes are identifie
as [OpenTelemetry services](https://github.com/open-telemetry/opentelemetry-specification/blob/d6bcc0cb072d8d6f6ced856f1f23c451648a3caa/specification/resource/semantic_conventions/README.md#service)
with the following names:
1. **`aspnet-server`**: ASP.NET Core application that makes requests to MongoDB and Redis databases.
2. **`{exampleApp}`**: .NET application that makes a few HTTP requests to the `aspnet-server` and some public websites. The exact name is equal to `exampleApp` value.
1. **`aspnet-server`**: ASP.NET Core application that makes requests to MongoDB
and Redis databases.
2. **`{exampleApp}`**: .NET application that makes a few HTTP requests
to the `aspnet-server` and some public websites. The exact name is equal
to `exampleApp` value.
The script creates Docker containers for MongoDB, Redis, Jaeger, and the [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/).
The script creates Docker containers for MongoDB, Redis, Jaeger,
and the [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/).
You can see the traces generated by the example in the Jaeger container.
The number and organization of traces generated depends on the `http-client`
used in the specific run. The script waits for your input before stopping the containers.
@ -48,9 +52,11 @@ exampleAppTargetFramework="net6.0" ./run-example.sh
### AspNetCoreMvc
An ASP.NET Core MVC application used to simulate a server application capable of making calls
to MongoDB and Redis. In addition to these calls, it also supports various other endpoints. Check
the [Controllers](./AspNetCoreMvc/Controllers/) for some of the endpoints you can use.
An ASP.NET Core MVC application used to simulate a server application capable
of making calls to MongoDB and Redis. In addition to these calls,
it also supports various other endpoints.
Check the [Controllers](./AspNetCoreMvc/Controllers/) for some
of the endpoints you can use.
Usage example:
@ -60,14 +66,17 @@ aspNetAppTargetFramework="net6.0" ./run-example.sh
### BindingRedirect
Example client app that uses .NET Framework binding redirects to handle assembly version conflict
between automatic instrumentation and third-party libraries that cannot be updated to the same
version required by OpenTelemetry. See the `OldReference` project for more information.
Example client app that uses .NET Framework binding redirects to handle assembly
version conflict between automatic instrumentation and third-party libraries
that cannot be updated to the same version required by OpenTelemetry.
See the `OldReference` project for more information.
The project representing the third-party library has a legacy Activity named `InstrumentedHttpCall.GetAsync`
set [`OTEL_DOTNET_AUTO_LEGACY_SOURCES`](../docs/config.md#customization) to capture it.
set [`OTEL_DOTNET_AUTO_LEGACY_SOURCES`](../docs/config.md#customization)
to capture it.
The following usage example is for Windows, as binding redirection only applies to .NET Framework:
The following usage example is for Windows, as binding redirection only applies
to .NET Framework:
```bash
OTEL_DOTNET_AUTO_LEGACY_SOURCES="InstrumentedHttpCall.GetAsync" exampleApp=BindingRedirect exampleAppTargetFramework=net472 ./run-example.sh
@ -87,14 +96,16 @@ exampleAppTargetFramework="net6.0" ./run-example.sh
A client app that bootstraps the OpenTelemetry SDK. It uses an
[ActivitySource](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/README.md#activity-source)
to implement manual instrumentation. The bootstrap code takes care of adding the ActivitySource name
for the automatic instrumentation and the manual instrumentation.
to implement manual instrumentation. The bootstrap code takes care of adding
the ActivitySource name for the automatic instrumentation and the manual instrumentation.
The bootstrap code enables the [Zipkin exporter](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Zipkin/README.md)
provided by the SDK. The OpenTelemetry collector container is also configured to accept Zipkin spans.
provided by the SDK. The OpenTelemetry collector container is also configured
to accept Zipkin spans.
Use the environment variable `exampleAppInjectSDK` in the script to control the value of
[`OTEL_DOTNET_AUTO_LOAD_AT_STARTUP`](../docs/config.md#customization). For example:
Use the environment variable `exampleAppInjectSDK` in the script to control
the value of [`OTEL_DOTNET_AUTO_LOAD_AT_STARTUP`](../docs/config.md#customization).
For example:
```bash
exampleAppInjectSDK=false exampleApp=ConsoleApp.SelfBootstrap ./run-example.sh
@ -102,11 +113,14 @@ exampleAppInjectSDK=false exampleApp=ConsoleApp.SelfBootstrap ./run-example.sh
### CoreAppOldReference
Example client application that uses NuGet package version resolution at build time to handle assembly version conflict
between automatic instrumentation and third-party libraries that can't be updated to the same version required by OpenTelemetry. See the `OldReference` project for more information.
Example client application that uses NuGet package version resolution at build
time to handle assembly version conflict between automatic instrumentation
and third-party libraries that can't be updated to the same version required
by OpenTelemetry. See the `OldReference` project for more information.
The project representing the third-party library has a legacy Activity named `InstrumentedHttpCall.GetAsync`
set [`OTEL_DOTNET_AUTO_LEGACY_SOURCES`](../docs/config.md#customization) to capture it.
set [`OTEL_DOTNET_AUTO_LEGACY_SOURCES`](../docs/config.md#customization)
to capture it.
Usage example:
@ -126,8 +140,8 @@ OTEL_DOTNET_AUTO_ADDITIONAL_SOURCES="Examples.ManualInstrumentations.*" exampleA
### OldReference
Represents a third-party project that can't be updated to use the same version of the assemblies
required by OpenTelemetry .NET SDK used by the automatic instrumentation.
Represents a third-party project that can't be updated to use the same version
of the assemblies required by OpenTelemetry .NET SDK used by the automatic instrumentation.
### OpenTracing.Library

487
package-lock.json generated Normal file
View File

@ -0,0 +1,487 @@
{
"name": "opentelemetry-dotnet-instrumentation",
"version": "0.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "opentelemetry-dotnet-instrumentation",
"version": "0.0.1",
"license": "Apache-2.0",
"dependencies": {
"markdownlint-cli": "^0.31.1"
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/commander": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
"integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==",
"engines": {
"node": "^12.20.0 || >=14"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/entities": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"node_modules/get-stdin": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
"integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
},
"engines": {
"node": "*"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ignore": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"engines": {
"node": ">= 4"
}
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ini": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
"integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
"engines": {
"node": ">=10"
}
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/jsonc-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA=="
},
"node_modules/linkify-it": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/markdown-it": {
"version": "12.3.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
"integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
"dependencies": {
"argparse": "^2.0.1",
"entities": "~2.1.0",
"linkify-it": "^3.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
"bin": {
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/markdownlint": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz",
"integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==",
"dependencies": {
"markdown-it": "12.3.2"
},
"engines": {
"node": ">=12"
}
},
"node_modules/markdownlint-cli": {
"version": "0.31.1",
"resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.1.tgz",
"integrity": "sha512-keIOMwQn+Ch7MoBwA+TdkyVMuxAeZFEGmIIlvwgV0Z1TGS5MxPnRr29XCLhkNzCHU+uNKGjU+VEjLX+Z9kli6g==",
"dependencies": {
"commander": "~9.0.0",
"get-stdin": "~9.0.0",
"glob": "~7.2.0",
"ignore": "~5.2.0",
"js-yaml": "^4.1.0",
"jsonc-parser": "~3.0.0",
"markdownlint": "~0.25.1",
"markdownlint-rule-helpers": "~0.16.0",
"minimatch": "~3.0.5",
"run-con": "~1.2.10"
},
"bin": {
"markdownlint": "markdownlint.js"
},
"engines": {
"node": ">=12"
}
},
"node_modules/markdownlint-rule-helpers": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz",
"integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w=="
},
"node_modules/mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
},
"node_modules/minimatch": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
"integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/run-con": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.10.tgz",
"integrity": "sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ==",
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~2.0.0",
"minimist": "^1.2.5",
"strip-json-comments": "~3.1.1"
},
"bin": {
"run-con": "cli.js"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
},
"dependencies": {
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"commander": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
"integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
},
"entities": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"get-stdin": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
"integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA=="
},
"glob": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"ignore": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
"integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA=="
},
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"requires": {
"argparse": "^2.0.1"
}
},
"jsonc-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA=="
},
"linkify-it": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
"requires": {
"uc.micro": "^1.0.1"
}
},
"markdown-it": {
"version": "12.3.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
"integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
"requires": {
"argparse": "^2.0.1",
"entities": "~2.1.0",
"linkify-it": "^3.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
}
},
"markdownlint": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz",
"integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==",
"requires": {
"markdown-it": "12.3.2"
}
},
"markdownlint-cli": {
"version": "0.31.1",
"resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.1.tgz",
"integrity": "sha512-keIOMwQn+Ch7MoBwA+TdkyVMuxAeZFEGmIIlvwgV0Z1TGS5MxPnRr29XCLhkNzCHU+uNKGjU+VEjLX+Z9kli6g==",
"requires": {
"commander": "~9.0.0",
"get-stdin": "~9.0.0",
"glob": "~7.2.0",
"ignore": "~5.2.0",
"js-yaml": "^4.1.0",
"jsonc-parser": "~3.0.0",
"markdownlint": "~0.25.1",
"markdownlint-rule-helpers": "~0.16.0",
"minimatch": "~3.0.5",
"run-con": "~1.2.10"
}
},
"markdownlint-rule-helpers": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz",
"integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w=="
},
"mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
},
"minimatch": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
"integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"run-con": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.10.tgz",
"integrity": "sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ==",
"requires": {
"deep-extend": "^0.6.0",
"ini": "~2.0.0",
"minimist": "^1.2.5",
"strip-json-comments": "~3.1.1"
}
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
}
}

13
package.json Normal file
View File

@ -0,0 +1,13 @@
{
"name": "opentelemetry-dotnet-instrumentation",
"version": "0.0.1",
"description": "Application to configure and execute markdownlint",
"scripts": {
"markdownlint": "npx markdownlint . -i node_modules",
"markdownlint-fix": "npx markdownlint . -i node_modules --fix"
},
"license": "Apache-2.0",
"dependencies": {
"markdownlint-cli": "^0.31.1"
}
}

View File

@ -1,15 +1,25 @@
The files here were copied from https://github.com/dotnet/runtime/tree/v5.0.5/src/coreclr/src.
# Info
The files here were copied from <https://github.com/dotnet/runtime/tree/v5.0.5/src/coreclr/src>.
This is to allow using the runtime's Platform Adaptation Layer.
Add back the definition of g_tkCorEncodeToken in cor.h l.2096:
replace
extern const mdToken g_tkCorEncodeToken[];
by
const mdToken g_tkCorEncodeToken[4] = { mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType };
Commented #define statements because there is naming conflicts when compiling with the stdlibc++ 8 (+ C++17)
```cpp
extern const mdToken g_tkCorEncodeToken[];
```
by
```cpp
const mdToken g_tkCorEncodeToken[4] = { mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType };
```
Commented #define statements because there is naming conflicts when compiling
with the stdlibc++ 8 (+ C++17)
in `dotnet-runtime-coreclr\pal\inc\rt\sal.h`
l.2612 // commented because it conflicts with stdlibc++ 8
l.2613 //#define __valid
@ -17,4 +27,4 @@ l.2613 //#define __valid
and
l.2622 // commented because it conflicts with stdlibc++ 8
l.2623 //#define __pre
l.2623 //#define __pre

View File

@ -1,12 +1,18 @@
# Updating idl files
This directory has a variety of .idl files (such as corprof.idl) that need a little special handling when you make changes. Originally when we built on Windows only
the build rules would automatically convert the idls into corresponding .h/.c files and include them in compilations. On non-windows platforms we don't have an equivalent
for midl.exe which did that conversion so we work around the issue by doing:
This directory has a variety of .idl files (such as corprof.idl) that need
a little special handling when you make changes. Originally when we built
on Windows only the build rules would automatically convert the idls into
corresponding .h/.c files and include them in compilations. On non-windows
platforms we don't have an equivalent for midl.exe which did that conversion
so we work around the issue by doing:
- Build on Windows as normal, which will generate files in artifacts\obj\Windows_NT.x64.Debug\src\inc\idls_out\
- Copy any updated headers into src\pal\prebuilt\inc\
- If needed, adjust any of the .cpp files in src\pal\prebuilt\idl\ by hand, using the corresponding artifacts\obj\Windows_NT.x64.Debug\src\inc\idls_out\*_i.c as a guide. Typically
this is just adding MIDL_DEFINE_GUID(...) for any new classes/interfaces that have been added to the idl file.
- If needed, adjust any of the .cpp files in src\pal\prebuilt\idl\ by hand,
using the corresponding
artifacts\obj\Windows_NT.x64.Debug\src\inc\idls_out\*_i.c as a guide.
Typically this is just adding MIDL_DEFINE_GUID(...)
for any new classes/interfaces that have been added to the idl file.
Include these src changes with the remainder of your work when you submit a PR.
Include these src changes with the remainder of your work when you submit a PR.

View File

@ -1,48 +1,55 @@
# OpenTelemetry.AutoInstrumentation.DuckTyping
The duck typing library allows us to get and set data from fields and properties and call methods from an object without having the type definition at compile time. This is done by creating a proxy type to an object instance using a proxy definition at runtime.
The duck typing library allows us to get and set data from fields and properties
and call methods from an object without having the type definition at compile
time. This is done by creating a proxy type to an object instance using a proxy
definition at runtime.
The goal of the library is to have an unify code to access unknown types as fastest and with the minimum allocations as possible.
The goal of the library is to have an unify code to access unknown types
as fastest and with the minimum allocations as possible.
### Example
Given the following scenario, where we want to access the data from an anonymous class instance in another method, a code example to do that would be:
## Example
Given the following scenario, where we want to access the data from an anonymous
class instance in another method, a code example to do that would be:
```csharp
public class Program
{
public static void Main()
{
// We create an anonymous object
var anonymousObject = new { Name = ".NET Core", Version = "3.1" };
Process(anonymousObject);
}
public static void Process(object obj)
{
public static void Main()
{
// We create an anonymous object
var anonymousObject = new { Name = ".NET Core", Version = "3.1" };
Process(anonymousObject);
}
public static void Process(object obj)
{
// First, we create a proxy instance using IDuckAnonymous type
// as a proxy definition and the obj instance as the target.
// Now the proxyInstance implements IDuckAnonymous type and all
// Now the proxyInstance implements IDuckAnonymous type and all
// getters to access the anonymous object internals were generated
// automatically for us.
// We use the `As` extension method to call the duck typing proxy creator.
var proxyInstance = obj.As<IDuckAnonymous>();
var proxyInstance = obj.As<IDuckAnonymous>();
// Here we can access the internal properties
Console.WriteLine($"Name: {proxyInstance.Name}");
Console.WriteLine($"Version: {proxyInstance.Version}");
}
public interface IDuckAnonymous
{
string Name { get; }
string Version { get; }
}
// Here we can access the internal properties
Console.WriteLine($"Name: {proxyInstance.Name}");
Console.WriteLine($"Version: {proxyInstance.Version}");
}
public interface IDuckAnonymous
{
string Name { get; }
string Version { get; }
}
}
```
For this particular case the generated proxy type by the Duck Type library will look like this:
For this particular case the generated proxy type by the Duck Type library will
look like this:
```csharp
public readonly struct IDuckAnonymous___<>f__AnonymousType0`2[System.String,System.String] : IDuckAnonymous, IDuckType
@ -60,7 +67,9 @@ public readonly struct IDuckAnonymous___<>f__AnonymousType0`2[System.String,Syst
```
## Proxy types
Depending on the proxy definition type, the library will create different proxy types as shown in the following table:
Depending on the proxy definition type, the library will create different proxy
types as shown in the following table:
| Proxy Definition Type | Resulting Proxy Type |
|----------------------------|--------------------------------------------------|
@ -68,7 +77,8 @@ Depending on the proxy definition type, the library will create different proxy
| Abstract class | Class inherits and overriding the abstract class |
| Class with virtual members | Class inherits and overriding the virtual class |
Also, all resulting proxy types implements the `IDuckType` interface to expose the target instance and type. The interface has the following definition:
Also, all resulting proxy types implements the `IDuckType` interface to expose
the target instance and type. The interface has the following definition:
```csharp
public interface IDuckType
@ -87,7 +97,8 @@ public interface IDuckType
## Controlling bindings
To control the bindings between the proxy definition and the target type, we can make use of the `DuckAttribute` attribute type defined as:
To control the bindings between the proxy definition and the target type, we can
make use of the `DuckAttribute` attribute type defined as:
```csharp
/// <summary>
@ -148,9 +159,10 @@ public enum DuckKind
}
```
This attribute can be used in `Properties` or `Methods` in the proxy definition and is used by the library to select the members we want to access.
This attribute can be used in `Properties` or `Methods` in the proxy definition
and is used by the library to select the members we want to access.
### Example
### Example with control bindings
The following example shows multiple uses of the `DuckAttribute`:
@ -222,10 +234,12 @@ public interface IMyProxy
}
```
## Accessor modifiers (AM)
In order to support all accessor modifiers for: instance types, parameters and return value types, the Duck Type library applies some `tricks` to avoid the visibility checks. This is done automatically when the library is creating the proxy type. In summary the following logic is applied depending on each case:
In order to support all accessor modifiers for: instance types, parameters
and return value types, the Duck Type library applies some `tricks` to avoid
the visibility checks. This is done automatically when the library is creating
the proxy type. In summary the following logic is applied depending on each case:
| Target Type AM | Target Member Type | Target Member AM | Access Method |
|------------------------------|--------------------|------------------------------|-----------------------------------------------|
@ -244,10 +258,14 @@ In order to support all accessor modifiers for: instance types, parameters and r
## Generics methods
Calling generics methods are supported by the library, but due the use of `DynamicMethod`in some scenarios we can´t define it as a normal generic method (Please note if we know that the target type is Public, then we can declare a normal generic method).
For those scenarios were we can´t use the generic definition, the alternative is to specify the generic parameters to be match in the duck attribute of the proxy definition.
Calling generics methods are supported by the library, but due
the use of `DynamicMethod`in some scenarios we can´t define it as a normal
generic method (Please note if we know that the target type is Public,
then we can declare a normal generic method).
For those scenarios were we can´t use the generic definition, the alternative
is to specify the generic parameters to be match in the duck attribute
of the proxy definition.
### Example with public type
@ -286,7 +304,8 @@ private class PrivateType
}
```
Because the type is non public we have to define each generic arguments we want to use in different calls.
Because the type is non public we have to define each generic arguments we want
to use in different calls.
```csharp
public interface IMyProxy
@ -303,9 +322,11 @@ public interface IMyProxy
## Duck chaining
Duck chaining enables the possibility to interact with properties or methods returning or using non public type parameters to be wrapped with a new duck type proxy, so we can access the internals of those objects.
Duck chaining enables the possibility to interact with properties or methods
returning or using non public type parameters to be wrapped with a new duck type
proxy, so we can access the internals of those objects.
### Example
### Example with chanining
Consider the following types:
@ -338,17 +359,22 @@ public interface IProxyMyHandlerConfiguration
}
```
In this example the non public instance of `MyHandlerConfiguration` when calling the `Configuration` property is going to be wrapped with a `IProxyMyHandlerConfiguration` instance automatically. That allow us to access the internal data of that non public type.
In this example the non public instance of `MyHandlerConfiguration` when calling
the `Configuration` property is going to be wrapped with
a `IProxyMyHandlerConfiguration` instance automatically. That allow us to access
the internal data of that non public type.
## Benchmarks
Several benchmark tests were run for multiple cases to keep track of the time execution and heap allocations of the library, these are the results:
Several benchmark tests were run for multiple cases to keep track of the time
execution and heap allocations of the library, these are the results:
### Fields Getter and Setter
The `proxy` column indicates the target type access modifier.
Tests with `blank` proxy are the direct access of the value through an interface without creating any ducktype proxy.
Tests with `blank` proxy are the direct access of the value through an interface
without creating any ducktype proxy.
``` ini
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.508 (2004/?/20H1)
@ -358,6 +384,7 @@ Intel Core i7-1068NG7 CPU 2.30GHz, 1 CPU, 2 logical and 2 physical cores
Job-LJAVIR : .NET Framework 4.8 (4.8.4220.0), X64 RyuJIT
Job-OHOUFK : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT
```
| Method | Runtime | Categories | proxy | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
|------------------------ |-------------- |-------------- |--------- |---------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:|
| GetPublicStaticField | .NET 4.7.2 | Static Getter | Internal | 3.207 ns | 0.0623 ns | 0.0553 ns | 1.00 | 0.00 | - | - | - | - |
@ -508,7 +535,8 @@ Intel Core i7-1068NG7 CPU 2.30GHz, 1 CPU, 2 logical and 2 physical cores
The `proxy` column indicates the target type access modifier.
Tests with `blank` proxy are the direct access of the value through an interface without creating any ducktype proxy.
Tests with `blank` proxy are the direct access of the value through an interface
without creating any ducktype proxy.
``` ini
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.508 (2004/?/20H1)
@ -518,6 +546,7 @@ Intel Core i7-1068NG7 CPU 2.30GHz, 1 CPU, 2 logical and 2 physical cores
Job-QIOTKF : .NET Framework 4.8 (4.8.4220.0), X64 RyuJIT
Job-FEKUVA : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT
```
| Method | Runtime | Categories | proxy | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
|--------------------------- |-------------- |--------------- |--------- |---------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:|
| GetPublicProperty | .NET 4.7.2 | Getter | | 1.046 ns | 0.0457 ns | 0.0449 ns | 1.00 | 0.00 | - | - | - | - |
@ -698,7 +727,8 @@ Intel Core i7-1068NG7 CPU 2.30GHz, 1 CPU, 2 logical and 2 physical cores
The `proxy` column indicates the target type access modifier.
Tests with `blank` proxy are the direct access of the value through an interface without creating any ducktype proxy.
Tests with `blank` proxy are the direct access of the value through an interface
without creating any ducktype proxy.
``` ini
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.508 (2004/?/20H1)
@ -708,6 +738,7 @@ Intel Core i7-1068NG7 CPU 2.30GHz, 1 CPU, 2 logical and 2 physical cores
Job-CGLGGF : .NET Framework 4.8 (4.8.4220.0), X64 RyuJIT
Job-GEDFFR : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT
```
| Method | Runtime | Categories | proxy | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
|-------------------------- |-------------- |----------------- |--------- |----------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:|
| PublicVoidMethod | .NET 4.7.2 | Void Method | | 1.3457 ns | 0.0441 ns | 0.0391 ns | 1.00 | 0.00 | - | - | - | - |
@ -772,4 +803,3 @@ Intel Core i7-1068NG7 CPU 2.30GHz, 1 CPU, 2 logical and 2 physical cores
| | | | | | | | | | | | | |
| PrivateOutParameterMethod | .NET 4.7.2 | Out-Param Method | Public | 3.7001 ns | 0.0380 ns | 0.0318 ns | 1.00 | 0.00 | - | - | - | - |
| PrivateOutParameterMethod | .NET Core 3.1 | Out-Param Method | Public | 3.9932 ns | 0.0553 ns | 0.0490 ns | 1.08 | 0.01 | - | - | - | - |