我希望在收到消息时初始化一些日志记录:
public class BaseMessage
{
public long TraceID { get; set; }
}
public class MyMessage : BaseMessage, ICommand
{
//..other properties
}
public class Handler : IHandleMessages<MyMessage>
{
public void Handle(MyMessage message)
{
log4net.ThreadContext.Properties["TraceID"] = message.TraceID
//Process message
}
}
问题是我有很多消息,我希望在收到消息时为所有消息执行此操作。我希望能够做到这样的事情:
public class Handler : IInitializeHandlers, IHandleMessages<MyMessage>
{
public void Init(BaseMessage message)
{
log4net.ThreadContext.Properties["TraceID"] = ((BaseMessage)message).TraceID
}
public void Handle(MyMessage message)
{
//Process message
}
}
答案 0 :(得分:1)
将跟踪ID移动到标头,并使用工作单元(IManageUnitsOfWork)将其注册到log4net上下文
答案 1 :(得分:0)
以下是我如何解决它。我想自动创建跟踪ID并将其发送到消息正文而不是标题。我不确定向总线添加标头的线程安全性,我不想更改所有调用代码或修改IHandleMessages实现。所以这就是我想出来的。
public class TraceIDMutator : IMutateIncomingMessages, IMutateOutgoingMessages
{
public object MutateIncoming(object message)
{
var baseMsg = message as MessageBase;
if (baseMsg != null)
ThreadContext.Properties[Constants.TraceID] = baseMsg.TraceID;
return message;
}
public object MutateOutgoing(object message)
{
var baseMsg = message as MessageBase;
if(baseMsg != null)
{
if(baseMsg.TraceID == 0)
{
var tid = ThreadContext.Properties[Constants.TraceID];
if (tid != null)
baseMsg.TraceID = (ulong)tid;
}
}
return message;
}
}
IMutateIncomingMessages
和IMutateOutgoingMessages
接口允许我接入nservicebus的消息传递管道。我只是在挖掘完源代码后才发现它,以找出实际发生的情况。您需要在IoC容器中注册此类才能使其正常工作。
ObjectFactory.Configure(x =>
{
x.For<IMutateIncomingMessages>().Use<TraceIDMutator>();
x.For<IMutateOutgoingMessages>().Use<TraceIDMutator>();
});
发送消息时,将调用“MutateOutgoing”。此时,我从log4net.ThreadContext
获取当前跟踪ID(如果有)并将其分配给消息。收到消息后,调用MutateIncoming
,然后为该线程设置log4net.ThreadContext
跟踪ID属性。