namespace LiteCharms.Features.Mediator; public sealed class TelemetryPipelineBehavior : IPipelineBehavior where TRequest : IRequest where TResponse : ResultBase, new() { public async ValueTask Handle(TRequest message, MessageHandlerDelegate next, CancellationToken cancellationToken) { var requestName = typeof(TRequest).Name; using var activity = MediatorTelemetry.Source.StartActivity(requestName); activity?.SetTag("mediator.request_type", typeof(TRequest).FullName); var stopWatch = Stopwatch.StartNew(); var status = "Success"; try { TResponse? response = await next(message, cancellationToken); if (response is null) { status = "NullResponse"; activity?.SetStatus(ActivityStatusCode.Error, "Response was null"); return response; } if (response.IsFailed) { status = "Failed"; activity?.SetStatus(ActivityStatusCode.Error, "Request failed"); var firstError = response.Errors.FirstOrDefault()?.Message ?? "Unknown Error"; activity?.SetTag("error.message", firstError); foreach (var error in response.Errors) activity?.AddEvent(new ActivityEvent("Result Error", tags: new() { { "message", error.Message } })); } else activity?.SetStatus(ActivityStatusCode.Ok); return response; } catch (Exception ex) { status = "Exception"; activity?.SetStatus(ActivityStatusCode.Error, ex.Message); activity?.AddException(ex); throw; } finally { stopWatch.Stop(); var tags = new TagList { { "request", requestName }, { "status", status } }; MediatorTelemetry.RequestCounter.Add(1, tags); MediatorTelemetry.RequestDuration.Record(stopWatch.Elapsed.TotalMilliseconds, tags); } } }