【问题标题】:Implement simple logging in WCF在 WCF 中实现简单的日志记录
【发布时间】:2016-08-11 16:59:26
【问题描述】:

AFAIK WCF 有一个非常强大的可配置日志基础设施,但在我的例子中它太复杂了。我想实现一些简单的东西,比如access.log,其模式与此类似

%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"

问题是 WCF 以非常复杂的格式记录 XML,而且有点冗长。也许有一些方法可以简化这个 XML?可以使用 XML 而不是文本文件,但它有多个字段和数据,占用空间,使日志更难阅读等等。

我现在找到的唯一方法是implement my own IOperationInvoker,但也许我可以重用内置日志系统?请指教。

【问题讨论】:

  • 您指的是 WCF 跟踪吗?我不认为你可以重复使用它,尽管你可以控制它记录多少信息。
  • @Tim WCF 跟踪很好,如果它在开销可以忽略不计的情况下记录一些额外的信息。但似乎并非如此。

标签: c# .net wcf logging


【解决方案1】:

我用自定义行为实现了它。这是实现:

class LoggingBehaviour : IEndpointBehavior
{
    public void Validate(ServiceEndpoint endpoint)
    {
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new LoggingMessageInspector());
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }
}

和自定义日志检查器:

public class LoggingMessageInspector : IDispatchMessageInspector
{
    private static readonly Logger CurrentClassLogger = LogManager.GetCurrentClassLogger();

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        return request.Headers.To;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        var requestUri = (Uri)correlationState;
        var currentContext = WebOperationContext.Current;
        if (currentContext == null)
        {
            CurrentClassLogger.Log(LogLevel.Error, "Cannot log reply to [{0}]: WebOperationContext is null", requestUri);
            return;
        }

        try
        {
            var httpRequest = currentContext.IncomingRequest;
            string host = httpRequest.Headers[HttpRequestHeader.Host];
            string method = httpRequest.Method;
            string userAgent = httpRequest.UserAgent;
            var statusCode = currentContext.OutgoingResponse.StatusCode;

            CurrentClassLogger.Log(LogLevel.Info, "[Host {0}] [{1} {2} {3} {4}] [{5}]", host, method, requestUri, (int) statusCode, statusCode,  userAgent);
        }
        catch (Exception ex)
        {
            CurrentClassLogger.Error("Cannot log reply to [{0}] : {1}", requestUri, ex);
        }
    }
}

那就用吧!

foreach (var endpoint in ServiceHost.Description.Endpoints)
{
    endpoint.Behaviors.Add(new LoggingBehaviour());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2020-12-07
    • 2011-12-29
    • 2018-06-13
    • 2023-03-11
    • 2010-12-03
    • 2011-01-29
    相关资源
    最近更新 更多