Tapeti/Tapeti.Serilog/Middleware/MessageHandlerLoggingBindin...

54 lines
2.0 KiB
C#

using System;
using System.Linq;
using Serilog.Events;
using Tapeti.Config;
namespace Tapeti.Serilog.Middleware
{
/// <summary>
/// Implements the middleware which binds any IDiagnosticContext parameter in message handlers.
/// </summary>
public class MessageHandlerLoggingBindingMiddleware : IControllerBindingMiddleware
{
private readonly IControllerMessageMiddleware controllerMessageMiddleware;
/// <summary>
/// Creates a new instance of the middleware which binds any IDiagnosticContext parameter in message handlers.
/// </summary>
/// <param name="elapsedWarningTreshold"></param>
/// <param name="defaultLevel"></param>
public MessageHandlerLoggingBindingMiddleware(double elapsedWarningTreshold = 500, LogEventLevel defaultLevel = LogEventLevel.Debug)
{
controllerMessageMiddleware = new MessageHandlerLoggingMessageMiddleware(elapsedWarningTreshold, defaultLevel);
}
/// <inheritdoc />
public void Handle(IControllerBindingContext context, Action next)
{
RegisterDiagnosticContextParameter(context);
// All state is contained within the message context, using a single middleware instance is safe
context.Use(controllerMessageMiddleware);
next();
}
private static void RegisterDiagnosticContextParameter(IControllerBindingContext context)
{
foreach (var parameter in context.Parameters.Where(p => !p.HasBinding && p.Info.ParameterType == typeof(IDiagnosticContext)))
parameter.SetBinding(DiagnosticContextFactory);
}
private static object? DiagnosticContextFactory(IMessageContext context)
{
return context.TryGet<DiagnosticContextPayload>(out var diagnosticContextPayload)
? diagnosticContextPayload.DiagnosticContext
: null;
}
}
}