Skip to content

Commit

Permalink
feat: Support ActivitySource in ClientHelper
Browse files Browse the repository at this point in the history
This wires everything up, but doesn't actually start any activities. The implementation will all be in ApiCallTracingExtensions, in another commit.
  • Loading branch information
jskeet committed Apr 11, 2024
1 parent 36ee7d3 commit d6fa8a1
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Google.Api.Gax.Grpc/ApiBidirectionalStreamingCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;

namespace Google.Api.Gax.Grpc
{
Expand Down Expand Up @@ -83,5 +84,9 @@ logger is null
? this
: new ApiBidirectionalStreamingCall<TRequest, TResponse>(_methodName, _call.WithLogging(logger, _methodName), BaseCallSettings, StreamingSettings);

internal ApiBidirectionalStreamingCall<TRequest, TResponse> WithTracing(ActivitySource activitySource) =>
activitySource is null
? this
: new ApiBidirectionalStreamingCall<TRequest, TResponse>(_methodName, _call.WithTracing(activitySource, _methodName), BaseCallSettings, StreamingSettings);
}
}
9 changes: 9 additions & 0 deletions Google.Api.Gax.Grpc/ApiCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Google.Api.Gax.Grpc
Expand Down Expand Up @@ -173,6 +174,14 @@ logger is null
_syncCall.WithLogging(logger, _methodName),
BaseCallSettings);

internal ApiCall<TRequest, TResponse> WithTracing(ActivitySource activitySource) =>
activitySource is null
? this
: new ApiCall<TRequest, TResponse>(
_methodName, _asyncCall.WithTracing(activitySource, _methodName),
_syncCall.WithTracing(activitySource, _methodName),
BaseCallSettings);

/// <summary>
/// Constructs a new <see cref="ApiCall{TRequest, TResponse}"/> that applies an overlay to
/// the underlying <see cref="CallSettings"/>. If a value exists in both the original and
Expand Down
51 changes: 51 additions & 0 deletions Google.Api.Gax.Grpc/ApiCallTracingExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2024 Google LLC All Rights Reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file or at
* https://developers.google.com/open-source/licenses/bsd
*/

using Grpc.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;

namespace Google.Api.Gax.Grpc;

/// <summary>
/// Extension methods to provide tracing via <see cref="ActivitySource"/>.
/// </summary>
internal static class ApiCallTracingExtensions
{
// Unary async
internal static Func<TRequest, CallSettings, Task<TResponse>> WithTracing<TRequest, TResponse>(
this Func<TRequest, CallSettings, Task<TResponse>> fn, ActivitySource activitySource, string methodName) =>
fn;

// Unary sync
internal static Func<TRequest, CallSettings, TResponse> WithTracing<TRequest, TResponse>(
this Func<TRequest, CallSettings, TResponse> fn, ActivitySource activitySource, string methodName) =>
fn;

// Server-streaming async
internal static Func<TRequest, CallSettings, Task<AsyncServerStreamingCall<TResponse>>> WithTracing<TRequest, TResponse>(
this Func<TRequest, CallSettings, Task<AsyncServerStreamingCall<TResponse>>> fn, ActivitySource activitySource, string methodName) =>
fn;

// Server-streaming sync
internal static Func<TRequest, CallSettings, AsyncServerStreamingCall<TResponse>> WithTracing<TRequest, TResponse>(
this Func<TRequest, CallSettings, AsyncServerStreamingCall<TResponse>> fn, ActivitySource activitySource, string methodName) =>
fn;

// Client-streaming
internal static Func<CallSettings, AsyncClientStreamingCall<TRequest, TResponse>> WithTracing<TRequest, TResponse>(
this Func<CallSettings, AsyncClientStreamingCall<TRequest, TResponse>> fn, ActivitySource activitySource, string methodName) =>
fn;

// Bidi-streaming
internal static Func<CallSettings, AsyncDuplexStreamingCall<TRequest, TResponse>> WithTracing<TRequest, TResponse>(
this Func<CallSettings, AsyncDuplexStreamingCall<TRequest, TResponse>> fn, ActivitySource activitySource, string methodName) =>
fn;
}
6 changes: 6 additions & 0 deletions Google.Api.Gax.Grpc/ApiClientStreamingCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;

