diff --git a/build/Common.props b/build/Common.props index 8f9490f903..0455be2fb7 100644 --- a/build/Common.props +++ b/build/Common.props @@ -34,6 +34,7 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [6.0.0,7.0) + [9.0.0,) [2.1.0,5.0) [9.0.0,) [9.0.0,) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs index 09a60868c6..fa3a322b7f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs @@ -121,5 +121,12 @@ private static void AddAspNetCoreInstrumentationSources( builder.AddSource(HttpInListener.ActivitySourceName); builder.AddLegacySource(HttpInListener.ActivityOperationName); // for the activities created by AspNetCore } + + // SignalR activities first added in .NET 9.0 + if (Environment.Version.Major >= 9) + { + // https://github.com/dotnet/aspnetcore/blob/6ae3ea387b20f6497b82897d613e9b8a6e31d69c/src/SignalR/server/Core/src/Internal/SignalRServerActivitySource.cs#L13C35-L13C70 + builder.AddSource("Microsoft.AspNetCore.SignalR.Server"); + } } } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index ac7a5929ec..2297a593dd 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.SignalR.Client; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -1114,6 +1115,63 @@ public async Task ValidateUrlQueryRedaction(string urlQuery, string expectedUrlQ Assert.Equal(expectedUrlQuery, activity.GetTagValue(SemanticConventions.AttributeUrlQuery)); } +#if NET9_0_OR_GREATER + [Fact] + public async Task SignalRActivitesAreListenedTo() + { + var exportedItems = new List(); + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + } + + // Arrange + using (var server = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + })) + { + await using var client = new HubConnectionBuilder() + .WithUrl(server.Server.BaseAddress + "testHub", o => + { + o.HttpMessageHandlerFactory = _ => server.Server.CreateHandler(); + o.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.LongPolling; + }).Build(); + await client.StartAsync(); + + await client.SendAsync("Send", "text"); + + await client.StopAsync(); + } + + WaitForActivityExport(exportedItems, 11); + + var hubActivity = exportedItems + .Where(a => a.DisplayName.StartsWith("TestApp.AspNetCore.TestHub", StringComparison.InvariantCulture)); + + Assert.Equal(3, hubActivity.Count()); + Assert.Collection( + hubActivity, + one => + { + Assert.Equal("TestApp.AspNetCore.TestHub/OnConnectedAsync", one.DisplayName); + }, + two => + { + Assert.Equal("TestApp.AspNetCore.TestHub/Send", two.DisplayName); + }, + three => + { + Assert.Equal("TestApp.AspNetCore.TestHub/OnDisconnectedAsync", three.DisplayName); + }); + } +#endif + public void Dispose() { this.tracerProvider?.Dispose(); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 11def19721..d0bf16a02e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -18,6 +18,7 @@ + diff --git a/test/TestApp.AspNetCore/Program.cs b/test/TestApp.AspNetCore/Program.cs index 5cbe2b5e3a..110693b6fa 100644 --- a/test/TestApp.AspNetCore/Program.cs +++ b/test/TestApp.AspNetCore/Program.cs @@ -20,6 +20,8 @@ public static void Main(string[] args) builder.Services.AddMvc(); + builder.Services.AddSignalR(); + builder.Services.AddSingleton(); builder.Services.AddSingleton( @@ -43,6 +45,8 @@ public static void Main(string[] args) app.MapControllers(); + app.MapHub("/testHub"); + app.UseMiddleware(); app.UseMiddleware(); diff --git a/test/TestApp.AspNetCore/TestHub.cs b/test/TestApp.AspNetCore/TestHub.cs new file mode 100644 index 0000000000..73a8a09bb0 --- /dev/null +++ b/test/TestApp.AspNetCore/TestHub.cs @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.AspNetCore.SignalR; + +namespace TestApp.AspNetCore; + +public class TestHub : Hub +{ + public override Task OnConnectedAsync() => base.OnConnectedAsync(); + + public void Send(string message) + { + } +}