August 18, 2007

Simple Tracing and Logging for Asp.Net and .Net Command Line Applications

Filed under: .Net,C++,PHP,Programming — pj @ 12:51 am

From time to time, I need some quick and dirty logging in my .Net applications.  I don’t always have time or energy to worry about the ideal logging API. The MSDN documentation and all the examples I found for the built-in .Net logging facilities were confusing and, it turns out, overkill.

Logging in Asp.Net

Logging in Asp.Net is confusing because Microsoft uses the word “trace” in two different contexts:

When a page is rendered and HTML generated, you can have the Asp.Net engine add a bunch of additional page state information to the generated HTML. In your application’s web.config file, this is the tracing that is controlled by
<trace></trace> under <web.config></web.config>. In practice, I don’t often find this kind of tracing helpful, but when I do,  I put the following tags in web.config to make it easy to turn on or off:

<system.web>
  <customErrors mode="Off"/>
  <trace enabled="false" requestLimit="10" pageOutput="true" traceMode="SortByTime" localOnly="true" />
  <!-- ... -->
</system.web>

With these tag in place, you can enable and disable page state tracing (more like a dump if you ask me) by changing enabled=”false” to enabled=”true”.

The other use of the word “trace” is related to the more traditional form of logging via .Net Debug.Write and Trace.Write. Essentially, under Asp.Net, you use Debug.Write and Trace.Write as usual. Contrary to the MSDN documentation, the default compiler options for Asp.Net web applications allow Debug.Write output in Debug builds and allow Trace.Write output in both Debug and Release builds. If you run your Asp.Net application under the Visual Studio debugger, you will see that Debug and Trace output is redirected to the debug output window without any additional configuration.  As with any use of .Net logging, you can setup tracing to various outputs either in code or via your application’s configuration file. To configure your Asp.Net web application to log trace output to a file (for use with other tools), place the following into your web.config:

<system.diagnostics>  
  <trace autoflush="true">    
  <listeners>    
  <add name="MyApplicationTracer" type="System.Diagnostics.TextWriterTraceListener, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="MyApplicationTrace.log" />
  </listeners>
  </trace>
</system.diagnostics>

This will result in debug (in debug builds) and trace output going into a file named MyApplicaitonTrace.log in your web site’s root folder.

Logging in .Net Command Line Applications

Since .Net applications are easy to create and fairly expressive, I often write small command line utilities that, on other platforms, I might create as shell scripts.  Here are some handy code snips that I use to handle simple logging for these applications:

namespace Program1
{
 ///

 /// Prepends each output line with the time
 ///
 public class TextWriterTraceListenerWithTime : TextWriterTraceListener
 {
  public TextWriterTraceListenerWithTime()
  : base()
  {
  }
public TextWriterTraceListenerWithTime(Stream stream)
  : base(stream)
  {
  }
public TextWriterTraceListenerWithTime(string path)
  : base(path)
  {
  }
public TextWriterTraceListenerWithTime(TextWriter writer)
  : base(writer)
  {
  }
public TextWriterTraceListenerWithTime(Stream stream, string name)
  : base(stream, name)
  {
  }

public TextWriterTraceListenerWithTime(string path, string name)
  : base(path, name)
  {
  }

public TextWriterTraceListenerWithTime(TextWriter writer, string name)
  : base(writer, name)
  {
  }

public override void WriteLine(string message)
  {
  base.Write(DateTime.Now.ToString());
  base.Write(" ");
  base.WriteLine(message);
  }
 }

class Program
 {

static void Main(string[] commandLineArgs)
  {
  MemoryStream messageStream = null;
  TextWriterTraceListenerWithTime messageWriter = null;

try
  {
  messageStream = new MemoryStream();
  messageWriter = new TextWriterTraceListenerWithTime(messageStream);
  Trace.Listeners.Add(messageWriter);
  Trace.Listeners.Add(new ConsoleTraceListener());

Trace.WriteLine("This is an example message");
  messageWriter.Flush();

// ...

messageWriter.Flush();
  messageWriter = null;
  }
  catch (Exception e)
  {
  Trace.Write(string.Format("ERROR: A fatal exception occured: {0}: {1}", e.GetType().Name, e.Message));
  if (e.InnerException != null)
  Trace.Write(string.Format(" ({0}: {1})", e.InnerException.GetType().Name, e.InnerException.Message));
  Trace.WriteLine("");

if (messageWriter != null)
  {
  messageWriter.Flush();
  messageStream.Seek(0, SeekOrigin.Begin);
  StreamReader messageReader = new StreamReader(messageStream);
  DbRequest.Singleton.Alert(messageReader.ReadToEnd()); // Send alert message via email
  }
  }
  }
 }
}

Hopefully, you get the idea from the example code above.

One Response to “Simple Tracing and Logging for Asp.Net and .Net Command Line Applications”

  1. [...] Simple Tracing and Logging for Asp.Net and .Net Command Line Applications [...]

Leave a Reply

Powered by Teztech