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

[Instrumentation.GrpcNetClient] Support only stable HTTP semantic convention #5259

Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -9,6 +9,11 @@
[issue](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092)
for details and workaround.
([#5077](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5077))
* Removed support for `http` and `http/dup` values for`OTEL_SEMCONV_STABILITY_OPT_IN`
Kielek marked this conversation as resolved.
Show resolved Hide resolved
Kielek marked this conversation as resolved.
Show resolved Hide resolved
environment variable. The library will now emit only the
[stable](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http)
HTTP semantic conventions.
Kielek marked this conversation as resolved.
Show resolved Hide resolved
([#5259](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5259))

## 1.6.0-beta.3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;
using Microsoft.Extensions.Configuration;
using static OpenTelemetry.Internal.HttpSemanticConventionHelper;

namespace OpenTelemetry.Instrumentation.GrpcNetClient;

Expand All @@ -12,23 +10,6 @@ namespace OpenTelemetry.Instrumentation.GrpcNetClient;
/// </summary>
public class GrpcClientInstrumentationOptions
{
internal readonly HttpSemanticConvention HttpSemanticConvention;

/// <summary>
/// Initializes a new instance of the <see cref="GrpcClientInstrumentationOptions"/> class.
/// </summary>
public GrpcClientInstrumentationOptions()
: this(new ConfigurationBuilder().AddEnvironmentVariables().Build())
{
}

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

this.HttpSemanticConvention = GetSemanticConventionOptIn(configuration);
}

/// <summary>
/// Gets or sets a value indicating whether down stream instrumentation is suppressed (disabled).
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Instrumentation.Http;
using OpenTelemetry.Trace;
using static OpenTelemetry.Internal.HttpSemanticConventionHelper;

namespace OpenTelemetry.Instrumentation.GrpcNetClient.Implementation;

Expand All @@ -27,17 +26,11 @@ internal sealed class GrpcClientDiagnosticListener : ListenerHandler
private static readonly PropertyFetcher<HttpResponseMessage> StopResponseFetcher = new("Response");

private readonly GrpcClientInstrumentationOptions options;
private readonly bool emitOldAttributes;
private readonly bool emitNewAttributes;

public GrpcClientDiagnosticListener(GrpcClientInstrumentationOptions options)
: base("Grpc.Net.Client")
{
this.options = options;

this.emitOldAttributes = this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old);

this.emitNewAttributes = this.options.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New);
}

public override void OnEventWritten(string name, object payload)
Expand Down Expand Up @@ -133,35 +126,18 @@ public void OnStartActivity(Activity activity, object payload)
}

var uriHostNameType = Uri.CheckHostName(request.RequestUri.Host);
if (this.emitOldAttributes)
{
if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6)
{
activity.SetTag(SemanticConventions.AttributeNetPeerIp, request.RequestUri.Host);
}
else
{
activity.SetTag(SemanticConventions.AttributeNetPeerName, request.RequestUri.Host);
}

activity.SetTag(SemanticConventions.AttributeNetPeerPort, request.RequestUri.Port);
if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6)
{
activity.SetTag(SemanticConventions.AttributeServerSocketAddress, request.RequestUri.Host);
}

// see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md
if (this.emitNewAttributes)
else
{
if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6)
{
activity.SetTag(SemanticConventions.AttributeServerSocketAddress, request.RequestUri.Host);
}
else
{
activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host);
}

activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port);
activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host);
}

activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port);

