diff --git a/README.md b/README.md index df5d9a4..b959581 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ This is an [Instrumentation Library](https://github.com/open-telemetry/opentelem - [Install](#install) - [Usage](#usage) + - [Exception Handling](#exception-handling) - [Example](#example) - [Related Work](#related-work) @@ -42,6 +43,27 @@ builder.Services.AddOpenTelemetry() }); ``` +### Exception Handling + +By setting the `OnException` option, you can override the attributes that this library writes by default. +For example, when an exception occurs inside your SignalR hub method, this library sets the `otel.status_code` attribute to `ERROR`. +However, there are cases where you do not want a specific exception to be `ERROR`. +In that case, you can override the default attribute by setting it as follows. + +```cs +builder.Services.AddSignalR() + .AddHubInstrumentation(options => + { + options.OnException = static (activity, exception) => + { + if (exception is HubException) + { + activity.SetTag("otel.status_code", "OK"); + } + }; + }); +``` + ## Example The example code architecture is as follows. diff --git a/src/AspNetCore.SignalR.OpenTelemetry/HubInstrumentationFilter.cs b/src/AspNetCore.SignalR.OpenTelemetry/HubInstrumentationFilter.cs index 3b16752..f200e2a 100644 --- a/src/AspNetCore.SignalR.OpenTelemetry/HubInstrumentationFilter.cs +++ b/src/AspNetCore.SignalR.OpenTelemetry/HubInstrumentationFilter.cs @@ -1,20 +1,24 @@ using System; +using System.Diagnostics; using System.Threading.Tasks; using AspNetCore.SignalR.OpenTelemetry.Internal; using Microsoft.AspNetCore.Http.Connections; using Microsoft.AspNetCore.Http.Connections.Features; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace AspNetCore.SignalR.OpenTelemetry; public sealed class HubInstrumentationFilter : IHubFilter { private readonly ILogger _logger; + private readonly HubInstrumentationOptions _options; - public HubInstrumentationFilter(ILoggerFactory loggerFactory) + public HubInstrumentationFilter(ILoggerFactory loggerFactory, IOptions options) { _logger = loggerFactory.CreateLogger("AspNetCore.SignalR.Logging.HubLoggingFilter"); + _options = options.Value; } public async ValueTask InvokeMethodAsync( @@ -46,6 +50,9 @@ public HubInstrumentationFilter(ILoggerFactory loggerFactory) catch (Exception exception) { HubActivitySource.StopInvocationActivityError(activity, exception); + + InvokeOptionExceptionHandler(activity, exception); + throw; } } @@ -75,6 +82,9 @@ public async Task OnConnectedAsync(HubLifetimeContext context, Func? OnException { get; set; } +} diff --git a/src/AspNetCore.SignalR.OpenTelemetry/SignalRServerBuilderExtensions.cs b/src/AspNetCore.SignalR.OpenTelemetry/SignalRServerBuilderExtensions.cs index 349bf98..8702542 100644 --- a/src/AspNetCore.SignalR.OpenTelemetry/SignalRServerBuilderExtensions.cs +++ b/src/AspNetCore.SignalR.OpenTelemetry/SignalRServerBuilderExtensions.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -7,6 +8,11 @@ namespace AspNetCore.SignalR.OpenTelemetry; public static class SignalRServerBuilderExtensions { public static ISignalRServerBuilder AddHubInstrumentation(this ISignalRServerBuilder builder) + { + return builder.AddHubInstrumentation(_ => { }); + } + + public static ISignalRServerBuilder AddHubInstrumentation(this ISignalRServerBuilder builder, Action configure) { builder.Services.TryAddSingleton(); @@ -15,6 +21,8 @@ public static ISignalRServerBuilder AddHubInstrumentation(this ISignalRServerBui options.AddFilter(); }); + builder.Services.Configure(configure); + return builder; } }