ASP.NET - auto registration for HttpModule (#2569)
Co-authored-by: Mateusz Łach <mateusza@splunk.com>
This commit is contained in:
parent
d54f7f548b
commit
23aea72241
|
|
@ -15,6 +15,9 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h
|
|||
|
||||
### Changed
|
||||
|
||||
- ASP.NET instrumentation no longer requires manual modification
|
||||
of config files to include `TelemetryHttpModule`.
|
||||
|
||||
### Deprecated
|
||||
|
||||
### Removed
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ partial class Build
|
|||
.SetProperty("PublishProfile", aspNetProject.Directory / "Properties" / "PublishProfiles" / $"FolderProfile.{BuildConfiguration}.pubxml")
|
||||
.SetTargetPath(aspNetProject));
|
||||
|
||||
var localCopyTracerHome = aspNetProject.Directory / "bin" / "tracer-home";
|
||||
CopyDirectoryRecursively(TracerHomeDirectory, localCopyTracerHome);
|
||||
|
||||
DockerBuild(x => x
|
||||
.SetPath(".")
|
||||
.SetBuildArg($"configuration={BuildConfiguration}", $"windowscontainer_version={WindowsContainerVersion}")
|
||||
|
|
@ -121,6 +124,8 @@ partial class Build
|
|||
.SetTag(Path.GetFileNameWithoutExtension(aspNetProject).Replace(".", "-").ToLowerInvariant())
|
||||
.SetProcessWorkingDirectory(aspNetProject.Directory)
|
||||
);
|
||||
|
||||
Directory.Delete(localCopyTracerHome, true);
|
||||
});
|
||||
|
||||
Target GenerateNetFxTransientDependencies => _ => _
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ due to lack of stable semantic convention.
|
|||
|
||||
| ID | Instrumented library | Supported versions | Instrumentation type | Status |
|
||||
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `ASPNET` | ASP.NET (.NET Framework) MVC / WebApi \[1\] **Not supported on .NET** | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `ASPNET` | ASP.NET (.NET Framework) MVC / WebApi \[1\] **Not supported on .NET** | * | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `ASPNETCORE` | ASP.NET Core **Not supported on .NET Framework** | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `ELASTICSEARCH` | [Elastic.Clients.Elasticsearch](https://www.nuget.org/packages/Elastic.Clients.Elasticsearch) | ≥8.0.0 | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `ENTITYFRAMEWORKCORE` | [Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/) **Not supported on .NET Framework** | ≥6.0.12 | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
|
|
@ -158,7 +158,7 @@ due to lack of stable semantic convention.
|
|||
|
||||
| ID | Instrumented library | Documentation | Supported versions | Instrumentation type | Status |
|
||||
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `ASPNET` | ASP.NET Framework \[1\] **Not supported on .NET** | [ASP.NET metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `ASPNET` | ASP.NET Framework \[1\] **Not supported on .NET** | [ASP.NET metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md#list-of-metrics-produced) | * | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `ASPNETCORE` | ASP.NET Core \[2\] **Not supported on .NET Framework** | [ASP.NET Core metrics](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `HTTPCLIENT` | [System.Net.Http.HttpClient](https://docs.microsoft.com/dotnet/api/system.net.http.httpclient) and [System.Net.HttpWebRequest](https://docs.microsoft.com/dotnet/api/system.net.httpwebrequest) | [HttpClient metrics](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.Http#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
| `NETRUNTIME` | [OpenTelemetry.Instrumentation.Runtime](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) | [Process metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.Process#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) |
|
||||
|
|
|
|||
|
|
@ -19,71 +19,6 @@ Register-OpenTelemetryForIIS
|
|||
> **Warning**
|
||||
> `Register-OpenTelemetryForIIS` performs IIS restart.
|
||||
|
||||
### Add TelemetryHttpModule ASP.NET HTTP module
|
||||
|
||||
> **Note**
|
||||
> This is NOT required for ASP.NET Core deployments.
|
||||
|
||||
This step is necessary only for ASP.NET (.NET Framework).
|
||||
|
||||
> **Note**
|
||||
> There are three distinct options.
|
||||
|
||||
Add `OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule`
|
||||
by modifying and extending `web.config` (first two options)
|
||||
or `applicationHost.config` (third option).
|
||||
|
||||
```xml
|
||||
<system.web>
|
||||
<httpModules>
|
||||
<add name="TelemetryHttpModule" type="OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule" />
|
||||
</httpModules>
|
||||
</system.web>
|
||||
```
|
||||
|
||||
> **Warning**
|
||||
> After applying above changes you might experience following error as this configuration
|
||||
> requires IIS classic mode.
|
||||
> In order to fix it you can switch to classic mode or use other options. .
|
||||
|
||||
```xml
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false" />
|
||||
<modules>
|
||||
<remove name="TelemetryHttpModule" />
|
||||
<add name="TelemetryHttpModule" type="OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule" preCondition="managedHandler" />
|
||||
</modules>
|
||||
</system.webServer>
|
||||
```
|
||||
|
||||
> **Note** `applicationHost.config` is located in `%SystemDrive%\Windows\system32\inetsrv\config`.
|
||||
> Below is an example where you can add the module
|
||||
> to set it for all ASP.NET application running in Integrated Pipeline Mode:
|
||||
|
||||
```xml
|
||||
<location path="" overrideMode="Allow">
|
||||
<system.webServer>
|
||||
<modules>
|
||||
<add name="TelemetryHttpModule" type="OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule" preCondition="managedHandler" />
|
||||
</modules>
|
||||
</system.webServer>
|
||||
</location>
|
||||
```
|
||||
|
||||
> **Note** After applying above changes you can check whether `opentelemetry modules`
|
||||
> are loaded by using `appcmd` command which can be found under `%SystemDrive%\Windows\system32\inetsrv`.
|
||||
> Following example shows invocation for `WebDemo\` application:
|
||||
|
||||
```terminal
|
||||
appcmd list modules /app.name:"WebDemo/"
|
||||
```
|
||||
|
||||
and correct result:
|
||||
|
||||
```terminal
|
||||
MODULE "TelemetryHttpModule" ( type:OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, preCondition:managedHandler )
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
> **Note**
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB |
|
|
@ -241,8 +241,7 @@ HRESULT STDMETHODCALLTYPE CorProfiler::Initialize(IUnknown* cor_profiler_info_un
|
|||
opcodes_names.push_back("->"); // CEE_SWITCH_ARG
|
||||
}
|
||||
|
||||
//
|
||||
managed_profiler_assembly_reference = AssemblyReference::GetFromCache(managed_profiler_full_assembly_version);
|
||||
managed_profiler_assembly_reference = AssemblyReference::GetFromCache(GetBytecodeInstrumentationAssembly());
|
||||
|
||||
const auto currentModuleFileName = GetCurrentModuleFileName();
|
||||
if (currentModuleFileName == EmptyWStr)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType
|
|||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.Instance.get -> object!
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.ToString() -> string!
|
||||
OpenTelemetry.AutoInstrumentation.DuckTyping.IDuckType.Type.get -> System.Type!
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.AspNet.HttpModuleIntegration
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ExecuteAsyncIntegration
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.MongoDB.MongoClientIntegration
|
||||
OpenTelemetry.AutoInstrumentation.Instrumentations.NServiceBus.EndpointConfigurationIntegration
|
||||
|
|
|
|||
|
|
@ -55,6 +55,14 @@ internal static class InstrumentationDefinitions
|
|||
var tracerSettings = Instrumentation.TracerSettings.Value;
|
||||
if (tracerSettings.TracesEnabled)
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
// AspNet
|
||||
if (tracerSettings.EnabledInstrumentations.Contains(TracerInstrumentation.AspNet))
|
||||
{
|
||||
nativeCallTargetDefinitions.Add(new("System.Web", "System.Web.Compilation.BuildManager", "InvokePreStartInitMethodsCore", new[] { "System.Void", "System.Collections.Generic.ICollection`1[System.Reflection.MethodInfo]", "System.Func`1[System.IDisposable]" }, 4, 0, 0, 4, 65535, 65535, AssemblyFullName, "OpenTelemetry.AutoInstrumentation.Instrumentations.AspNet.HttpModuleIntegration"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tracerSettings.EnabledInstrumentations.Contains(TracerInstrumentation.GraphQL))
|
||||
{
|
||||
nativeCallTargetDefinitions.Add(new("GraphQL", "GraphQL.Execution.ExecutionStrategy", "ExecuteAsync", new[] { "System.Threading.Tasks.Task`1<GraphQL.ExecutionResult>", "GraphQL.Execution.ExecutionContext" }, 2, 3, 0, 2, 65535, 65535, AssemblyFullName, "OpenTelemetry.AutoInstrumentation.Instrumentations.GraphQL.ExecuteAsyncIntegration"));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
// <copyright file="HttpModuleIntegration.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
#if NETFRAMEWORK
|
||||
using System.Web;
|
||||
using OpenTelemetry.AutoInstrumentation.CallTarget;
|
||||
using OpenTelemetry.Instrumentation.AspNet;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.Instrumentations.AspNet;
|
||||
|
||||
/// <summary>
|
||||
/// System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore calltarget instrumentation
|
||||
/// </summary>
|
||||
[InstrumentMethod(
|
||||
"System.Web",
|
||||
"System.Web.Compilation.BuildManager",
|
||||
"InvokePreStartInitMethodsCore",
|
||||
ClrNames.Void,
|
||||
new[] { "System.Collections.Generic.ICollection`1[System.Reflection.MethodInfo]", "System.Func`1[System.IDisposable]" },
|
||||
"4.0.0",
|
||||
"4.*.*",
|
||||
"AspNet",
|
||||
InstrumentationType.Trace)]
|
||||
public static class HttpModuleIntegration
|
||||
{
|
||||
private static int _initialized;
|
||||
|
||||
/// <summary>
|
||||
/// OnMethodBegin callback
|
||||
/// </summary>
|
||||
/// <typeparam name="TTarget">Type of the target</typeparam>
|
||||
/// <typeparam name="TCollection">Type of the collection</typeparam>
|
||||
/// <typeparam name="TFunc">Type of the </typeparam>
|
||||
/// <param name="instance">Instance value, aka `this` of the instrumented method. This method is static so this parameter will always be null</param>
|
||||
/// <param name="methods">The methods to be invoked</param>
|
||||
/// <param name="setHostingEnvironmentCultures">The function to set the environment culture</param>
|
||||
/// <returns>Calltarget state value</returns>
|
||||
internal static CallTargetState OnMethodBegin<TTarget, TCollection, TFunc>(TTarget instance, TCollection methods, TFunc setHostingEnvironmentCultures)
|
||||
{
|
||||
if (Interlocked.Exchange(ref _initialized, 1) != default)
|
||||
{
|
||||
return CallTargetState.GetDefault();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
HttpApplication.RegisterModule(typeof(TelemetryHttpModule));
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Exception while registering telemetry http module
|
||||
// nothing we can do with this
|
||||
}
|
||||
|
||||
return CallTargetState.GetDefault();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -4,6 +4,11 @@ ARG windowscontainer_version=ltsc2022
|
|||
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-${windowscontainer_version}
|
||||
ARG configuration=Debug
|
||||
ARG platform=x64
|
||||
WORKDIR C:\opentelemetry
|
||||
COPY bin/tracer-home .
|
||||
WORKDIR C:\init
|
||||
COPY docker-init.ps1 .
|
||||
RUN [ "powershell", "-c", ".\\docker-init.ps1" ]
|
||||
ENV COR_ENABLE_PROFILING=1 `
|
||||
COR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318} `
|
||||
COR_PROFILER_PATH=C:\opentelemetry\win-${platform}\OpenTelemetry.AutoInstrumentation.Native.dll `
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@
|
|||
<Folder Include="App_Data\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="docker-init.ps1" />
|
||||
<None Include="Dockerfile" />
|
||||
<None Include=".dockerignore">
|
||||
<DependentUpon>Dockerfile</DependentUpon>
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@
|
|||
</customErrors>
|
||||
<compilation debug="true" targetFramework="4.6.2" />
|
||||
<httpRuntime targetFramework="4.6.2" />
|
||||
<httpModules>
|
||||
<add name="TelemetryHttpModule" type="OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule" />
|
||||
</httpModules>
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<httpErrors errorMode="Detailed" />
|
||||
|
|
@ -74,9 +71,5 @@
|
|||
</system.codedom>
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false" />
|
||||
<modules>
|
||||
<remove name="TelemetryHttpModule" />
|
||||
<add name="TelemetryHttpModule" type="OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule" preCondition="managedHandler" />
|
||||
</modules>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
function Test-AssemblyNotForGAC([string] $Name) {
|
||||
switch ($Name) {
|
||||
"netstandard.dll" { return $true }
|
||||
"grpc_csharp_ext.x64.dll" { return $true }
|
||||
"grpc_csharp_ext.x86.dll" { return $true }
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
[System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") | Out-Null
|
||||
$publish = New-Object System.EnterpriseServices.Internal.Publish
|
||||
$dlls = Get-ChildItem -Path C:\opentelemetry\netfx\ -Filter *.dll -File
|
||||
for ($i = 0; $i -lt $dlls.Count; $i++) {
|
||||
if (Test-AssemblyNotForGAC $dlls[$i].Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
$publish.GacInstall($dlls[$i].FullName)
|
||||
}
|
||||
Write-Progress -Activity "Registering .NET Framework dlls in GAC" -Status "Ready" -Completed
|
||||
Loading…
Reference in New Issue