try
{
this.options.EnrichWithHttpRequestMessage?.Invoke(activity, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
<ItemGroup>
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.Http\HttpRequestMessageContextPropagation.cs" Link="Includes\HttpRequestMessageContextPropagation.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\Shared\EnvironmentVariables\*.cs" Link="Includes\EnvironmentVariables\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\Shared\HttpSemanticConventionHelper.cs" Link="Includes\HttpSemanticConventionHelper.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Options\*.cs" Link="Includes\Options\%(Filename).cs" />
<Compile Include="$(RepoRoot)\src\Shared\Shims\NullableAttributes.cs" Link="Includes\Shims\NullableAttributes.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,10 @@ public static TracerProviderBuilder AddGrpcClientInstrumentation(

name ??= Options.DefaultName;

builder.ConfigureServices(services =>
if (configure != null)
{
if (configure != null)
{
services.Configure(name, configure);
}

services.RegisterOptionsFactory(configuration => new GrpcClientInstrumentationOptions(configuration));
});
builder.ConfigureServices(services => services.Configure(name, configure));
}

builder.AddSource(GrpcClientDiagnosticListener.ActivitySourceName);
builder.AddLegacySource("Grpc.Net.Client.GrpcOut");
Expand Down
198 changes: 0 additions & 198 deletions test/OpenTelemetry.Instrumentation.Grpc.Tests/GrpcTests.client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Grpc.Core;
#endif
using Grpc.Net.Client;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
#if !NETFRAMEWORK
using OpenTelemetry.Context.Propagation;
Expand Down Expand Up @@ -91,213 +90,16 @@ public void GrpcClientCallsAreCollectedSuccessfully(string baseAddress, bool sho

if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6)
{
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeNetPeerIp));
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeNetPeerName));
}
else
{
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeNetPeerIp));
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeNetPeerName));
}

Assert.Equal(uri.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort));
Assert.Equal(Status.Unset, activity.GetStatus());

// Tags added by the library then removed from the instrumentation
Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName));
Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName));
Assert.Equal(0, activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode));

if (shouldEnrich)
{
Assert.True(enrichWithHttpRequestMessageCalled);
Assert.True(enrichWithHttpResponseMessageCalled);
}
}

[Theory]
[InlineData("http://localhost")]
[InlineData("http://localhost", false)]
[InlineData("http://127.0.0.1")]
[InlineData("http://127.0.0.1", false)]
[InlineData("http://[::1]")]
[InlineData("http://[::1]", false)]
public void GrpcClientCallsAreCollectedSuccessfully_New(string baseAddress, bool shouldEnrich = true)
{
var config = new KeyValuePair<string, string>[] { new("OTEL_SEMCONV_STABILITY_OPT_IN", "http") };
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(config)
.Build();

bool enrichWithHttpRequestMessageCalled = false;
bool enrichWithHttpResponseMessageCalled = false;

var uri = new Uri($"{baseAddress}:1234");
var uriHostNameType = Uri.CheckHostName(uri.Host);

using var httpClient = ClientTestHelpers.CreateTestClient(async request =>
{
var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply());
var response = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent, grpcStatusCode: global::Grpc.Core.StatusCode.OK);
response.TrailingHeaders().Add("grpc-message", "value");
return response;
});

var exportedItems = new List<Activity>();

using var parent = new Activity("parent")
.SetIdFormat(ActivityIdFormat.W3C)
.Start();

using (Sdk.CreateTracerProviderBuilder()
.SetSampler(new AlwaysOnSampler())
.ConfigureServices(services => services.AddSingleton<IConfiguration>(configuration))
.AddGrpcClientInstrumentation(options =>
{
if (shouldEnrich)
{
options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; };
options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; };
}
})
.AddInMemoryExporter(exportedItems)
.Build())
{
var channel = GrpcChannel.ForAddress(uri, new GrpcChannelOptions
{
HttpClient = httpClient,
});
var client = new Greeter.GreeterClient(channel);
var rs = client.SayHello(new HelloRequest());
}

Assert.Single(exportedItems);
var activity = exportedItems[0];

ValidateGrpcActivity(activity);
Assert.Equal(parent.TraceId, activity.Context.TraceId);
Assert.Equal(parent.SpanId, activity.ParentSpanId);
Assert.NotEqual(parent.SpanId, activity.Context.SpanId);
Assert.NotEqual(default, activity.Context.SpanId);

Assert.Equal($"greet.Greeter/SayHello", activity.DisplayName);
Assert.Equal("grpc", activity.GetTagValue(SemanticConventions.AttributeRpcSystem));
Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService));
Assert.Equal("SayHello", activity.GetTagValue(SemanticConventions.AttributeRpcMethod));

