Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add grpc instrumentation with experimental feature flag #5130

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

using System.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
#if NET6_0_OR_GREATER
using OpenTelemetry.Internal;
#endif

namespace OpenTelemetry.Instrumentation.AspNetCore;

Expand All @@ -24,6 +28,26 @@ namespace OpenTelemetry.Instrumentation.AspNetCore;
/// </summary>
public class AspNetCoreTraceInstrumentationOptions
{
/// <summary>
/// Initializes a new instance of the <see cref="AspNetCoreTraceInstrumentationOptions"/> class.
/// </summary>
public AspNetCoreTraceInstrumentationOptions()
: this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
{
}

internal AspNetCoreTraceInstrumentationOptions(IConfiguration configuration)
{
Debug.Assert(configuration != null, "configuration was null");

#if NET6_0_OR_GREATER
if (configuration.TryGetBoolValue("OTEL_DOTNET_EXPERIMENTAL_ENABLE_GRPC_INSTRUMENTATION", out var enableGrpcInstrumentation))
utpilla marked this conversation as resolved.
Show resolved Hide resolved
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
{
this.EnableGrpcAspNetCoreSupport = enableGrpcInstrumentation;
}
#endif
}

/// <summary>
/// Gets or sets a filter function that determines whether or not to
/// collect telemetry on a per request basis.
Expand Down Expand Up @@ -77,17 +101,13 @@ public class AspNetCoreTraceInstrumentationOptions
/// </remarks>
public bool RecordException { get; set; }

/*
* Removing for stable release of http instrumentation.
* grpc semantic conventions are not yet stable so this option will not be part of stable package.
#if NET6_0_OR_GREATER
/// <summary>
/// Gets or sets a value indicating whether RPC attributes are added to an Activity when using Grpc.AspNetCore. Default is true.
/// </summary>
/// <remarks>
/// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-spans.md.
/// </remarks>
public bool EnableGrpcAspNetCoreSupport { get; set; } = true;
#endif
*/
#if NET6_0_OR_GREATER
/// <summary>
/// Gets or sets a value indicating whether RPC attributes are added to an Activity when using Grpc.AspNetCore. Default is true.
/// </summary>
/// <remarks>
/// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-spans.md.
/// </remarks>
internal bool EnableGrpcAspNetCoreSupport { get; set; }
#endif
}
12 changes: 12 additions & 0 deletions src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

## Unreleased

* Added support for gRPC instrumentation under an experimental feature flag
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
`OTEL_DOTNET_EXPERIMENTAL_ENABLE_GRPC_INSTRUMENTATION`. Note that the support
was removed in `1.6.0-rc.1` version of the package and versions released
before `1.6.0-rc.1` had gRPC instrumentation enabled by default. From now
onwards, gRPC instrumentation will only be enabled when
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
`OTEL_DOTNET_EXPERIMENTAL_ENABLE_GRPC_INSTRUMENTATION` is set to `True`. The
change is introduced in order to support stable release of `http`
instrumentation. Semantic conventions for RPC is still
[experimental](https://github.com/open-telemetry/semantic-conventions/tree/main/docs/rpc)
and hence the package will only support it as an experimental feature.
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
([#5130](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5130))

## 1.6.0-rc.1

Released 2023-Dec-01
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,13 @@ public void OnStopActivity(Activity activity, object payload)
#endif

activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode));
/*
#if !NETSTANDARD2_0

if (this.options.EnableGrpcAspNetCoreSupport && TryGetGrpcMethod(activity, out var grpcMethod))
{
this.AddGrpcAttributes(activity, grpcMethod, context);
}
*/

#if !NETSTANDARD2_0
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
if (this.options.EnableGrpcAspNetCoreSupport && TryGetGrpcMethod(activity, out var grpcMethod))
{
this.AddGrpcAttributes(activity, grpcMethod, context);
}
#endif
if (activity.Status == ActivityStatusCode.Unset)
{
activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(activity.Kind, response.StatusCode));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="$(RepoRoot)\src\Shared\EnvironmentVariables\*.cs" Link="Includes\EnvironmentVariables\%(Filename).cs" Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.GrpcNetClient\GrpcTagHelper.cs" Link="Includes\GrpcTagHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.GrpcNetClient\StatusCanonicalCode.cs" Link="Includes\StatusCanonicalCode.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\Shared\RequestMethodHelper.cs" Link="Includes\RequestMethodHelper.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Shims\NullableAttributes.cs" Link="Includes\Shims\NullableAttributes.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Options\*.cs" Link="Includes\Options\%(Filename).cs" />
</ItemGroup>

<ItemGroup Condition="'$(RunningDotNetPack)' != 'true'">
Expand All @@ -32,6 +34,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" />
<PackageReference Include="Microsoft.Extensions.Options" />
<PackageReference Include="Microsoft.Extensions.Configuration" />
vishweshbankwar marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ public static TracerProviderBuilder AddAspNetCoreInstrumentation(
{
services.Configure(name, configureAspNetCoreTraceInstrumentationOptions);
}

#if !NETSTANDARD2_0
services.RegisterOptionsFactory(configuration => new AspNetCoreTraceInstrumentationOptions(configuration));
#endif
});

