WCF Tracing

Ciao a tutti!
Con questo mio primo post vorrei affrontare un argomento che a molti potrebbe sembrare banale, ma che sarà la base per molti post che scriverò in seguito: il tracing di WCF.

Quando c’è un problema con WCF, nel 99% dei casi, quello che bisogna fare è abilitare la funzionalità di tracing sia sul client che sul server (ovviamente a meno che uno dei due non sia sviluppato con altre tecnologie), riprodurre il problema, analizzare i trace per capirne la causa. Naturalmente le cose non sono sempre così semplici, ma si tratta comunque di un buon punto di inizio per il troubleshooting. Nota bene: il tracing non è abilitato by default, dovete farlo voi.

Tutte le informazioni che potete leggere in questo post sono ovviamente trattate con la dovuta precisione e completezza in MSDN, ma il mio scopo non è esattamente quello di approfondire l’argomento in questa sede, quanto quello di farvi risparmiare tempo.

Il tracing di WCF si basa su System.Diagnostics ed è quindi strutturato in ‘source’ e ‘listener’: in breve questo significa che le entità che partecipano all’attività di tracing di distinguono in coloro che producono le informazioni e in quelli che ricevono tali informazioni per poi salvarle in qualche modo.
Nel caso di WCF abbiamo diverse source di tracing, ma quelle che io solitamente utilizzo sono System.ServiceModel e System.ServiceModel.MessageLogging: la prima traccia tutte le fasi nel corso dell’elaborazione di WCF (lettura configuraizone, security, trasporto, etc.) mentre il secondo traccia tutti i messaggi in ingresso e uscita.
Il listener normalmente utilizzato è System.Diagnostics.XmlWriterTraceListener (attenzione: non è thread-safe!).
Un altro punto importante è il livello di tracing che si vuole impostare (Off, Critical, Error, Warning, Information, Verbose, Activitytracing, All), prestando attenzione alla quantità di dati potenzialmente generabile dai diversi livelli.

Ciò detto, vorrei condividere le impostazioni di tracing che normalmente invio ai clienti nelle prime fasi del troubleshooting: nella mia esperienza vanno quasi sempre bene sia per quantità di dati prodotti, sia per presenza di informazioni significative.

L’aspetto principale di cui si deve tenere conto è la fase del processo di sviluppo (semplificando estremamente debugging durante lo sviluppo, test di carico, etc.), nonché l’ambiente in cui di troviamo: sviluppo, pre-produzione/produzione.

Questa è la configurazione del tracing che solitamente suggerisco per gli ambienti di pre-produzione/produzione:

 <configuration>
 <system.diagnostics>
  <sources>
    <source name="System.ServiceModel"
            switchValue="Warning"
            propagateActivity="true" >
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
  </sources>
  <shareListeners>
    <add name="xml"
         type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="C:\logs\Traces.svclog" />
  </sharedListeners>
 </system.diagnostics>
</configuration>

Questa invece è la configurazione solitamente raccomandata per gli ambienti di sviluppo:

 <configuration>

 <system.diagnostics>
  <sources>
    <source name="System.ServiceModel"
            switchValue="Information, ActivityTracing"
            propagateActivity="true" >
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
    <source name="System.ServiceModel.MessageLogging">
      <listeners>
        <add name="xml"/>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="xml"
         type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="C:\logs\Traces.svclog" />
  </sharedListeners>
 </system.diagnostics>

<system.serviceModel>
  <diagnostics>
      <messageLogging 
           logEntireMessage="true" 
           logMalformedMessages="true"
           logMessagesAtServiceLevel="true" 
           logMessagesAtTransportLevel="true"
           maxMessagesToLog="3000" 
       />
  </diagnostics>
 </system.serviceModel>


</configuration>

Ve la potrete cavare con un semplice copia e incolla nel vostro file di configurazione.

Come avrete notato, i trace vengono salvati nel file system: assicuratevi che l’applicazione abbia i permessi di scrittura sulla destination folder, altrimenti perderete parecchio tempo a chiedervi come mai non viene scritto alcun file. In particolare, se il servizio WCF gira in ASP.NET, aggiungete l’identity del worker process (Network Service by default in IIS6/7) tra gli utenti abilitati alla scrittura della cartella di destinazione; riavviate l’application pool prima di cominciare il troubleshooting).

Molti di voi a questo punto potrebbero chiedersi: “ok, ho il file, ma ora cosa me ne faccio?” Spero che non abbiate già tentato di aprirlo con il notepad.exe.. (per carità non voglio offendere nessuno, se lo dico è perché io una volta l’ho fatto! E comunque si tratta di info in formato testuale, XML appunto).

Il modo migliore per leggere i trace è aprirli con il Service Trace Viewer, un tool solitamente reperibile in C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin, che vi permette di visualizzare informazioni e correlazioni tra di esse in modo grafico. Se proprio volete vederne delle belle, aprite entrambi i trace lato client e server contemporaneamente con Service Trace Viewer.

Il tema del WCF tracing non si esaurisce di certo qui, per questo sto pensando di scrivere altri post in merito e vi assicuro che c’è molto altro da dire.

A presto!

Andrea Liberatore

Senior Support Engineer

Developer Support Core