You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe the problem.
I am trying to add W3C Trace Context to our client's SignalR calls over WebSockets.
Our client generates a root trace ID when the page loads, and we are able to use interceptors on our REST calls to add the trace context to HTTP requests very easily, and ASP.NET Core automatically handles mapping the trace context to System.Diagnostics.Activity.Current. This allows us to do distributed tracing and track requests initiated by a single user's page load across all of our services.
I would like the same thing for SignalR: automatic sending (for clients) and parsing (for servers/hubs) of W3C trace context, as well as handling Activity.Current. This may only be applicable to the browser-based WebSocket clients, since you should be able to set arbitrary HTTP headers, including traceparent and tracestate, using other clients/transports, and I assume those would still be parsed by ASP.NET Core.
I found a workaround to do this in the browser, but it passes the trace context using a query string parameter in the connection URL, which I am not sure is supported or not. It also requires you to manually reset the current for each hub method call, which is easy to miss.
Describe the solution you'd like
I would like it if there was a way to specify a trace context in the client libraries and send it to the hub somehow, and for the HubContext to automatically parse the context and set Activity.Current accordingly. (This would require some trickery for JS/browser clients since browsers don't allow extra headers in WebSocket connections.)
For example:
/** * Add W3C trace context to the negotiation and connection requests * @param {string?} traceparent - Parent trace context string. * If not specified, a random context will be created. */functionwithTraceContext(traceparent: string?){}
In my example, the hub methods' parent activity is a "StartSession" activity created on connection, but I would probably be fine if the parent was set to the client's trace context directly.
Another option is to have another property in HubContext or a magic key in HubContext.Items 🪄 (e.g. Context.Items["traceparent"]) that is automatically parsed by the hub. That way, the user could decide how they want to get the trace context to the hub on the initial connection and parse it in OnConnectedAsync. From there, the HubContext could automatically pick up the trace context from that HubContext property or Item.
Additional context
I have found a way to add this, but it feels a little hacky:
//MyHub.cspublicclassMyHub{// ...publicTaskOnConnectedAsync(){ActivityContextactivityCtx=default;varhttpCtx=Context.GetHttpContext();if(httpCtx.Request.Query.TryGetValue("traceparent",outStringValuestpParam)&&tpParam.SingleOrDefault()isstringtraceParent){try{stringtraceState=(httpCtx.Request.Query.TryGetValue("tracestate",outStringValuestsParam))?tsParam.SingleOrDefault():null;if(ActivityContext.TryParse(traceParent,traceState,outactivityCtx)){}}catch{}}Activityactivity=MyDiagnostics.ActivitySource.StartActivity("MyHub.StartSession",ActivityKind.Client,activityCtx);Context.Items["tracecontext"]=activity;returnTask.CompletedTask;}publicasyncTaskDoSomething(){// Add this line to the beginning of every hub method.usingvaractivity=StartActivity($"{nameof(MyHub)}.{nameof(DoSomething)});
}
private Activity GetCurrentConnectionActivity(){return Context.Items["tracecontext"]asActivity;}privateActivityStartActivity(stringoperation){returnMyDiagnostics.ActivitySource.StartActivity(operation,ActivityKind.Client,GetCurrentConnectionActivity().Context);}}
// MyDiagnostics.cspublicstaticclassMyDiagnostics{publicstaticreadonlyActivitySourceActivitySource=StartActivitySource();privatestaticActivitySourceStartActivitySource(){varsource=newActivitySource("MyActivitySource",FileVersionInfo.GetVersionInfo(Assembly.GetAssembly(typeof(MyDiagnostics))!.Location).FileVersion);ActivitySource.AddActivityListener(newActivityListener{ShouldListenTo= s =>true,SampleUsingParentId=(refActivityCreationOptions<string>activityOptions)=>ActivitySamplingResult.AllData,Sample=(refActivityCreationOptions<ActivityContext>activityOptions)=>ActivitySamplingResult.AllData,});returnsource;}}
The text was updated successfully, but these errors were encountered:
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
Is there an existing issue for this?
Is your feature request related to a problem? Please describe the problem.
I am trying to add W3C Trace Context to our client's SignalR calls over WebSockets.
Our client generates a root trace ID when the page loads, and we are able to use interceptors on our REST calls to add the trace context to HTTP requests very easily, and ASP.NET Core automatically handles mapping the trace context to
System.Diagnostics.Activity.Current
. This allows us to do distributed tracing and track requests initiated by a single user's page load across all of our services.I would like the same thing for SignalR: automatic sending (for clients) and parsing (for servers/hubs) of W3C trace context, as well as handling
Activity.Current
. This may only be applicable to the browser-based WebSocket clients, since you should be able to set arbitrary HTTP headers, includingtraceparent
andtracestate
, using other clients/transports, and I assume those would still be parsed by ASP.NET Core.I found a workaround to do this in the browser, but it passes the trace context using a query string parameter in the connection URL, which I am not sure is supported or not. It also requires you to manually reset the current for each hub method call, which is easy to miss.
Describe the solution you'd like
I would like it if there was a way to specify a trace context in the client libraries and send it to the hub somehow, and for the
HubContext
to automatically parse the context and setActivity.Current
accordingly. (This would require some trickery for JS/browser clients since browsers don't allow extra headers in WebSocket connections.)For example:
In my example, the hub methods' parent activity is a "StartSession" activity created on connection, but I would probably be fine if the parent was set to the client's trace context directly.
Another option is to have another property in
HubContext
or a magic key inHubContext.Items
🪄 (e.g.Context.Items["traceparent"]
) that is automatically parsed by the hub. That way, the user could decide how they want to get the trace context to the hub on the initial connection and parse it inOnConnectedAsync
. From there, theHubContext
could automatically pick up the trace context from thatHubContext
property orItem
.Additional context
I have found a way to add this, but it feels a little hacky:
In the client:
On the server:
The text was updated successfully, but these errors were encountered: