WCF 服务 - 记录调用方详细信息
WCF Service - Logging Caller Details
我创建了一个 Windows 服务 (.Net 4.0),它通过 TCP 绑定公开 WCF 服务端点。
调用服务方法时,它将在不同的线程中执行多个任务。每个 class 执行的操作都有一个 Log4Net ILog 实现注入(使用依赖注入)。
我想做的是每个日志条目都有调用者的 IP 地址,这样我就可以跟踪调用或确定服务器上哪个调用出错。
使用 log4Net 的 LogicalThreadContext,我已经设法为写在同一线程上的任何日志消息实现了这一点,但没有为其他线程上的任何内容实现。
示例代码如下。
服务接口:
[ServiceContract(Namespace = "http://tremac")]
public interface IBroadcastService
{
[OperationContract]
void PublishMessage(Message message);
}
服务实施:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class BroadcastService: IBroadcastService
{
private readonly ILog _logger;
public BroadcastService(ILog logger)
{
_logger = logger;
_logger.Debug("Broadcast Service Initiated");
}
public void PublishMessage(Message message)
{
var prop =
OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as
RemoteEndpointMessageProperty;
string ip = prop == null ? "" : prop.Address;
log4net.LogicalThreadContext.Properties["CallerIp"] = ip;
try
{
_logger.Info("Publishing message from " + message.Sender);
var sinks = ObjectFactory.GetAllInstances<IMessageWriteRepository>();
Parallel.ForEach(sinks, x => x.SaveMessage(message));
_logger.Info("Message published");
}
catch (Exception ex)
{
_logger.Error("Issue publishing message from " + message.Sender + " on " + ip, ex);
throw new FaultException("Message was either not published or only partially published. Please contact support");
}
}
}
注意 Parallel.Foreach 的使用,其中并行使用了 IMessageWriteRepository 的多个实现。每个实现都有一个通过依赖注入注入的 ILog。似乎此时调用者的上下文丢失了。
我的 Log4Net appender 中的模式布局如下所示:
<conversionPattern value="%date [%-5level] [%thread] [%class] [%property{CallerIp}] %message%newline" />
最后,生成的日志如下所示:
2015-06-23 09:49:11,004 [INFO ] [13] [BroadcastService] [127.0.0.1] Publishing message from Graeme on 127.0.0.1
2015-06-23 09:49:11,073 [INFO ] [13] [RabbitMqMessageWriter] [(null)] Sending message on topic TestTopic
2015-06-23 09:49:11,073 [INFO ] [15] [DatabaseAndFileshareWriteMessageRepository] [(null)] Saving message body to disk
2015-06-23 09:49:11,104 [INFO ] [15] [DatabaseAndFileshareWriteMessageRepository] [(null)] Saving message meta to database
2015-06-23 09:49:11,737 [INFO ] [13] [BroadcastService] [127.0.0.1] Message published
注意 [(null)] 调用者 IP 应该在不同线程的日志消息中。
欢迎提出任何建议。
感谢log4net LogicalThreadContext not working。
以下代码将在升级到 log4net 版本 1.12.13.0 后跨线程工作
log4net.LogicalThreadContext.Properties["CallerIp"] = ip;
我创建了一个 Windows 服务 (.Net 4.0),它通过 TCP 绑定公开 WCF 服务端点。
调用服务方法时,它将在不同的线程中执行多个任务。每个 class 执行的操作都有一个 Log4Net ILog 实现注入(使用依赖注入)。
我想做的是每个日志条目都有调用者的 IP 地址,这样我就可以跟踪调用或确定服务器上哪个调用出错。
使用 log4Net 的 LogicalThreadContext,我已经设法为写在同一线程上的任何日志消息实现了这一点,但没有为其他线程上的任何内容实现。
示例代码如下。
服务接口:
[ServiceContract(Namespace = "http://tremac")]
public interface IBroadcastService
{
[OperationContract]
void PublishMessage(Message message);
}
服务实施:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class BroadcastService: IBroadcastService
{
private readonly ILog _logger;
public BroadcastService(ILog logger)
{
_logger = logger;
_logger.Debug("Broadcast Service Initiated");
}
public void PublishMessage(Message message)
{
var prop =
OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as
RemoteEndpointMessageProperty;
string ip = prop == null ? "" : prop.Address;
log4net.LogicalThreadContext.Properties["CallerIp"] = ip;
try
{
_logger.Info("Publishing message from " + message.Sender);
var sinks = ObjectFactory.GetAllInstances<IMessageWriteRepository>();
Parallel.ForEach(sinks, x => x.SaveMessage(message));
_logger.Info("Message published");
}
catch (Exception ex)
{
_logger.Error("Issue publishing message from " + message.Sender + " on " + ip, ex);
throw new FaultException("Message was either not published or only partially published. Please contact support");
}
}
}
注意 Parallel.Foreach 的使用,其中并行使用了 IMessageWriteRepository 的多个实现。每个实现都有一个通过依赖注入注入的 ILog。似乎此时调用者的上下文丢失了。
我的 Log4Net appender 中的模式布局如下所示:
<conversionPattern value="%date [%-5level] [%thread] [%class] [%property{CallerIp}] %message%newline" />
最后,生成的日志如下所示:
2015-06-23 09:49:11,004 [INFO ] [13] [BroadcastService] [127.0.0.1] Publishing message from Graeme on 127.0.0.1
2015-06-23 09:49:11,073 [INFO ] [13] [RabbitMqMessageWriter] [(null)] Sending message on topic TestTopic
2015-06-23 09:49:11,073 [INFO ] [15] [DatabaseAndFileshareWriteMessageRepository] [(null)] Saving message body to disk
2015-06-23 09:49:11,104 [INFO ] [15] [DatabaseAndFileshareWriteMessageRepository] [(null)] Saving message meta to database
2015-06-23 09:49:11,737 [INFO ] [13] [BroadcastService] [127.0.0.1] Message published
注意 [(null)] 调用者 IP 应该在不同线程的日志消息中。
欢迎提出任何建议。
感谢log4net LogicalThreadContext not working。
以下代码将在升级到 log4net 版本 1.12.13.0 后跨线程工作
log4net.LogicalThreadContext.Properties["CallerIp"] = ip;