在以下示例中,我将范围应用于NServiceBus Behavior中间件中的ILogger。不幸的是,此作用域不会在后续的next()调用中持续存在。我如何在IHandleMessages处理程序中获取范围以保留消息?
public override async Task Invoke(ITransportReceiveContext context, Func<Task> next)
{
var correlationId = context.Message.Headers[Headers.CorrelationId] ?? context.Message.MessageId;
using (_logger.BeginScope(correlationId))
{
await next().ConfigureAwait(false);
}
}
我实现了类似于使用传入消息中的已知标头设置日志记录上下文的操作,以便我的日志包含上下文信息。
有两个步骤:
实施例:
public class IncomingBehavior : Behavior<IIncomingLogicalMessageContext>
{
public override Task Invoke(IIncomingLogicalMessageContext context, Func<Task> next)
{
context.StoreHeaderValueToPipelineContext(KnownHeader.MyHeader);
NLog.MappedDiagnosticsLogicalContext.Clear();
context.StoreHeaderToNLogContext(KnownHeader.MyHeader);
return next();
}
}
public class OutgoingBehavior : Behavior<IOutgoingLogicalMessageContext>
{
public override Task Invoke(IOutgoingLogicalMessageContext context, Func<Task> next)
{
context.StorePipelineContextToOutgoingMessageHeader(KnownHeader.MyHeader);
return next();
}
}
public static class IMessageProcessingExtensions
{
public static IMessageProcessingContext StoreHeaderValueToPipelineContext(this IMessageProcessingContext context,
string headerName)
{
if (context.MessageHeaders.TryGetValue(headerName, out string headerValue))
{
context.Extensions.Set(headerName, headerValue);
}
return context;
}
public static IOutgoingLogicalMessageContext StorePipelineContextToOutgoingMessageHeader
(this IOutgoingLogicalMessageContext context,
string headerName)
{
if (context.Extensions.TryGet(headerName, out string headerValue))
{
context.Headers[headerName] = headerValue;
}
return context;
}
public static IMessageProcessingContext StoreHeaderToNLogContext(this IMessageProcessingContext context,
string headerName)
{
if (context.MessageHeaders.TryGetValue(headerName, out string headerValue))
{
NLog.MappedDiagnosticsLogicalContext.Set(headerName, headerValue);
}
return context;
}
}