open-telemetry / opentelemetry-dotnet

The OpenTelemetry .NET Client
https://opentelemetry.io
Apache License 2.0
3.27k stars 769 forks source link

Support user provided grpc CallInvoker #5028

Open Kadajski opened 1 year ago

Kadajski commented 1 year ago

Feature Request

It would be great if we could have a Func<CallInvoker> for the grpc protocol similar to the current Func<HttpClient> HttpClientFactory for http protocol. There are numerous cases where customising the grpc client is valuable and right now there is not much flexibility in terms of customising the grpc channel. The grpc CallInvoker would allow custom interceptors, clientside load balancing configuration, retry strategy configuration, custom error handling, etc which are all currently not supported in openteletry-dotnet from what I can see

Is your feature request related to a problem? No

Describe the solution you'd like: OtlpExporterOptions.cs to be extended with a new property public Func<CallInvoker> GrpcCallInvoker { get; set; } which, when provided, will be used instead of the internal Channel that lives inside of BaseOtlpGrpcExportClient<TRequest>. Allowing for the consumer of the OpenTelemetry.Exporter.OpenTelemetryProtocol package to configure the grpc client as they wish

Describe alternatives you've considered. The alternative may be to provide a lot of additional options for every feature that may be requested such as #3272, #1779, or for the consumers to need to implement the entire exporter themselves. Another option may be to expose some support for Grpc.Net.ClientFactory although this would only work for framework versions that support grpc-dotnet.

Additional Context

My company already has a bunch of tooling around grpc which generates our own grpc client factory which wraps the CallInvoker with a set of interceptors and configuration which has worked very well for us. It would be great if we could re-use this tooling for OpenTelemetry.Exporter.OpenTelemetryProtocol as right now anytime we see grpc client issues in opentelemetry-dotnet there is very little flexibility in terms of options for us to tweak to improve ths

cvi-mft commented 6 months ago

This seems like a good candidate https://github.com/open-telemetry/opentelemetry-dotnet/pull/4815. It's sad it was closed due to inactivitity. Is it possible to revive that PR?

madskonradsen commented 5 months ago

Hej Claus @cvi-mft ;-)

Did you come across anything interesting after this comment? I thought that the approach in #4815 would be key in solving my issue of trying to use OTEL in Blazor WASM, but after trying to integrate the code in the PR locally, I just ended up in another issue - the fact that gRPC tries to make blocking unary calls and expects the environment to support threading, which Blazor WASM doesn't support yet (has been postponed to .Net10 - https://github.com/dotnet/aspnetcore/issues/17730#issuecomment-2059602250 )

cvi-mft commented 5 months ago

Hej Mads @madskonradsen. Lol.

I do not use Blazor. I am using #4815 with great success in standard ASP.NET applications with the following factory:

                        o.CallInvokerFactory = uri =>
                        {
                            var azureCredential = new DefaultAzureCredential();
                            var credentials = CallCredentials.FromInterceptor(async (_, metadata) =>
                            {
                                var token = await azureCredential.GetTokenAsync(new TokenRequestContext([
                                    scope
                                ]));
                                metadata.Add("Authorization", $"Bearer {token.Token}");
                            });
                            return GrpcChannel.ForAddress(uri,
                                new GrpcChannelOptions
                                {
                                    Credentials = ChannelCredentials.Create(new SslCredentials(), credentials)
                                }).CreateCallInvoker();
                        };
madskonradsen commented 5 months ago

HAH! Love that you probably deploy a patched DLL to prod! Seems like our issues are not very related, I just ended up in this ticket from #5083 , but nice that you make it work :)