2012-10-15 20 views
6

Ho cercato di accedere ai servizi WCF (incluse tecnologie come NLog e PostSharp), ma ho qualcosa che non ho ancora risolto ... Non so se mi manca qualcosa di ovvio o semplicemente non è possibile.Servizi WCF, registrazione verticale

Diciamo che ho un livello di servizio WCF con oltre 100 punti di accesso alle chiamate del servizio web. Uno di questi sta causando un problema. Sotto quel livello c'è un livello di logica aziendale e un livello di database. Quello che voglio fare (credo) è attivare la registrazione per quella chiamata di servizio (che includerebbe l'ID di attività per la correlazione), in modo che tutte le chiamate a quel servizio vengano registrate e anche tutti i messaggi di registro nei livelli inferiori vengano registrati. Non desidero davvero attivare la registrazione a livello di assembly per i livelli inferiori perché saranno condivisi da molti dei metodi del servizio Web.

È possibile anche tramite un framework esistente o utilizzando qualcosa come CorrelationManager in modo creativo?

risposta

1

In log4net è possibile impostare una proprietà sul contesto del thread che verrà inclusa in tutti gli eventi di registrazione per il thread.

public class WcfServiceClass 
{ 
    public void ProblemServiceMethod() 
    { 
     using (log4net.ThreadContext.Stacks["logThisMethod"].Push("ProblemServiceMethod")) 
     { 
      // can also add the correlationId to the logs using this method. 
      // call business logic... 

     } 
    } 
} 

Quindi create a custom appender che filtra da esso.

public class IfContextSetFilterAppender : log4net.Appender.AppenderSkeleton 
{ 
    protected override void Append(LoggingEvent loggingEvent) 
    { 
     bool logThisEntry = false; 
     string serviceMethodBeingLogged; 

     foreach (object p in loggingEvent.GetProperties()) 
     { 
      System.Collections.DictionaryEntry dEntry = (System.Collections.DictionaryEntry)p; 
      if (dEntry.Key == "logThisMethod") 
      { 
       logThisEntry = true; 
       serviceMethodBeingLogged = dEntry.Value.ToString(); 
      } 
     } 

     if (!logThisEntry) 
      return; // don't log it. 

     // log it. 
    } 
} 

Questo è l'esempio semplicistico (ma chiaro) dell'idea.

Se ero davvero costruire questo in così grande scala un servizio come lei, avrei:

  1. Creare un comportamento IOperationInvoker endpoint che afferra il nome del metodo e imposta un valore di contesto log4net per tutte le chiamate la sua applicata ai.

  2. (Facoltativo) L'appender ha letto da app.config l'elenco dei filtri di tutti i nomi dei metodi di servizio che devono essere registrati. (Se siete selettivi in ​​quello che i metodi del comportamento OperationInvoker vengono applicati, l'appender non ha bisogno di questa complessità.)

Facendo il comportamento sono disponibili diverse opzioni per controllare la registrazione su un servizio di produzione attraverso la configurazione da solo senza mai toccare il codice di servizio.

+0

Grazie! Questo è esattamente il tipo di cosa che sto cercando. Idealmente mi piacerebbe usare NLog su log4net perché sembra un po 'più attivo, ma questo è esattamente il tipo di cosa che mi farebbe cambiare idea ... Hai usato un codice come questo in rabbia? Come si gestirà un servizio multi-thread? –

+0

log4net.ThreadContext utilizza l'archiviazione locale del thread. Finché una chiamata di servizio non interrompe i thread (leggi l'utilizzo di asych), funziona perfettamente in un ambiente con multithreading. Sì, ne ho fatto parecchi per servizi di produzione aziendale reali. L'ultimo è stato quello di mettere un id di correlazione in tutti i log (qualsiasi cosa spinga sul ThreadContext può essere inclusa nel modello di conversione dell'appender.) Log4net non è molto attivo perché manca molto ed estendendolo è molto ben documentato. Se riesci a sopportare che sia stato scritto prima dei farmaci generici, ti tratta bene. – ErnieL

+0

Grazie Ernie. Era esattamente il tipo di cosa che stavo cercando! –

0

È possibile creare una nuova origine di registrazione per quella chiamata di servizio particolare e quindi abilitare la diagnostica per filtrarla.

<system.diagnostics> 
    <sources> 
     <source name="Your.Source.Here" switchValue="Verbose"> 
     <listeners> 
      <add name="xml" /> 
     </listeners> 
     </source> 
    </sources> 
    <sharedListeners> 
     <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" traceOutputOptions="LogicalOperationStack" initializeData="l:\logs\N4S.MSO.ADC.Host.svclog" /> 
    </sharedListeners> 
    </system.diagnostics> 
+0

Ciò non significa che le chiamate al framework di registrazione nei livelli inferiori dovranno conoscere anche il nome sorgente? –

+0

Chris - btw, grazie per l'input; molto apprezzato! –

Problemi correlati