2016-04-19 7 views
1

AFAIK WCF hat eine sehr leistungsfähige konfigurierbare Protokollierungsinfrastruktur, aber in meinem Fall ist es zu komplex. Ich mag einfach etwas implementieren, wie access.log mit Mustern ähnlich wie diesesImplementieren Sie einfache Anmeldung WCF

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

Problem ist, dass WCF in sehr komplexem Format in XML protokolliert, und es ist irgendwie ausführlich. Vielleicht gibt es eine Möglichkeit, dieses XML zu vereinfachen? Es ist in Ordnung, dass es ein XML anstelle von Textdatei ist, aber es hat mehrere Felder und Daten, die Platz braucht, macht es schwieriger zu lesen und so weiter.

Die einzige Möglichkeit, die ich für jetzt gefunden habe, ist implement my own IOperationInvoker dafür, aber vielleicht kann ich eingebaute Logging-System wiederverwenden? Bitte, Beratung.

+0

Beziehen Sie sich auf WCF Tracing? Ich glaube nicht, dass Sie es wiederverwenden können, obwohl Sie steuern können, wie viele Informationen es protokolliert. – Tim

+0

@Tim WCF Tracing ist in Ordnung, wenn es diese Informationen mit einigen zusätzlichen protokolliert, wenn Overhead vernachlässigbar ist. Aber das scheint nicht der Fall zu sein. –

Antwort

0

Ich habe es mit benutzerdefiniertem Verhalten implementiert. Hier ist die Umsetzung:

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) 
    { 
    } 
} 

und benutzerdefinierte Protokollierung Inspektor:

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); 
     } 
    } 
} 

Dann nutzen Sie es!

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