2016-04-19 4 views
1

AFAIK WCFは非常に強力な設定可能なロギングインフラストラクチャを備えていますが、私の場合は複雑すぎます。私はこの問題は、WCFは、非常に複雑な形式にXMLでログインしている、そしてそれはちょっと冗長だということですこれに類似したパターンを持つ単純なもののようなaccess.logWCFで単純なロギングを実装する

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

を実装したいです。おそらく、このXMLを単純化する方法がいくつかありますか?テキストファイルではなくXMLであることは大丈夫ですが、スペースをとり、ログを読みにくくするなど、複数のフィールドとデータがあります。

私が今見つけた唯一の方法はimplement my own IOperationInvokerですが、おそらく私は組み込みのロギングシステムを再利用できますか?ご意見をお聞かせください。

+0

あなたはWCFトレースを参照していますか?私はあなたがそれを再利用できるとは思わないが、どのくらいの情報が記録されるかを制御することができる。 – Tim

+0

@Tim WCFオーバーヘッドがごくわずかなときにこの情報をいくつか追加して記録すればよい。しかし、それはそうではないようです。 –

答えて

0

私はそれをカスタム動作で実装しました。ここでの実装は次のとおりです。

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()); 
} 
関連する問題