namespace Google.Api.Gax.Grpc
{
Expand Down Expand Up @@ -80,5 +81,10 @@ internal ApiClientStreamingCall<TRequest, TResponse> WithLogging(ILogger logger)
logger is null
? this
: new ApiClientStreamingCall<TRequest, TResponse>(_methodName, _call.WithLogging(logger, _methodName), BaseCallSettings, StreamingSettings);

internal ApiClientStreamingCall<TRequest, TResponse> WithTracing(ActivitySource activitySource) =>
activitySource is null
? this
: new ApiClientStreamingCall<TRequest, TResponse>(_methodName, _call.WithTracing(activitySource, _methodName), BaseCallSettings, StreamingSettings);
}
}
10 changes: 10 additions & 0 deletions Google.Api.Gax.Grpc/ApiServerStreamingCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Google.Api.Gax.Grpc
Expand Down Expand Up @@ -144,5 +145,14 @@ logger is null
_asyncCall.WithLogging(logger, _methodName),
_syncCall.WithLogging(logger, _methodName),
BaseCallSettings);

internal ApiServerStreamingCall<TRequest, TResponse> WithTracing(ActivitySource activitySource) =>
activitySource is null
? this
: new ApiServerStreamingCall<TRequest, TResponse>(
_methodName,
_asyncCall.WithTracing(activitySource, _methodName),
_syncCall.WithTracing(activitySource, _methodName),
BaseCallSettings);
}
}
14 changes: 14 additions & 0 deletions Google.Api.Gax.Grpc/ClientHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;

namespace Google.Api.Gax.Grpc
{
Expand All @@ -28,6 +29,8 @@ public class ClientHelper
/// </summary>
private readonly CallSettings _versionCallSettings;

private readonly ActivitySource _activitySource;

/// <summary>
/// Constructs a helper from the given settings.
/// Behavior is undefined if settings are changed after construction.
Expand Down Expand Up @@ -61,6 +64,7 @@ public ClientHelper(Options options)
{
_versionCallSettings = _versionCallSettings.WithHeader(ApiVersionHeaderName, options.ApiVersion);
}
_activitySource = options.ActivitySource;
}

/// <summary>
Expand Down Expand Up @@ -105,6 +109,7 @@ public ApiCall<TRequest, TResponse> BuildApiCall<TRequest, TResponse>(
// I.e. Version header is added first, then retry is performed.
return ApiCall.Create(methodName, asyncGrpcCall, syncGrpcCall, baseCallSettings, Clock)
.WithLogging(Logger)
.WithTracing(_activitySource)
.WithRetry(Clock, Scheduler, Logger)
.WithMergedBaseCallSettings(_versionCallSettings);
}
Expand All @@ -129,6 +134,7 @@ public ApiServerStreamingCall<TRequest, TResponse> BuildApiCall<TRequest, TRespo
// I.e. Version header is added first, then retry is performed.
return ApiServerStreamingCall.Create(methodName, grpcCall, baseCallSettings, Clock)
.WithLogging(Logger)
.WithTracing(_activitySource)
.WithMergedBaseCallSettings(_versionCallSettings);
}

Expand All @@ -153,6 +159,7 @@ public ApiBidirectionalStreamingCall<TRequest, TResponse> BuildApiCall<TRequest,
CallSettings baseCallSettings = _clientCallSettings.MergedWith(perMethodCallSettings);
return ApiBidirectionalStreamingCall.Create(methodName, grpcCall, baseCallSettings, streamingSettings, Clock)
.WithLogging(Logger)
.WithTracing(_activitySource)
.WithMergedBaseCallSettings(_versionCallSettings);
}

Expand All @@ -177,6 +184,7 @@ public ApiClientStreamingCall<TRequest, TResponse> BuildApiCall<TRequest, TRespo
CallSettings baseCallSettings = _clientCallSettings.MergedWith(perMethodCallSettings);
return ApiClientStreamingCall.Create(methodName, grpcCall, baseCallSettings, streamingSettings, Clock)
.WithLogging(Logger)
.WithTracing(_activitySource)
.WithMergedBaseCallSettings(_versionCallSettings);
}

Expand Down Expand Up @@ -204,6 +212,12 @@ public sealed class Options
/// The API version to send in the x-goog-api-version header, if any. This may be null.
/// </summary>
public string ApiVersion { get; set; }

/// <summary>
/// The activity source to use for tracing, if any. This may be null.
/// Note: currently internal until we're ready to roll out OpenTelemetry support "properly".
/// </summary>
internal ActivitySource ActivitySource { get; set; }
}
}
}

0 comments on commit d6fa8a1

Please sign in to comment.