using System;
using System.Linq;
using Serilog.Events;
using Tapeti.Config;
namespace Tapeti.Serilog.Middleware
{
///
/// Implements the middleware which binds any IDiagnosticContext parameter in message handlers.
///
public class MessageHandlerLoggingBindingMiddleware : IControllerBindingMiddleware
{
private readonly IControllerMessageMiddleware controllerMessageMiddleware;
///
/// Creates a new instance of the middleware which binds any IDiagnosticContext parameter in message handlers.
///
///
///
public MessageHandlerLoggingBindingMiddleware(double elapsedWarningTreshold = 500, LogEventLevel defaultLevel = LogEventLevel.Debug)
{
controllerMessageMiddleware = new MessageHandlerLoggingMessageMiddleware(elapsedWarningTreshold, defaultLevel);
}
///
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(out var diagnosticContextPayload)
? diagnosticContextPayload.DiagnosticContext
: null;
}
}
}