MSDN has some sample code showing how to implement a trace listener for the EWS Managed API (which is crucial for debugging EWS applications). However, the sample trace listener isn't actually very good for a variety of reasons (it creates different files for each trace type, and will actually overwrite the previous trace if the name is the same). I use a trace listener in my sample applications that is thread-safe (you can use the same trace listener object for all instance of ExchangeService even when it will be called from multiple threads), and logs everything to a single file. For single-threaded applications, logging to a single file is very useful as you can follow the EWS conversation very easily (as it will be sequential - the request will be followed by the response). For multi-threaded applications, the requests/responses will most likely be out of order, but it is not too difficult to process such files to get them into order again (the log analyser of SOAPe can now do this, and I'll be releasing that version once I've got the error analysis working again).
To use the trace listener below, you just specify the name of the file to which the trace will be written when you instantiate the object:
_traceListener = new ClassTraceListener("Trace.log");
My sample trace listener (which is also available for download at the bottom of the page):
/*
* By David Barrett, Microsoft Ltd. 2015. Use at your own risk. No warranties are given.
*
* DISCLAIMER:
* THIS CODE IS SAMPLE CODE. THESE SAMPLES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
* MICROSOFT FURTHER DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS FOR
* A PARTICULAR PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THE SAMPLES REMAINS WITH YOU. IN NO EVENT SHALL
* MICROSOFT OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
* BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE
* SAMPLES, EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION
* OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
* */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Exchange.WebServices.Data;
using System.IO;
namespace EWSTracingSample
{
public class ClassTraceListener: ITraceListener
{
string _traceFile = "";
private StreamWriter _traceStream = null;
public ClassTraceListener(string traceFile)
{
try
{
_traceStream = File.AppendText(traceFile);
_traceFile = traceFile;
}
catch { }
}
~ClassTraceListener()
{
try
{
_traceStream.Flush();
_traceStream.Close();
}
catch { }
}
public void Trace(string traceType, string traceMessage)
{
if (_traceStream == null)
return;
lock (this)
{
try
{
_traceStream.WriteLine(traceMessage);
_traceStream.Flush();
}
catch { }
}
}
}
}