Skip to content

Commit

Permalink
[WCF] Fix WCF instrumentation initialization (#3650)
Browse files Browse the repository at this point in the history
  • Loading branch information
lachmatt authored Sep 20, 2024
1 parent 1f41c78 commit 52d169a
Show file tree
Hide file tree
Showing 27 changed files with 583 additions and 150 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h

### Fixed

- Initialize WCF instrumentation only when necessary ([#3650](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/pull/3650))

## [1.7.0](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/tag/v1.7.0)

- [Core components](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#core-components):
Expand Down
21 changes: 20 additions & 1 deletion OpenTelemetry.AutoInstrumentation.sln
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApplication.OracleMda.C
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started-dotnet-monitor-logs", "next-gen\docs\getting-started-dotnet-monitor-logs\getting-started-dotnet-monitor-logs.csproj", "{959764E7-5A0C-4511-8004-48DE6B10F499}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication.RabbitMq", "test\test-applications\integrations\TestApplication.RabbitMq\TestApplication.RabbitMq.csproj", "{91D883EC-069E-46BC-B6F7-67C94299851E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApplication.RabbitMq", "test\test-applications\integrations\TestApplication.RabbitMq\TestApplication.RabbitMq.csproj", "{91D883EC-069E-46BC-B6F7-67C94299851E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication.Owin.IIS.NetFramework", "test\test-applications\integrations\TestApplication.Owin.IIS.NetFramework\TestApplication.Owin.IIS.NetFramework.csproj", "{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -1477,6 +1479,22 @@ Global
{91D883EC-069E-46BC-B6F7-67C94299851E}.Release|x64.Build.0 = Release|x64
{91D883EC-069E-46BC-B6F7-67C94299851E}.Release|x86.ActiveCfg = Release|x86
{91D883EC-069E-46BC-B6F7-67C94299851E}.Release|x86.Build.0 = Release|x86
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|ARM64.Build.0 = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|x64.ActiveCfg = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|x64.Build.0 = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|x86.ActiveCfg = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Debug|x86.Build.0 = Debug|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|Any CPU.Build.0 = Release|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|ARM64.ActiveCfg = Release|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|ARM64.Build.0 = Release|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|x64.ActiveCfg = Release|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|x64.Build.0 = Release|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|x86.ActiveCfg = Release|Any CPU
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1564,6 +1582,7 @@ Global
{21A915DF-8B9E-4CE8-84DA-1057CDCE117E} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
{959764E7-5A0C-4511-8004-48DE6B10F499} = {3F051815-8E0D-4356-BC36-55CA642DDF18}
{91D883EC-069E-46BC-B6F7-67C94299851E} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
{AA3E0C5C-A4E2-46AB-BD18-2D30D3ABF692} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
Expand Down
3 changes: 3 additions & 0 deletions build/Build.Steps.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ partial class Build
var wcfProject = Solution.GetProjectByName(Projects.Tests.Applications.WcfIis);
BuildDockerImage(wcfProject);
var owinProject = Solution.GetProjectByName(Projects.Tests.Applications.OwinIis);
BuildDockerImage(owinProject);
});

void BuildDockerImage(Project project)
Expand Down
3 changes: 2 additions & 1 deletion build/Build.Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ DotNetRestoreSettings Restore(DotNetRestoreSettings s) =>
// Projects using `packages.config` can't be restored via "dotnet restore", use a NuGet Task to restore these projects.
var legacyRestoreProjects = Solution.GetNativeProjects()
.Concat(Solution.GetProjectByName(Projects.Tests.Applications.AspNet))
.Concat(Solution.GetProjectByName(Projects.Tests.Applications.WcfIis));
.Concat(Solution.GetProjectByName(Projects.Tests.Applications.WcfIis))
.Concat(Solution.GetProjectByName(Projects.Tests.Applications.OwinIis));
RestoreLegacyNuGetPackagesConfig(legacyRestoreProjects);
}
Expand Down
3 changes: 2 additions & 1 deletion build/Projects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ public static class Tests
public static class Applications
{
public const string AspNet = "TestApplication.AspNet.NetFramework";
public const string ContinuousProfilerNativeDep = "TestApplication.ContinuousProfiler.NativeDep";
public const string OwinIis = "TestApplication.Owin.IIS.NetFramework";
public const string WcfIis = "TestApplication.Wcf.Server.IIS.NetFramework";
public const string WcfServer = "TestApplication.Wcf.Server.NetFramework";
public const string ContinuousProfilerNativeDep = "TestApplication.ContinuousProfiler.NativeDep";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,6 @@ public static void AddGraphQL(LazyInstrumentationLoader lazyInstrumentationLoade
}
#endif

[MethodImpl(MethodImplOptions.NoInlining)]
public static void AddWcf(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager)
{
lazyInstrumentationLoader.Add(new WcfInitializer(pluginManager));
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void AddQuartz(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,16 @@ public static TracerProviderBuilder UseEnvironmentVariables(
TracerSettings settings,
PluginManager pluginManager)
{
// ensure WcfInitializer is added only once,
// ensure WCF instrumentation activity source is added only once,
// it is needed when either WcfClient or WcfService instrumentations are enabled
// to initialize WcfInstrumentationOptions
var wcfInstrumentationAdded = false;
foreach (var enabledInstrumentation in settings.EnabledInstrumentations)
{
_ = enabledInstrumentation switch
{
#if NETFRAMEWORK
TracerInstrumentation.AspNet => Wrappers.AddAspNetInstrumentation(builder, pluginManager, lazyInstrumentationLoader, settings),
TracerInstrumentation.WcfService => AddWcfIfNeeded(builder, pluginManager, lazyInstrumentationLoader, ref wcfInstrumentationAdded),
TracerInstrumentation.WcfService => AddWcfIfNeeded(builder, ref wcfInstrumentationAdded),
#endif
TracerInstrumentation.GrpcNetClient => Wrappers.AddGrpcClientInstrumentation(builder, pluginManager, lazyInstrumentationLoader, settings),
TracerInstrumentation.HttpClient => Wrappers.AddHttpClientInstrumentation(builder, pluginManager, lazyInstrumentationLoader, settings),
Expand All @@ -39,7 +38,7 @@ public static TracerProviderBuilder UseEnvironmentVariables(
TracerInstrumentation.MongoDB => builder.AddSource("MongoDB.Driver.Core.Extensions.DiagnosticSources"),
TracerInstrumentation.MySqlConnector => builder.AddSource("MySqlConnector"),
TracerInstrumentation.Azure => Wrappers.AddAzureInstrumentation(builder),
TracerInstrumentation.WcfClient => AddWcfIfNeeded(builder, pluginManager, lazyInstrumentationLoader, ref wcfInstrumentationAdded),
TracerInstrumentation.WcfClient => AddWcfIfNeeded(builder, ref wcfInstrumentationAdded),
TracerInstrumentation.OracleMda => Wrappers.AddOracleMdaInstrumentation(builder, lazyInstrumentationLoader, settings),
#if NET6_0_OR_GREATER
TracerInstrumentation.AspNetCore => Wrappers.AddAspNetCoreInstrumentation(builder, pluginManager, lazyInstrumentationLoader, settings),
Expand Down Expand Up @@ -74,16 +73,14 @@ public static TracerProviderBuilder UseEnvironmentVariables(

private static TracerProviderBuilder AddWcfIfNeeded(
TracerProviderBuilder tracerProviderBuilder,
PluginManager pluginManager,
LazyInstrumentationLoader lazyInstrumentationLoader,
ref bool wcfInstrumentationAdded)
{
if (wcfInstrumentationAdded)
{
return tracerProviderBuilder;
}

Wrappers.AddWcfInstrumentation(tracerProviderBuilder, pluginManager, lazyInstrumentationLoader);
tracerProviderBuilder.AddSource("OpenTelemetry.Instrumentation.Wcf");
wcfInstrumentationAdded = true;

return tracerProviderBuilder;
Expand Down Expand Up @@ -113,14 +110,6 @@ private static class Wrappers
{
// Instrumentations

[MethodImpl(MethodImplOptions.NoInlining)]
public static TracerProviderBuilder AddWcfInstrumentation(TracerProviderBuilder builder, PluginManager pluginManager, LazyInstrumentationLoader lazyInstrumentationLoader)
{
DelayedInitialization.Traces.AddWcf(lazyInstrumentationLoader, pluginManager);

return builder.AddSource("OpenTelemetry.Instrumentation.Wcf");
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static TracerProviderBuilder AddHttpClientInstrumentation(TracerProviderBuilder builder, PluginManager pluginManager, LazyInstrumentationLoader lazyInstrumentationLoader, TracerSettings tracerSettings)
{
Expand Down
20 changes: 0 additions & 20 deletions src/OpenTelemetry.AutoInstrumentation/Instrumentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,6 @@ private static void AddLazilyLoadedMetricInstrumentations(LazyInstrumentationLoa

private static void AddLazilyLoadedTraceInstrumentations(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings)
{
// ensure WcfInitializer is added only once,
// it is needed when either WcfClient or WcfService instrumentations are enabled
// to initialize WcfInstrumentationOptions
var wcfInstrumentationAdded = false;
foreach (var instrumentation in tracerSettings.EnabledInstrumentations)
{
switch (instrumentation)
Expand All @@ -324,7 +320,6 @@ private static void AddLazilyLoadedTraceInstrumentations(LazyInstrumentationLoad
DelayedInitialization.Traces.AddAspNet(lazyInstrumentationLoader, pluginManager, tracerSettings);
break;
case TracerInstrumentation.WcfService:
AddWcfIfNeeded(lazyInstrumentationLoader, pluginManager, ref wcfInstrumentationAdded);
break;
#endif
case TracerInstrumentation.HttpClient:
Expand All @@ -340,7 +335,6 @@ private static void AddLazilyLoadedTraceInstrumentations(LazyInstrumentationLoad
DelayedInitialization.Traces.AddQuartz(lazyInstrumentationLoader, pluginManager);
break;
case TracerInstrumentation.WcfClient:
AddWcfIfNeeded(lazyInstrumentationLoader, pluginManager, ref wcfInstrumentationAdded);
break;
#if NET6_0_OR_GREATER
case TracerInstrumentation.AspNetCore:
Expand Down Expand Up @@ -391,20 +385,6 @@ private static void AddLazilyLoadedTraceInstrumentations(LazyInstrumentationLoad
}
}

private static void AddWcfIfNeeded(
LazyInstrumentationLoader lazyInstrumentationLoader,
PluginManager pluginManager,
ref bool wcfInstrumentationAdded)
{
if (wcfInstrumentationAdded)
{
return;
}

DelayedInitialization.Traces.AddWcf(lazyInstrumentationLoader, pluginManager);
wcfInstrumentationAdded = true;
}

private static void OnExit(object? sender, EventArgs e)
{
if (Interlocked.Exchange(ref _isExiting, value: 1) != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public static class HttpModuleIntegration
{
private static int _initialized;

internal static bool IsInitialized => Interlocked.CompareExchange(ref _initialized, 0, 0) != default;

/// <summary>
/// OnMethodBegin callback
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ internal interface IEndpoint

public static void Initialize(IChannelFactory channelFactory)
{
WcfInstrumentationInitializer.TryInitializeOptions();

var behaviors = channelFactory.Endpoint.Behaviors;
if (!behaviors.Contains(typeof(TelemetryEndpointBehavior)))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ internal interface IDescription

public static void Initialize(IServiceHostBase serviceHost)
{
WcfInstrumentationInitializer.TryInitializeOptions();
WcfInstrumentationInitializer.TryInitializeParentSpanCorrector();

var behaviors = serviceHost.Description.Behaviors;
if (!behaviors.Contains(typeof(TelemetryServiceBehavior)))
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#if NETFRAMEWORK
using System.Reflection;
using OpenTelemetry.AutoInstrumentation.Instrumentations.AspNet;
#endif
using OpenTelemetry.Instrumentation.Wcf;

namespace OpenTelemetry.AutoInstrumentation.Instrumentations.Wcf;

internal static class WcfInstrumentationInitializer
{
private static int _instrumentationOptionsInitialized;
#if NETFRAMEWORK
private static int _aspNetParentSpanCorrectorInitialized;
#endif

public static void TryInitializeOptions()
{
if (Interlocked.Exchange(ref _instrumentationOptionsInitialized, value: 1) != default)
{
return;
}

var options = new WcfInstrumentationOptions();

Instrumentation.PluginManager?.ConfigureTracesOptions(options);

var instrumentationType =
Type.GetType(
"OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationActivitySource, OpenTelemetry.Instrumentation.Wcf");

instrumentationType?.GetProperty("Options")?.SetValue(null, options);
}

#if NETFRAMEWORK
public static void TryInitializeParentSpanCorrector()
{
if (Interlocked.Exchange(ref _aspNetParentSpanCorrectorInitialized, value: 1) != default)
{
return;
}

if (HttpModuleIntegration.IsInitialized)
{
var aspNetParentSpanCorrectorType = Type.GetType("OpenTelemetry.Instrumentation.Wcf.Implementation.AspNetParentSpanCorrector, OpenTelemetry.Instrumentation.Wcf");
var methodInfo = aspNetParentSpanCorrectorType?.GetMethod("Register", BindingFlags.Static | BindingFlags.Public);
methodInfo?.Invoke(null, null);
}
}
#endif
}

This file was deleted.

Loading

0 comments on commit 52d169a

Please sign in to comment.