【问题标题】:WCF Service - Logging Caller DetailsWCF 服务 - 记录调用者详细信息
【发布时间】:2015-06-23 11:45:48
【问题描述】:

我创建了一个 Windows 服务 (.Net 4.0),它通过 TCP 绑定公开 WCF 服务端点。

当一个服务方法被调用时,它会在不同的线程中执行几个任务。每个执行动作的类都注入了一个 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

注意调用者 IP 应该在不同线程的日志消息中的 [(null)]。

欢迎提出任何建议。

【问题讨论】:

    标签: c# .net multithreading wcf log4net


    【解决方案1】:

    感谢log4net LogicalThreadContext not working

    以下代码将在升级到 log4net 版本 1.12.13.0 后跨线程工作

    log4net.LogicalThreadContext.Properties["CallerIp"] = ip;
    

    【讨论】:

    • 这不是您在发布的代码中使用的同一行吗?
    • 它是......关键部分是:(1)升级 Log4Net 和(2)使用该行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 2017-07-16
    • 2020-08-03
    相关资源
    最近更新 更多