opentracing-contrib / csharp-netcore

OpenTracing instrumentation for .NET Core 3.1 & .NET 6+ apps
Apache License 2.0
261 stars 74 forks source link

Creating Spans for SignalR messages sent over Web Sockets #84

Open js8080 opened 3 years ago

js8080 commented 3 years ago

I'm using opentracing-csharp-netcore in an ASP.NET Core (3.1) application that receives SignalR requests via WebSockets.

In my Startup.ConfigureServices() method I setup OpenTracing as follows:

            services.AddOpenTracingCoreServices(otBuilder =>
            {
                otBuilder.AddAspNetCore()
                    .ConfigureAspNetCore(options =>
                    {
                        var ignoredRequestPaths = tracingOptions.IgnoredRequestPaths;
                        options.Hosting.IgnorePatterns.Add(ctx => (ignoredRequestPaths != null) ? ignoredRequestPaths.Contains(ctx.Request.Path) : false);

                        // options.Hosting.OnError = (span, exception, context) => {} -- this is only thrown when there is an unhandled exception, not when an HTTP error is purposefully returned by a controller

                        // This sets the main-level Span Operation Name which normally has a less than useful value in my experience.
                        options.Hosting.OperationNameResolver = (httpContext) =>
                        {
                            return httpContext.Request.Path.Value;
                        };
                    })
                    .AddCoreFx()
                    .AddEntityFrameworkCore()
                    .AddLoggerProvider();
            });

Unfortunately, what I am finding is that SignalR via WebSockets requests received do not cause a Span to be created. Meanwhile, regular HTTP web requests work fine.

Is there some limitation to DiagnosticListeners that don't support SignalR over Web Sockets or does opentracing-csharp-netcore just not support listening for Web Socket events?

Sorry I am not an expert in the terminology for SignalR over Web Sockets or the inner workings of opentracing-charp-netcore but hopefully I got my question across despite that.

cwe1ss commented 3 years ago

Hi. I don't have any experience with SignalR so I don't know if & how it can be instrumented. Could you point me to some instrumentaion-code in the SignalR code?

js8080 commented 3 years ago

That's an excellent question and I'm in the process of digging up info on how to instrument SignalR. I will follow-up with what I find.

js8080 commented 3 years ago

@cwe1ss - check out Add EventSource/EventCounter tracing and metrics for SignalR and WebSockets #2461 (aspnetcore github). Sounds like there is no DiagnosticSource in the ASP.NET Core SignalR code so a different approach would be needed. Unfortunately, I am not sure if there is another approach.

cwe1ss commented 3 years ago

Thank you for the link!

I've done some quick research as well and I've seen that they introduced "Hub filters" with ASP.NET Core 5.0. This seems to be the same concept as "action filters" for MVC and gives you a nice hook.

So, if you're on ASP.NET Core 5.0, you could write a global hub filter that creates OpenTracing spans via the regular OpenTracing API.

js8080 commented 3 years ago

@cwe1ss thanks! I will look into that.