Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
9 changes: 9 additions & 0 deletions src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## Unreleased

* **BREAKING**: Update to version 1.41.0 of the Semantic Conventions.
([#4338](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4338))

* Add instrumentation scope version and schema URL to traces.
([#4338](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4338))

* Add `net8.0` and `net10.0` target frameworks.
([#4338](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4338))
Comment thread
Kielek marked this conversation as resolved.
Outdated

## 1.0.0-beta.11

Released 2026-Apr-21
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,6 @@ private sealed class ClientRpcScope<TRequest, TResponse> : RpcScope<TRequest, TR
/// </summary>
private static readonly Action<Metadata?, string, string> MetadataSetter = (metadata, key, value) => { metadata?.Add(new Metadata.Entry(key, value)); };

/// <summary>
/// The context.
/// </summary>
private readonly ClientInterceptorContext<TRequest, TResponse> context;

/// <summary>
/// The parent activity.
/// </summary>
Expand All @@ -307,9 +302,9 @@ private sealed class ClientRpcScope<TRequest, TResponse> : RpcScope<TRequest, TR
/// <param name="context">The context.</param>
/// <param name="options">The options.</param>
public ClientRpcScope(ClientInterceptorContext<TRequest, TResponse> context, ClientTracingInterceptorOptions options)
: base(context.Method?.FullName, options.RecordMessageEvents, options.RecordException)
: base(context.Host, context.Method?.FullName, options.RecordMessageEvents, options.RecordException)
{
this.context = context;
this.Context = context;

// Capture the current activity.
this.parentActivity = Activity.Current;
Expand Down Expand Up @@ -355,20 +350,18 @@ public ClientRpcScope(ClientInterceptorContext<TRequest, TResponse> context, Cli

this.SetActivity(rpcActivity);
options.Propagator.Inject(new PropagationContext(rpcActivity.Context, Baggage.Current), callOptions.Headers, MetadataSetter);
this.context = new ClientInterceptorContext<TRequest, TResponse>(context.Method!, context.Host, callOptions);
this.Context = new ClientInterceptorContext<TRequest, TResponse>(context.Method!, context.Host, callOptions);
}

/// <summary>
/// Gets the context.
/// </summary>
public ClientInterceptorContext<TRequest, TResponse> Context => this.context;
public ClientInterceptorContext<TRequest, TResponse> Context { get; }

/// <summary>
/// Restores the parent activity.
/// </summary>
public void RestoreParentActivity()
{
Activity.Current = this.parentActivity;
}
=> Activity.Current = this.parentActivity;
}
}
21 changes: 9 additions & 12 deletions src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,15 @@ internal static class Extensions
/// <param name="first">The first.</param>
/// <param name="second">The second.</param>
/// <returns>An Action.</returns>
internal static Action WithBestEffortDispose(this IDisposable first, IDisposable second)
internal static Action WithBestEffortDispose(this IDisposable first, IDisposable second) => () =>
{
return () =>
try
{
try
{
first.Dispose();
}
finally
{
second.Dispose();
}
};
}
first.Dispose();
}
finally
{
second.Dispose();
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;
using System.Reflection;
using OpenTelemetry.Internal;
using OpenTelemetry.Trace;

namespace OpenTelemetry.Instrumentation.GrpcCore;

Expand All @@ -13,22 +12,12 @@ namespace OpenTelemetry.Instrumentation.GrpcCore;
internal static class GrpcCoreInstrumentation
{
/// <summary>
/// The assembly.
/// Gets the version of the RPC Semantic Conventions used by the instrumentation.
/// </summary>
internal static readonly Assembly Assembly = typeof(GrpcCoreInstrumentation).Assembly;
internal static readonly Version SemanticConventionsVersion = new(1, 41, 0);

/// <summary>
/// The assembly name.
/// Gets the activity source for the instrumentation.
/// </summary>
internal static readonly AssemblyName AssemblyName = Assembly.GetName();

/// <summary>
/// The activity source name.
/// </summary>
internal static readonly string ActivitySourceName = AssemblyName.Name;

/// <summary>
/// The activity source.
/// </summary>
internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion());
internal static readonly ActivitySource ActivitySource = ActivitySourceFactory.Create(typeof(GrpcCoreInstrumentation), SemanticConventionsVersion);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(NetStandardMinimumSupportedVersion)</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworksForLibraries)</TargetFrameworks>
<Description>.NET gRPC Core based client and server interceptors for OpenTelemetry.</Description>
<PackageTags>$(PackageTags);gRPC Core;interceptors</PackageTags>
<MinVerTagPrefix>Instrumentation.GrpcCore-</MinVerTagPrefix>
Expand All @@ -24,6 +24,7 @@
</ItemGroup>

<ItemGroup>
<Compile Include="$(RepoRoot)\src\Shared\ActivitySourceFactory.cs" Link="Includes\ActivitySourceFactory.cs" />
<Compile Include="$(RepoRoot)\src\Shared\AssemblyVersionExtensions.cs" Link="Includes\AssemblyVersionExtensions.cs" />
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\Shared\SemanticConventions.cs" Link="Includes\SemanticConventions.cs" />
Expand Down
56 changes: 42 additions & 14 deletions src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;
using System.Globalization;
using Google.Protobuf;
using Grpc.Core;
using OpenTelemetry.Internal;
Expand All @@ -19,6 +20,11 @@ internal abstract class RpcScope<TRequest, TResponse> : IDisposable
where TRequest : class
where TResponse : class
{
/// <summary>
/// The host.
/// </summary>
private readonly string? host;

/// <summary>
/// The record message events flag.
/// </summary>
Expand Down Expand Up @@ -52,11 +58,17 @@ internal abstract class RpcScope<TRequest, TResponse> : IDisposable
/// <summary>
/// Initializes a new instance of the <see cref="RpcScope{TRequest, TResponse}" /> class.
/// </summary>
/// <param name="host">The host that the current invocation will be dispatched to.</param>
/// <param name="fullServiceName">Full name of the service.</param>
/// <param name="recordMessageEvents">if set to <c>true</c> [record message events].</param>
/// <param name="recordException">If set to <c>true</c> [record exception].</param>
protected RpcScope(string? fullServiceName, bool recordMessageEvents, bool recordException)
protected RpcScope(
string? host,
string? fullServiceName,
bool recordMessageEvents,
bool recordException)
{
this.host = host;
this.FullServiceName = fullServiceName?.TrimStart('/') ?? "unknownservice/unknownmethod";
this.recordMessageEvents = recordMessageEvents;
this.recordException = recordException;
Expand Down Expand Up @@ -164,21 +176,39 @@ protected void SetActivity(Activity? activity)
return;
}

// assign some reasonable defaults
// Assign some reasonable defaults
var rpcService = this.FullServiceName;
var rpcMethod = this.FullServiceName;

// split the full service name by the slash
// Split the full service name by the slash
var parts = this.FullServiceName.Split('/');
if (parts.Length == 2)
{
rpcService = parts[0];
rpcMethod = parts[1];
}

this.activity.SetTag(SemanticConventions.AttributeRpcSystem, "grpc");
this.activity.SetTag(SemanticConventions.AttributeRpcSystemName, "grpc");
this.activity.SetTag(SemanticConventions.AttributeRpcService, rpcService);
this.activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod);

if (this.host is { Length: > 0 } host)
Comment thread
martincostello marked this conversation as resolved.
{
parts = host.Split(':');
Comment thread
martincostello marked this conversation as resolved.
Outdated

if (parts.Length > 0)
{
this.activity.SetTag(SemanticConventions.AttributeServerAddress, parts[0]);

if (parts.Length > 1 &&
int.TryParse(parts[1], NumberStyles.None, CultureInfo.InvariantCulture, out var port))
{
this.activity.SetTag(SemanticConventions.AttributeServerPort, port);
}
}
}
Comment thread
martincostello marked this conversation as resolved.

this.activity.DisplayName = rpcMethod.Trim('/');
}

/// <summary>
Expand All @@ -188,12 +218,12 @@ protected void SetActivity(Activity? activity)
/// <param name="markAsCompleted">If set to <c>true</c> [mark as completed].</param>
private void StopActivity(int statusCode, bool markAsCompleted = true)
{
if (markAsCompleted && !this.TryMarkAsCompleted())
if ((markAsCompleted && !this.TryMarkAsCompleted()) || this.activity is null)
{
return;
}

this.activity!.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, statusCode);
this.activity.SetTag(SemanticConventions.AttributeRpcResponseStatusCode, statusCode);
this.activity.Stop();
}

Expand All @@ -203,7 +233,7 @@ private void StopActivity(int statusCode, bool markAsCompleted = true)
/// <param name="exception">The exception.</param>
private void StopActivity(Exception exception)
{
if (!this.TryMarkAsCompleted())
if (!this.TryMarkAsCompleted() || this.activity is null)
{
return;
}
Expand All @@ -219,10 +249,10 @@ private void StopActivity(Exception exception)

if (!string.IsNullOrEmpty(description))
{
this.activity!.SetStatus(ActivityStatusCode.Error, description);
this.activity.SetStatus(ActivityStatusCode.Error, description);
}

if (this.activity!.IsAllDataRequested && this.recordException)
if (this.activity.IsAllDataRequested && this.recordException)
{
this.activity.AddException(exception);
}
Expand All @@ -235,9 +265,7 @@ private void StopActivity(Exception exception)
/// </summary>
/// <returns>Returns <c>true</c> if marked as completed successfully.</returns>
private bool TryMarkAsCompleted()
{
return Interlocked.CompareExchange(ref this.complete, 1, 0) == 0;
}
=> Interlocked.CompareExchange(ref this.complete, 1, 0) == 0;

/// <summary>
/// Adds a message event.
Expand All @@ -247,7 +275,7 @@ private bool TryMarkAsCompleted()
/// <param name="request">if true this is a request message.</param>
private void AddMessageEvent(string eventName, IMessage? message, bool request)
{
if (message == null)
if (message == null || this.activity is null)
{
return;
}
Expand All @@ -265,6 +293,6 @@ private void AddMessageEvent(string eventName, IMessage? message, bool request)
new(SemanticConventions.AttributeMessageUncompressedSize, messageSize),
]);

this.activity!.AddEvent(new ActivityEvent(eventName, default, attributes));
this.activity.AddEvent(new ActivityEvent(eventName, default, attributes));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ private class ServerRpcScope<TRequest, TResponse> : RpcScope<TRequest, TResponse
/// <param name="context">The context.</param>
/// <param name="options">The options.</param>
public ServerRpcScope(ServerCallContext context, ServerTracingInterceptorOptions options)
: base(context.Method, options.RecordMessageEvents, options.RecordException)
: base(context.Host, context.Method, options.RecordMessageEvents, options.RecordException)
{
if (!GrpcCoreInstrumentation.ActivitySource.HasListeners())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ public static TracerProviderBuilder AddGrpcCoreInstrumentation(
{
Guard.ThrowIfNull(builder);

return builder.AddSource(GrpcCoreInstrumentation.ActivitySourceName);
return builder.AddSource(GrpcCoreInstrumentation.ActivitySource.Name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

* **BREAKING**: Update to version 1.41.0 of the Semantic Conventions.
([#4338](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4338))

* Add instrumentation scope version and schema URL to traces.
([#4338](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4338))

## 1.15.1-beta.1

Released 2026-Apr-21
Expand Down
Loading
Loading