if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder)
Expand Down
85 changes: 43 additions & 42 deletions test/OpenTelemetry.Instrumentation.Grpc.Tests/GrpcTests.server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,20 @@

#if NET6_0_OR_GREATER
using System.Diagnostics;
using System.Net;
using Greet;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Instrumentation.Grpc.Services.Tests;
using OpenTelemetry.Instrumentation.GrpcNetClient;
using OpenTelemetry.Trace;
using Xunit;
using static OpenTelemetry.Internal.HttpSemanticConventionHelper;
using Status = OpenTelemetry.Trace.Status;

namespace OpenTelemetry.Instrumentation.Grpc.Tests;

Expand All @@ -35,34 +46,26 @@ public GrpcTests()
this.server = new GrpcServer<GreeterService>();
}

/*
[Theory]
[InlineData(null)]
[InlineData(true)]
[InlineData(false)]
public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(bool? enableGrpcAspNetCoreSupport)
[InlineData("true")]
[InlineData("false")]
[InlineData("True")]
[InlineData("False")]
public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(string enableGrpcAspNetCoreSupport)
{
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string> { [SemanticConventionOptInKeyName] = "http" })
.AddInMemoryCollection(new Dictionary<string, string>
{
[SemanticConventionOptInKeyName] = "http",
["OTEL_DOTNET_EXPERIMENTAL_ENABLE_GRPC_INSTRUMENTATION"] = enableGrpcAspNetCoreSupport,
})
.Build();

var exportedItems = new List<Activity>();
var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder()
.ConfigureServices(services => services.AddSingleton<IConfiguration>(configuration));

if (enableGrpcAspNetCoreSupport.HasValue)
{
tracerProviderBuilder.AddAspNetCoreInstrumentation(options =>
{
options.EnableGrpcAspNetCoreSupport = enableGrpcAspNetCoreSupport.Value;
});
}
else
{
tracerProviderBuilder.AddAspNetCoreInstrumentation();
}

using var tracerProvider = tracerProviderBuilder
using var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder()
.ConfigureServices(services => services.AddSingleton<IConfiguration>(configuration))
.AddAspNetCoreInstrumentation()
.AddInMemoryExporter(exportedItems)
.Build();

Expand All @@ -80,7 +83,7 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(bool? enableGrpcA

Assert.Equal(ActivityKind.Server, activity.Kind);

if (!enableGrpcAspNetCoreSupport.HasValue || enableGrpcAspNetCoreSupport.Value)
if (enableGrpcAspNetCoreSupport != null && enableGrpcAspNetCoreSupport.Equals("true", StringComparison.OrdinalIgnoreCase))
{
Assert.Equal("grpc", activity.GetTagValue(SemanticConventions.AttributeRpcSystem));
Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService));
Expand Down Expand Up @@ -113,30 +116,28 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(bool? enableGrpcA
[Theory(Skip = "Skipping for .NET 6 and higher due to bug #3023")]
#endif
[InlineData(null)]
[InlineData(true)]
[InlineData(false)]
public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewActivity(bool? enableGrpcAspNetCoreSupport)
[InlineData("true")]
[InlineData("false")]
[InlineData("True")]
[InlineData("False")]
public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewActivity(string enableGrpcAspNetCoreSupport)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this PR but these tests should be moved to OpenTelemetry.Instrumentation.AspNetCore.Tests.

{
try
{
// B3Propagator along with the headers passed to the client.SayHello ensure that the instrumentation creates a sibling activity
Sdk.SetDefaultTextMapPropagator(new Extensions.Propagators.B3Propagator());
var exportedItems = new List<Activity>();
var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder();

if (enableGrpcAspNetCoreSupport.HasValue)
{
tracerProviderBuilder.AddAspNetCoreInstrumentation(options =>
{
options.EnableGrpcAspNetCoreSupport = enableGrpcAspNetCoreSupport.Value;
});
}
else
{
tracerProviderBuilder.AddAspNetCoreInstrumentation();
}

using var tracerProvider = tracerProviderBuilder
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
[SemanticConventionOptInKeyName] = "http",
["OTEL_DOTNET_EXPERIMENTAL_ENABLE_GRPC_INSTRUMENTATION"] = enableGrpcAspNetCoreSupport,
})
.Build();

using var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder()
.ConfigureServices(services => services.AddSingleton<IConfiguration>(configuration))
.AddAspNetCoreInstrumentation()
.AddInMemoryExporter(exportedItems)
.Build();

Expand All @@ -160,7 +161,7 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewAc

Assert.Equal(ActivityKind.Server, activity.Kind);

if (!enableGrpcAspNetCoreSupport.HasValue || enableGrpcAspNetCoreSupport.Value)
if (enableGrpcAspNetCoreSupport != null && enableGrpcAspNetCoreSupport.Equals("true", StringComparison.OrdinalIgnoreCase))
{
Assert.Equal("grpc", activity.GetTagValue(SemanticConventions.AttributeRpcSystem));
Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService));
Expand Down Expand Up @@ -197,7 +198,7 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewAc
}));
}
}
*/

public void Dispose()
{
this.server.Dispose();
Expand Down