Wednesday, 18 June 2014

There aren't enough TraceListener's in the world...

... so here's one of mine.

I got fed up with the process information polluting my console window so here's my ConsoleTraceListener which displays the Date/Time in the header (if you specify TraceOptions.DateTime) and only displays the event type if it's not TraceEventType.Information.




namespace Foo.Bar
{
  using System;
  using System.Collections;
  using System.Diagnostics;
  using System.Globalization;
  using System.Runtime.InteropServices;
  using System.Security.Permissions;
 
  /// <summary>
  /// A simple derivative of the ConsoleTraceListener which doesn't include the process information (for example).
  /// </summary>
  [HostProtection(SecurityAction.LinkDemandSynchronization = true)]
  public class SimpleConsoleTraceListener : ConsoleTraceListener
  {
    /// <summary>
    /// Writes trace information, a message, and event information to the
    /// listener specific output.
    /// </summary>
    /// <param name="eventCache">A TraceEventCache object that contains the
    /// current process ID, thread ID, and stack trace information.</param>
    /// <param name="source">A name used to identify the output, typically
    /// the name of the application that generated the trace event.</param>
    /// <param name="eventType">One of the TraceEventType values specifying
    /// the type of event that has caused the trace.</param>
    /// <param name="id">A numeric identifier for the event.</param>
    /// <param name="message">A message to write.</param>
    [ComVisible(false)]
    public override void TraceEvent(
        TraceEventCache eventCache,
        string source,
        TraceEventType eventType,
        int id,
        string message)
    {
      if ((this.Filter == null)
          || this.Filter.ShouldTrace(
              eventCache, source, eventType, id, message, nullnullnull))
      {
        this.WriteHeader(eventType, eventCache);
        this.WriteLine(message);
        this.WriteFooter(eventCache);
      }
    }
 
    /// <summary>
    /// Writes trace information, a formatted array of objects and event information to the listener specific output.
    /// </summary>
    /// <param name="eventCache">A TraceEventCache object that contains the current process ID, thread ID, and stack trace information.</param>
    /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
    /// <param name="eventType">One of the TraceEventType values specifying the type of event that has caused the trace.</param>
    /// <param name="id">A numeric identifier for the event.</param>
    /// <param name="format">A format string that contains zero or more format items, which correspond to objects in the <paramref name="args"/> array.</param>
    /// <param name="args">An object array containing zero or more objects to format.</param>
    [ComVisible(false)]
    public override void TraceEvent(
        TraceEventCache eventCache,
        string source,
        TraceEventType eventType,
        int id,
        string format,
        params object[] args)
    {
      if ((this.Filter == null)
          || this.Filter.ShouldTrace(
              eventCache, source, eventType, id, format, args, nullnull))
      {
        this.WriteHeader(eventType, eventCache);
        this.WriteLine(string.Format(
          CultureInfo.InvariantCulture, format, args));
        this.WriteFooter(eventCache);
      }
    }
 
    /// <summary>Write footer.</summary>
    /// <param name="eventCache">The event cache.</param>
    private void WriteFooter(
        TraceEventCache eventCache)
    {
      if (eventCache == null)
      {
        return;
      }
 
      this.IndentLevel++;
      if (this.IsEnabled(TraceOptions.ProcessId))
      {
        this.WriteLine("ProcessId=" + eventCache.ProcessId);
      }
 
      if (this.IsEnabled(TraceOptions.LogicalOperationStack))
      {
        this.Write("LogicalOperationStack=");
        Stack logicalOperationStack = eventCache.LogicalOperationStack;
        bool flag = true;
        foreach (object obj2 in logicalOperationStack)
        {
          if (!flag)
          {
            this.Write(", ");
          }
          else
          {
            flag = false;
          }
 
          this.Write(obj2.ToString());
        }
 
        this.WriteLine(string.Empty);
      }
 
      if (this.IsEnabled(TraceOptions.ThreadId))
      {
        this.WriteLine("ThreadId=" + eventCache.ThreadId);
      }
 
      if (this.IsEnabled(TraceOptions.Timestamp))
      {
        this.WriteLine("Timestamp=" + eventCache.Timestamp);
      }
 
      if (this.IsEnabled(TraceOptions.Callstack))
      {
        this.WriteLine("Callstack=" + eventCache.Callstack);
      }
 
      this.IndentLevel--;
    }
 
    /// <summary>Write the header.</summary>
    /// <param name="eventType">The event type.</param>
    /// <param name="eventCache">The event cache.</param>
    private void WriteHeader(TraceEventType eventType, TraceEventCache eventCache)
    {
      if (eventCache != null)
      {
        if (this.IsEnabled(TraceOptions.DateTime))
        {
          this.Write(eventCache.DateTime.ToLocalTime().ToString("s"CultureInfo.InvariantCulture));
          this.Write(" ");
        }
      }
 
      if (eventType != TraceEventType.Information)
      {
        this.Write(string.Format(CultureInfo.InvariantCulture"{0}: ", eventType));
      }
    }
 
    /// <summary>Is this listener enabled?</summary>
    /// <param name="options">The options.</param>
    /// <returns>The <see cref="bool"/>.</returns>
    private bool IsEnabled(
        TraceOptions options)
    {
      return (options & this.TraceOutputOptions) != TraceOptions.None;
    }
  }
}

Using it in an application config file

<?xml version="1.0"?>
<configuration>
  
...
 
  <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add name="MySimpleListener" type="Foo.Bar.SimpleConsoleTraceListener, My.Foo.Bar.Assembly"/>
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

No comments: