1

I suspect this is not possible, but someone may have an interesting solution.

I want to set the TraceId on a gRPC call. This will allow me continuity of trace across a variety of boundaries. For example a bunch of requests that have been stored to file, and now need processing.

The destination is a C# ASP.NET Core gRPC service. The source is a c# console app that uses an ASP.NET Core WebApplicationBuilder as the source of the client. i.e.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
builder.Services.AddGrpcClient<Greeter.GreeterClient>(options => 
    {options.Address = new (serviceAddress);});

//logging stuff
var serilog = new LoggerConfiguration();
serilog.WriteTo.Console();
serilog.WriteTo.File(new CompactJsonFormatter(), @"D:\Log\Consumer.json", rollingInterval: RollingInterval.Day);
builder.Logging.ClearProviders();
builder.Logging.AddSerilog(serilog.CreateLogger());

var app = builder.Build();

using var scope = app.Services.CreateScope();
var client = scope.ServiceProvider.GetRequiredService<Greeter.GreeterClient>();
client.SayHello(new HelloRequest());

The json log output then contains lines such as:

{"@t":"2025-06-27T10:37:05.7886907Z","@mt":"Start processing HTTP request {HttpMethod} {Uri}","@tr":"9b14662ca75754818cc8cac1a61924b7","@sp":"896f4d5f87913065","HttpMethod":"POST","Uri":"https://localhost:7156/greet.Greeter/SayHello","EventId":{"Id":100,"Name":"RequestPipelineStart"},"SourceContext":"System.Net.Http.HttpClient.GreeterClient.LogicalHandler","SpanId":"896f4d5f87913065","TraceId":"9b14662ca75754818cc8cac1a61924b7","ParentId":"0000000000000000", ....

Using the ASP.NET Core wrapper adds a load of useful log enriching to the client, including a TraceId that will propagate along the chain. In my case however the client is not the originator of the request, just of the the gRPC section.

I know that using a CorrelationId as additional metadata will get me the majority of the functionality. I have already tried it and I expect that may well be the best available solution. But it would be much neater if I could tie into the existing infrastructure and not have to included a load of additional interceptors.

What I have tried:

  • I have tried adding ASP.NET Core middleware, but it seems to not get hit on the client outbound. gRPC interceptors are of course hit, but these do not have edit access to the HTTP context.

  • I have tried adding in traceId and traceparent to the metadata of the call from the client. This does override the trace-id (via traceparent) at the server end, but not in the logging at the client end. It also seems to not override correctly.

I believe that the only way to do it is to get in at the point that the client is generated. I suspect that somewhere in the chain there is a service that provides the trace data to the client that would need to be overridden or manipulated, but I can't find it.

Context:

  • Windows 11,
  • .NET 8
  • Grpc.AspNetCore v2.71.0
  • everything latest stable as of posting date
10
  • 1
    What TraceID are you talking about? If you mean OpenTelemetry Tracing, it's not just possible, gRPC is the actual protocol used to transfer traces. You didn't post any code that sets up OpenTelemetry, much less propagate traces Commented Jun 26 at 10:52
  • The edit doesn't explain anything. There's still no OpenTelemetry configuration code. Tracing isn't logging so can't be configured using the logging middleware. The trace context (that's what you're asking for) is propagated using standardized headers, not the HTTP call payload. .NET 5+ support the standard. ASP.NET Core is already instrumented, your own code though never sets up tracing Commented Jun 27 at 11:49
  • I'm pretty sure I posted links to the docs yesterday. In case I forgot to submit, check the OTEL for .NET Getting Started guide. Both ASP.NET Core and HttpClient are instrumented, but you do need those AddOpenTelemetry calls. .NET's Observability with OpenTelemetry goes into more details, using Aspire Dashboard as a way to visualize the traces, no matter what app is used. Commented Jun 27 at 11:54
  • I understand that OpenTelemetry (or equivalent) is needed for a more formal tracing solution. What I am looking at here is exactly what is in the question. The log output from the code includes a TraceId, that does propagate to the server but I can not find (and suspect there isn't) a way to set the value on the client. Commented Jun 28 at 9:49
  • The question is unclear, confusing tracing, logging and Serilog and thus impossible to answer until you understand the distinction. If you want to include the TraceID in the Serilog message, use Serilog.Enrichers.Span. You still need to create an ActivitySource. otherwise there won't be any Activity to which a TraceId can be set and read. If you want to use Serilog as the tracing system, use SerilogTracing. You'll have to instrument HttpClient and other libraries too Commented Jun 30 at 6:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.