if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6)
{
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress));
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeServerAddress));
}
else
{
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress));
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeServerAddress));
}

Assert.Equal(uri.Port, activity.GetTagValue(SemanticConventions.AttributeServerPort));
Assert.Equal(Status.Unset, activity.GetStatus());

// Tags added by the library then removed from the instrumentation
Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName));
Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName));
Assert.Equal(0, activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode));

if (shouldEnrich)
{
Assert.True(enrichWithHttpRequestMessageCalled);
Assert.True(enrichWithHttpResponseMessageCalled);
}
}

[Theory]
[InlineData("http://localhost")]
[InlineData("http://localhost", false)]
[InlineData("http://127.0.0.1")]
[InlineData("http://127.0.0.1", false)]
[InlineData("http://[::1]")]
[InlineData("http://[::1]", false)]
public void GrpcClientCallsAreCollectedSuccessfully_Dupe(string baseAddress, bool shouldEnrich = true)
{
var config = new KeyValuePair<string, string>[] { new("OTEL_SEMCONV_STABILITY_OPT_IN", "http/dup") };
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(config)
.Build();

bool enrichWithHttpRequestMessageCalled = false;
bool enrichWithHttpResponseMessageCalled = false;

var uri = new Uri($"{baseAddress}:1234");
var uriHostNameType = Uri.CheckHostName(uri.Host);

using var httpClient = ClientTestHelpers.CreateTestClient(async request =>
{
var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply());
var response = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent, grpcStatusCode: global::Grpc.Core.StatusCode.OK);
response.TrailingHeaders().Add("grpc-message", "value");
return response;
});

var exportedItems = new List<Activity>();

using var parent = new Activity("parent")
.SetIdFormat(ActivityIdFormat.W3C)
.Start();

using (Sdk.CreateTracerProviderBuilder()
.SetSampler(new AlwaysOnSampler())
.ConfigureServices(services => services.AddSingleton<IConfiguration>(configuration))
.AddGrpcClientInstrumentation(options =>
{
if (shouldEnrich)
{
options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; };
options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; };
}
})
.AddInMemoryExporter(exportedItems)
.Build())
{
var channel = GrpcChannel.ForAddress(uri, new GrpcChannelOptions
{
HttpClient = httpClient,
});
var client = new Greeter.GreeterClient(channel);
var rs = client.SayHello(new HelloRequest());
}

Assert.Single(exportedItems);
var activity = exportedItems[0];

ValidateGrpcActivity(activity);
Assert.Equal(parent.TraceId, activity.Context.TraceId);
Assert.Equal(parent.SpanId, activity.ParentSpanId);
Assert.NotEqual(parent.SpanId, activity.Context.SpanId);
Assert.NotEqual(default, activity.Context.SpanId);

Assert.Equal($"greet.Greeter/SayHello", activity.DisplayName);
Assert.Equal("grpc", activity.GetTagValue(SemanticConventions.AttributeRpcSystem));
Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService));
Assert.Equal("SayHello", activity.GetTagValue(SemanticConventions.AttributeRpcMethod));

if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6)
{
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeNetPeerIp));
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeNetPeerName));
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress));
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeServerAddress));
}
else
{
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeNetPeerIp));
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeNetPeerName));
Assert.Null(activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress));
Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeServerAddress));
}

Assert.Equal(uri.Port, activity.GetTagValue(SemanticConventions.AttributeServerPort));
Assert.Equal(uri.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort));
Assert.Equal(Status.Unset, activity.GetStatus());

// Tags added by the library then removed from the instrumentation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
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 Down Expand Up @@ -43,7 +42,6 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(string enableGrpc
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
[SemanticConventionOptInKeyName] = "http",
["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION"] = enableGrpcAspNetCoreSupport,
})
.Build();
Expand Down Expand Up @@ -116,7 +114,6 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewAc
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string>
{
[SemanticConventionOptInKeyName] = "http",
["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION"] = enableGrpcAspNetCoreSupport,
})
.Build();
Expand Down
Loading