GrandMasterFlush
GrandMasterFlush

Reputation: 6409

Logging errors in WCF - Nothing being stored in log file when exception is being thrown

I've been trying to catch exceptions in my WCF service and store them in a log file (I don't want the client to get any specific error message at this point).

Having read a few tutorials online I've added some logging configuration to the <system.diagnostics> section of web.config:

<sources>
  <source name="System.ServiceModel.MessageLogging" switchValue="Error">
    <listeners>
      <add type="System.Diagnostics.DefaultTraceListener" name="Default">
        <filter type="" />
      </add>
      <add name="ServiceModelMessageLoggingListener">
        <filter type="" />
      </add>
    </listeners>
  </source>
  <source name="System.ServiceModel" switchValue="Error" propagateActivity="true">
    <listeners>
      <add type="System.Diagnostics.DefaultTraceListener" name="Default">
        <filter type="" />
      </add>
      <add name="ServiceModelTraceListener">
        <filter type="" />
      </add>
    </listeners>
  </source>
</sources>    
<sharedListeners>
  <add initializeData="C:\inetpub\wwwroot\myApp\logs\Web_messages.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
    <filter type="" />
  </add>
  <add initializeData="C:\inetpub\wwwroot\myApp\logs\Web_tracelog.svclog" type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
    <filter type="" />
  </add>
</sharedListeners>

In the event of an exception I've been tried using Debug.WriteLine and Trace.WriteLine but nothing is getting written to the tracefile.

I know IIS / WCF can write to the log file, if I set the switchValue for either of the sources to be Verbose I get plenty of information (too much to be of use), but I only want the exception code.

Upvotes: 1

Views: 2784

Answers (1)

CSharpenter
CSharpenter

Reputation: 762

Try this, consider the following class

public class TraceUtility 
{
    private TraceSource trcSrc;

    public TraceUtility(string traceSourceName)
    {
        if (string.IsNullOrEmpty(traceSourceName))
        {
            throw new ArgumentNullException(traceSourceName);
        }

        trcSrc = new TraceSource(traceSourceName);
    }

    public void TraceError(int id, string message)
    {
        trcSrc.TraceEvent(TraceEventType.Error, id, message);
    }

    public void TraceError(int id, string message, params object[] args)
    {
        trcSrc.TraceEvent(TraceEventType.Error, id, message, args);
    }

    public void TraceError(string message)
    {
        TraceError(0, message);
    }

    public void TraceError(string message, params object[] args)
    {
        TraceError(0, message, args);
    }

}

Now add the following config section to your configuration file

<system.diagnostics>
    <sources>
        <source name="xyz" switchName="AllSwitch">
            <listeners>
                <add name="xyzListener"  type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Traces\xyz.txt" traceOutputOptions="DateTime" />
            </listeners>
        </source>
    </sources>
    <switches>
        <add name="AllSwitch" value="All"/>
        <add name="OnlyErrors" value="Error"/>
    </switches>
    <trace autoflush="true" indentsize="3"/>
</system.diagnostics>

Finally, in order to use it:

TraceUtilitiy trcSrc = new TraceUtility("xyz");

trcSrc.TraceError("Error: {0}", "Your error description");

Note that you can add trace methods for information and warnings to the trace utility class just as I did with the trace error methods.

Hope this is what you are seeking for.

EDIT: Your other code did not run because you did not specify a custom listener to the System.Diagnostics.Trace class. To do so add the following section into your config:

  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <remove name="DefaultTraceListener" />

        <add name="LogFileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Traces\xyz1.txt" />
      </listeners>
    </trace>
  </system.diagnostics>

and try using your old code. Hope this will de-baffle you ;)

Upvotes: 1

Related Questions